Inquiries

Operations of the Workflow Engine API. Paths are relative to your deployment's API host.

GET /api/workflow-engine-api/inquiries

List the inquiries the caller may see in the caller org

An org admin sees every inquiry of the org (or, with recipientUserId, that person's). Any other caller sees only the inquiries addressed to them; recipientUserId only narrows further. A non-person caller that is not an org admin is 403 INQUIRY_LIST_CALLER_NOT_A_PERSON. Further filters: projectId / runId / kind / status / originBiome / inquiryKind. Cross-org inquiries are invisible — every row carries orgId directly so the tenant scope is a column check, not a cross-table join.

Authentication: bearer token (Authorization: Bearer <token>)

ParameterInTypeRequiredDescription
inquiryKindquerystringnoExact match on the inquiry's approval-card discriminator; rows with none never match.
kindqueryInquiryKindno
limitquerynumberno
offsetquerynumberno
originBiomequerystringnoExact match on the inquiry's origin biome; rows with none never match.
projectIdquerystringnoOnly inquiries of this project (checked to belong to the caller org).
recipientUserIdquerystringnoNarrows to inquiries addressed to this person. A caller who is not an org admin only ever sees inquiries addressed to them, so naming another person lists those addressed to both.
runIdquerystringnoOnly inquiries raised by this workflow run.
statusqueryInquiryStatusno
StatusDescriptionBody
200application/json InquiryResponseDtoDataArrayEnvelope

POST /api/workflow-engine-api/inquiries

Create an inquiry (idempotent on id)

Producer-side path called by the workflow worker. Validates the kind-specific prompt against the registered Zod schema. Idempotent on id — a retry returns the existing row unchanged. Recipients are inserted in the supplied order; ord is auto-assigned 0..N-1.

Authentication: bearer token (Authorization: Bearer <token>)

Request body: application/json CreateInquiryRequestDto

StatusDescriptionBody
201application/json InquiryResponseDtoDataEnvelope

GET /api/workflow-engine-api/inquiries/{id}

Get a single inquiry by id

Authentication: bearer token (Authorization: Bearer <token>)

ParameterInTypeRequiredDescription
idpathstringyes
StatusDescriptionBody
200application/json InquiryResponseDtoDataEnvelope

POST /api/workflow-engine-api/inquiries/{id}/cancel

Cancel a pending inquiry

Idempotent: cancelling a non-pending inquiry returns the existing row unchanged. All pending recipient rows transition to skipped with reasonCode=inquiry_cancelled.

Authentication: bearer token (Authorization: Bearer <token>)

ParameterInTypeRequiredDescription
idpathstringyes

Request body: application/json CancelInquiryRequestDto

StatusDescriptionBody
200application/json InquiryResponseDtoDataEnvelope

POST /api/workflow-engine-api/inquiries/{id}/escalate

Advance an inquiry to its next escalation level

Called by the gate workflow when its deadline timer fires AND the inquiry has onTimeout=escalate. Atomically: marks pending recipients as skipped(reason='escalation_timeout'), inserts the next chain step's recipients as fresh PENDING rows, and resets expiresAt. Refuses (409) if the chain is exhausted — call /resolve-exhausted instead. Refuses (400) if the deadline hasn't passed.

Authentication: bearer token (Authorization: Bearer <token>)

ParameterInTypeRequiredDescription
idpathstringyes

Request body: application/json EscalateInquiryRequestDto

StatusDescriptionBody
200application/json InquiryResponseDtoDataEnvelope

POST /api/workflow-engine-api/inquiries/{id}/replies

Submit a recipient reply

Atomic per-recipient idempotency: the recipient row is locked FOR UPDATE; a second reply for the same recipient returns 409 (INQUIRY_RECIPIENT_ALREADY_REPLIED). Reply payload is validated against the kind-specific Zod schema. For AGENT_TOOL_INQUIRY the engine resolves in-place; for DECISION_GATE the engine just records (the gate workflow applies the policy).

Authentication: bearer token (Authorization: Bearer <token>)

ParameterInTypeRequiredDescription
idpathstringyes

Request body: application/json SubmitInquiryReplyRequestDto

StatusDescriptionBody
200application/json InquiryResponseDtoDataEnvelope

POST /api/workflow-engine-api/inquiries/{id}/resolve

Resolve a DECISION_GATE inquiry with the gate workflow verdict

Called by the gate workflow right before it returns its outcome to the parent run. Transitions the inquiry to status='resolved', stores the verdict payload, and marks any still-pending recipients as skipped(reason='policy_resolved'). Idempotent: a non-pending inquiry returns the existing row unchanged. Without this call the row stays pending forever and the FE bell badge keeps showing the task.

Authentication: bearer token (Authorization: Bearer <token>)

ParameterInTypeRequiredDescription
idpathstringyes

Request body: application/json ResolveInquiryRequestDto

StatusDescriptionBody
200application/json InquiryResponseDtoDataEnvelope

POST /api/workflow-engine-api/inquiries/{id}/resolve-exhausted

Settle an inquiry whose escalation chain is exhausted

Called by the gate workflow after the final escalation level's deadline passes when currentEscalationLevel === escalationChain.length. Resolves the inquiry with the onEscalationExhaustion outcome (default reject). Idempotent.

Authentication: bearer token (Authorization: Bearer <token>)

ParameterInTypeRequiredDescription
idpathstringyes
StatusDescriptionBody
200application/json InquiryResponseDtoDataEnvelope