Skip to main content
Two endpoints cover the whole lifecycle from an external system:
  • POST /platform/v1/workflows/{workflow_id}/executions — start an execution
  • POST /platform/v1/workflow_executions/{execution_id}/resume — resume an execution that is waiting for input
Both are asynchronous: they queue the work and return immediately.

Before you start

  • The workflow status must be active
  • The workflow needs an active API trigger
  • Every request needs an X-API-Key header

Start an execution

Response is 202 Accepted:
Keep id to fetch or resume the execution, and tracking_id to correlate it with your own systems.

Start by BSUID

When you only have a business-scoped user ID, send recipient instead of phone_number:
If you send both identifiers, the phone number routes the conversation and the BSUID is kept as the participant identity. BSUID recipients are not supported on sandbox numbers.

Execution context

An API-triggered execution starts with:
See Triggers for the full context reference.

Check execution status

The execution row is created when the queued job picks up the request, so a lookup fired immediately after the 202 can return 404. Retry after a moment. To find executions that need input, filter the workflow’s execution list:

Resume a waiting execution

An execution enters waiting when it reaches a wait for response step. Resume it with the input the workflow was waiting for:
Note that message and variables sit at the top level, not under workflow_execution. The response is 200 OK with the execution’s id, status, tracking_id, current_step, timestamps, requested_execution_id, and parent_flow_execution_id. Resume work runs in the background, so the returned status can still be waiting — poll GET /platform/v1/workflow_executions/{id} to see it advance. Only one resume can be pending at a time. A second request while the first is still pending returns 409 Conflict.

Executions that call another workflow

When an execution is waiting at a call workflow step, the workflow that actually needs the input is the child execution it started. Resume the execution you started anyway — the input is routed down the chain to the deepest waiting execution:
  • id — the execution that received the input
  • requested_execution_id — the ID you sent in the path
  • parent_flow_execution_id — parent of the resumed execution, null at the root
Keep using the original execution ID for every reply; it stays valid as the child chain starts and finishes. variables you send are merged into the child that receives the input, and merge back into the parent when the child returns. GET /platform/v1/workflow_executions/{id} reports where input can go next in resumable_execution_id. It equals id for a plain waiting execution, points at the child while a call workflow is in progress, and is null when nothing in the chain is waiting. The execution list does not resolve this field. If the call workflow step was edited to call a different workflow while its child was still active, resume returns 422 with error: "Execution configuration changed". No input or variables are applied, and the child is preserved. Restore the original called workflow before retrying.

Errors

The start endpoint has a burst limiter on top of the general rate limits, scoped by API key and workflow, resetting every second:
  • legacy / free: 5 requests per second
  • pro: 15 requests per second
  • enterprise / platform: 30 requests per second
Successful responses carry X-Burst-RateLimit-Limit and X-Burst-RateLimit-Remaining.