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:

http
Authorization: Bearer cfw_your_workflow_key_here
Content-Type: application/json

A 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.

EndpointPurpose
POST /api/v1/runsStart 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}/messagesList the run's conversation messages.
GET /api/v1/runs/{id}/streamWebSocket stream of live run events.
POST /api/v1/runs/{id}/tokensMint a participant token for a role.
GET /api/v1/schema/workflowThe workflow JSON Schema (public, no auth).

Start a run

http
POST /api/v1/runs
Authorization: Bearer cf_your_api_key_here
Content-Type: application/json

{
  "input": { "name": "Alice", "issue": "Billing query" }
}
FieldDescription
inputObject of initial run state, validated against the workflow's declared inputs. Available to nodes via template variables like {{state.name}}.
connectionsOptional. Per-run credentials for connections whose fulfillment is set to caller, keyed by connection slug.
hooksOptional. Run-scoped event hooks (see Triggers & Webhooks).

Returns 202 Accepted — execution is asynchronous, queued immediately:

json
{ "run_id": "run_xyz789", "status": "pending" }
Note: If inputfails validation against the workflow's declared inputs, the API returns 422 with an { "errors": [...] } array describing each problem.

Connection authority

For caller-fulfilled connections, connectionsis keyed by the logical connection slug. Setcredential_ownership tobroker for metadata-only host authority, ortransfer when Chatterfly becomes the exclusive refresh owner. One ownership mode applies to every supplied entry.

json
{
  "credential_ownership": "broker",
  "connections": {
    "zoho-crm": {
      "grant_reference": "opaque-host-reference",
      "provider_account_id": "verified-account",
      "organization_id": "verified-organization",
      "actor_id": "verified-actor",
      "region": "eu",
      "scopes": ["ZohoCRM.modules.leads.CREATE"]
    }
  }
}
Warning: Build this request on a trusted backend. Do not send refresh grants, broker secrets, regional provider hosts, or browser-selected identity. Use an Idempotency-Key for replay-safe run creation. Exact schemas and validation errors are published at$APP_URL/openapi.yaml.

Management clients can inspect safe operation contracts atGET /api/management/connections/{id}/operations, read normalized field metadata atGET /api/management/connections/{id}/metadata, and request a refresh with the corresponding/metadata/refresh endpoint. Responses never include provider credentials.

Get run status

http
GET /api/v1/runs/run_xyz789
json
{
  "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"
}
FieldDescription
statuspending → running → completed | failed. Waiting states appear while a HITL session is open.
stateThe run's accumulated state object — initial input plus values captured by Input/Agent nodes.
current_step_idID of the node currently executing, if any.
errorFailure 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.

http
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-cancel

Before 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

http
GET /api/v1/runs/run_xyz789/messages
json
[
  {
    "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.

http
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
json
{ "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.

Warning: These endpoints cover Chatterfly-stored browser/widget Gemini Live recordings. Phone recording endpoints currently return provider-hosted metadata only and do not expose media URLs.

Stream run events

For live updates, open a WebSocket instead of polling. Events are pushed as JSON frames as the engine executes:

text
wss://your-chatterfly.example.com/api/v1/runs/run_xyz789/stream

Authenticate 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.

Tip: For browser-side streaming use the widget or participant endpoints — this server stream is meant for backend consumers, since it requires your API key.

Mint participant token

http
POST /api/v1/runs/run_xyz789/tokens
Authorization: Bearer cf_your_api_key_here
Content-Type: application/json

{ "role": "customer" }
json
{ "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:

http
GET /api/v1/schema/workflow

Errors & rate limits

StatusMeaning
400Malformed request body or invalid ID.
401Missing or invalid API key. Check the Authorization header format: Bearer cf_…
404Run not found — or it belongs to a different deployment than your key.
422Run input failed validation; response body contains an errors array.
429Per-tenant rate limit exceeded. Back off and retry with exponential delay.

Error responses share the shape { "error": "message" }.