Set or Change Chat Workflow

Attach a workflow to a chat, or move the chat one stage along it — the same action a team member takes from the inbox sidebar, under the same rules:

  • Attach: pass workflowId (from GET /workflows/{organisationId}) and no stageId. The chat lands on the workflow's initial stage (outcome: attached). If it is already on this workflow nothing changes (unchanged).
  • Move: pass workflowId + stageId. The move must be ONE allowed transition from the current stage (see availableTransitions on GET …/workflow); otherwise 409 ILLEGAL_TRANSITION. When the chat is not on the workflow yet, it is attached first and then moved if the stage is one hop from the initial stage (attached); if not reachable in one hop the chat stays on the initial stage and the outcome is partial with code: STAGE_UNREACHABLE.
  • Finish: moving into a final stage finishes the run. Where the workflow requires a disposition first, the move is refused with 409 DISPOSITION_REQUIRED and nothing is written. Where the workflow or organisation resolves chats on finish, the chat is marked resolved too — unless keepChatOpen: true.
  • Finished runs: a chat whose run already finished answers outcome: finished and does not change, unless onFinished: "restart" starts a new run from the initial stage (restarted; on a resolved chat this reopens it where the resolve-on-finish rule applies).
  • Switch workflows: a chat that is live on a DIFFERENT workflow is refused with 409 ACTIVE_WORKFLOW_CONFLICT (the body lists activeWorkflows). Pass replaceActive: true to close that run and switch; the closed run is kept in the history as "Superseded by workflow change via API". The other run is closed after the switch succeeds — except when the target is a final stage, where it is closed first so the closing rules can resolve the chat; a refusal after that point (e.g. DISPOSITION_REQUIRED) lists replacedWorkflowIds in the error body.

Every attach fires the chat.workflow_started webhook with trigger: "API"; every move or restart fires chat.state_changed — exactly as a team member's change does, so automations and Meta lead signals react to it too. The stage history attributes the change to the API user your token belongs to. remarks (max 200 characters) is stored with the change.

One hop per call: to move several stages, call once per stage. Concurrent updates to the same chat are serialised; a call that finds another update in progress answers 409 WORKFLOW_BUSY — retry after a moment.

Requires CRM_ADMIN, ACCOUNT_OWNER, or CRM_BOT.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Path Params
string
required

Your organisation UUID (returned as org from the /token endpoint).

string
required

The chat UUID (the chatId from the chat list / create-chat response).

Body Params
string
required

The workflow to attach, or to move within (workflowId from GET /workflows/{org}).

string

Target stage id. Omit it (or pass the initial stage) to attach only: the chat lands on the workflow's initial stage, or stays where it is when it is already on this workflow. A move must be ONE allowed transition from the current stage (availableTransitions on GET …/workflow); anything else is refused with 409 ILLEGAL_TRANSITION. When the call attaches or restarts first, the stage must be one hop from the initial stage, otherwise the outcome is partial.

string

Note stored with the stage change and shown in the chat's stage history (max 200 characters).

string
enum

What to do when the chat's run on this workflow has already reached a final stage. leave (default) = change nothing and answer with outcome finished; restart = start a new run from the initial stage (then move to stageId when given and one hop away). Restarting on a resolved chat reopens it where the workflow's resolve-on-finish rule applies, exactly as a team member's restart does.

Allowed:
boolean

Only read when the move lands on a final stage: true keeps the chat open even where the workflow or organisation rule would mark it resolved. It cannot force a resolve where that rule is off.

boolean

When the chat is live on a DIFFERENT workflow: true closes that run (recorded in its history as "Superseded by workflow change via API") and switches; false/omitted refuses with 409 ACTIVE_WORKFLOW_CONFLICT listing the live workflows. Ignored when nothing else is live.

Responses

400

Validation failed (workflowId not a UUID, stageId/remarks too long, unknown onFinished), the workflow has no initial stage (NO_START_STAGE), or the underlying step rejected the request (REJECTED).

401

Unauthorized

403

Forbidden

404

Not found in your organisation — code is CHAT_NOT_FOUND, WORKFLOW_NOT_FOUND or STAGE_NOT_FOUND.

409

Refused — code is ILLEGAL_TRANSITION (not an allowed move from the current stage), DISPOSITION_REQUIRED (capture a chat disposition first), ACTIVE_WORKFLOW_CONFLICT (live on another workflow; body lists activeWorkflows), WORKFLOW_INACTIVE, CURRENT_STAGE_UNKNOWN (the chat sits on a stage that was deleted from the workflow) or WORKFLOW_BUSY (another update to this chat is in progress — retry).

429

Too many requests

503

LOCK_UNAVAILABLE — the lock service is unavailable; nothing was changed. Retry later.

Language
Credentials
Bearer
JWT
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json