Skip to main content

Overview

Deployed conversational Flows expose a chat session API on the automation URL. Instead of a single /kickoff run, you create a session, send user messages as turns, optionally stream tokens and runtime events, and resume HITL pauses when a turn needs human feedback.
Conversational Flow chat is experimental. Endpoints are available only when the deployed Flow reports both conversational: true and handle_turn: true from GET /inspect.
For building the Flow itself (conversational = True, handle_turn, routers, tracing), see the open-source Conversational Flows guide.

Prerequisites

  1. Deploy a Flow automation that implements conversational turns (handle_turn).
  2. Copy the bearer token from the automation Status tab (same token used for /kickoff).
  3. Confirm chat is enabled via /inspect (below).
All requests use:
Base URL examples in this guide use https://your-flow-url.crewai.com.

Discover chat capability

Look for flow.chat:
If either flag is false, chat endpoints return 404 with "Conversational flow chat is not available".

End-to-end chat loop

1

Start a session

Create a chat session. Optionally register a completed-turn webhook and event webhooks for the session lifetime.
Response:
An empty body ({} or no body) is valid when you do not need webhooks.
2

Send a user message

Queue one turn for the session:
Response:
Roles accepted in messageHistory: user, assistant, system, tool.
3

Wait for the turn to finish

Poll the turn with the returned kickoff_id (same status API as a normal Flow kickoff):
Only one turn can be active per session. A second /message while active_kickoff_id is set returns 409:
Wait until history shows active_kickoff_id: null (or the turn reaches a terminal status / pause) before sending the next message.
4

Read session history

Streaming a turn

Streaming is optional. Use it when a UI needs tokens or runtime events as the turn runs. Frames always include lifecycle types (turn_started, turn_completed, turn_failed, token, error). Additional event frames can be filtered with the events query parameter (* or a comma-separated list).

Option A: HTTP message + SSE attach

  1. POST /chat/{session_id}/message with "stream": true.
  2. Attach to the active turn:
SSE returns text/event-stream JSON frames (data: {...}), plus keepalive comments. The stream ends on turn_completed or turn_failed. If there is no active turn, this endpoint returns 409 (No active chat turn).

Option B: WebSocket (attach or send)

Auth: pass the bearer token as the token query param, or as an Authorization: Bearer ... header when your client supports WebSocket headers. Behavior:
  • Active turn already running — the socket attaches and first emits turn_started with data.status: "attached", then streams frames until a terminal type.
  • No active turn — send a JSON message to queue a turn, then consume the stream:
The server responds with turn_started (status: "queued") and then stream frames for that kickoff_id. Use last_event_id / lastEventId to resume after disconnects.

Example stream frames

HITL inside a chat session

If a turn pauses for human feedback (status / state PAUSED), resume with the same Flow resume endpoint used for non-chat runs:
Then poll the resume kickoff_id from the response. Wait until /history shows active_kickoff_id: null before sending the next chat message. See HITL Workflows and Flow HITL Management for platform review UX.

API reference

Common errors

Conversational Flows

Build multi-turn Flows with handle_turn, routers, and tracing.

Kickoff Crew / Flow

Single-run kickoff and status polling on a deployment URL.

Webhook Streaming

Event webhook payload shape and authentication options.

Flow HITL Management

Email-first human review for paused Flow steps.