REST API Reference
The /api/v1 endpoints let your backend start workflow runs, poll their status, fetch conversation messages, stream live events, and mint participant tokens. All endpoints require an API key unless noted otherwise.
Basics
All requests are JSON over HTTPS against your Chatterfly host. Authenticate with a bearer token — either a stable workflow key (recommended) or a per-deployment key:
Authorization: Bearer cfw_your_workflow_key_here
Content-Type: application/jsonA cfw_ workflow keyis scoped to a workflow and survives redeploys — runs resolve to the workflow's latest active deployment. Add "deployment_id" to the run body only to pin a specific snapshot. A legacy cf_ deployment key is bound to one deployment (and revoked on redeploy), so endpoints operate on the workflow that key belongs to with no workflow ID parameter.
| Endpoint | Purpose |
|---|---|
| POST /api/v1/runs | Start a new run (latest deployment; optional deployment_id to pin). |
| GET /api/v1/runs/{id} | Get run status, state, and current step. |
| GET /api/v1/runs/{id}/messages | List the run's conversation messages. |
| GET /api/v1/runs/{id}/stream | WebSocket stream of live run events. |
| POST /api/v1/runs/{id}/tokens | Mint a participant token for a role. |
| GET /api/v1/schema/workflow | The workflow JSON Schema (public, no auth). |
Start a run
POST /api/v1/runs
Authorization: Bearer cf_your_api_key_here
Content-Type: application/json
{
"input": { "name": "Alice", "issue": "Billing query" }
}| Field | Description |
|---|---|
| input | Object of initial run state, validated against the workflow's declared inputs. Available to nodes via template variables like {{state.name}}. |
| connections | Optional. Per-run credentials for connections whose fulfillment is set to caller, keyed by connection slug. |
| hooks | Optional. Run-scoped event hooks (see Triggers & Webhooks). |
Returns 202 Accepted — execution is asynchronous, queued immediately:
{ "run_id": "run_xyz789", "status": "pending" }inputfails validation against the workflow's declared inputs, the API returns 422 with an { "errors": [...] } array describing each problem.Get run status
GET /api/v1/runs/run_xyz789{
"id": "run_xyz789",
"status": "running",
"state": { "name": "Alice", "issue": "Billing query" },
"current_step_id": "ask-details",
"created_at": "2026-06-10T12:00:00Z",
"started_at": "2026-06-10T12:00:01Z"
}| Field | Description |
|---|---|
| status | pending → running → completed | failed. Waiting states appear while a HITL session is open. |
| state | The run's accumulated state object — initial input plus values captured by Input/Agent nodes. |
| current_step_id | ID of the node currently executing, if any. |
| error | Failure message when status is failed. |
Parallel operations
Durable Parallel progress is available through the authenticated management API. List fan-outs first, then use a fan-out ID to page branch items. The item response supplies an opaqueX-Next-Cursor header when another page is available.
GET /api/management/runs/{runID}/fanouts
GET /api/management/runs/{runID}/fanouts/{fanoutID}/items?cursor=<opaque-cursor>
GET /api/management/runs/{runID}/fanouts/{fanoutID}/items?status=failed
POST /api/management/runs/{runID}/fanouts/{fanoutID}/items/{itemID}/retry
POST /api/management/runs/{runID}/fanouts/{fanoutID}/items/{itemID}/cancel
POST /api/management/runs/{runID}/fanouts/{fanoutID}/items/batch-retry
POST /api/management/runs/{runID}/fanouts/{fanoutID}/items/batch-cancelBefore selecting ephemeral WorkflowCall.for_each, call GET /api/management/workflows/{workflowID}/ephemeral-eligibility. The response evaluates the latest active deployment and returns itsdeployment_id plus every nested blocker. A missing active deployment returns 409.
Retry is limited to failed or cancelled items. Cancel is limited to unstarted items. Batch operations accept an explicit list of one to 100 item IDs and are atomic: if any requested item is ineligible, no item changes. All operations return 409once an item is ineligible or the fan-out has reached a terminal join state. Filter item pages with status=active,completed, failed, orcancelled; filtering occurs before cursor pagination. See the Parallel execution guide for branch semantics and CLI examples.
Get run messages
GET /api/v1/runs/run_xyz789/messages[
{
"id": "msg_1",
"role": "assistant",
"content": "Hi Alice! How can I help with your billing query?",
"step_id": "support-agent",
"created_at": "2026-06-10T12:00:02Z"
}
]Useful for rendering transcripts or archiving conversations after a run completes.
Play voice recordings
Browser Live voice recordings are private management resources. From your host backend, list a run's recordings and mint a short-lived playback URL with a cfpat_ personal access token or management session. Never expose that management credential to the embedded browser.
GET /api/management/runs/{runID}/voice-recordings
Authorization: Bearer cfpat_your_management_token
POST /api/management/runs/{runID}/voice-recordings/{recordingID}/playback-url
Authorization: Bearer cfpat_your_management_token{ "url": "https://storage.example.com/…", "expires_in": 300 }Return only the presigned URL to your frontend and assign it to an HTML <audio> element. The URL expires after five minutes and supports range requests for seeking. Mint a new URL when playback starts after expiry; do not cache or persist it.
Use the corresponding /download-url endpoint only when the recording metadata hasallow_download: true. Playback remains available to authorized workspace users when downloads are disabled. Participant tokens and workflow keys cannot retrieve recording media.
Stream run events
For live updates, open a WebSocket instead of polling. Events are pushed as JSON frames as the engine executes:
wss://your-chatterfly.example.com/api/v1/runs/run_xyz789/streamAuthenticate the upgrade request with the same Authorization header. Each frame carries an event type (step started/completed, message created, run completed, etc.) and a payload.
Mint participant token
POST /api/v1/runs/run_xyz789/tokens
Authorization: Bearer cf_your_api_key_here
Content-Type: application/json
{ "role": "customer" }{ "participant_token": "eyJhbGciOiJIUzI1NiIs..." }The token is a JWT valid for 1 hour, scoped to this run and role. Pass it to the widget on your frontend. See Authentication for details.
Workflow schema
The full JSON Schema for workflow definitions is served publicly — handy for editor tooling and validation in CI:
GET /api/v1/schema/workflowErrors & rate limits
| Status | Meaning |
|---|---|
| 400 | Malformed request body or invalid ID. |
| 401 | Missing or invalid API key. Check the Authorization header format: Bearer cf_… |
| 404 | Run not found — or it belongs to a different deployment than your key. |
| 422 | Run input failed validation; response body contains an errors array. |
| 429 | Per-tenant rate limit exceeded. Back off and retry with exponential delay. |
Error responses share the shape { "error": "message" }.
