Conversations
Text-based agent conversations over REST and WebSocket - full CRUD lifecycle, persistent freeze-thaw, cross-channel continuity.
API Surface
Architecture
Conversation Lifecycle
What Gets Saved
Session Timing (WebSocket)
Completion Reasons
REST API
Create a Conversation
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
HSM execution channel type.
Determines how the HSM engine communicates with end users. Each kind maps to one or more providers.
webPossible values: Destination address for an outbound conversation (E.164 for sms/imessage). Required for non-web.
Channel-manager use case the outbound conversation is sent through. Required for non-web; channel-manager resolves the sender (FROM) from it (never caller-supplied). Must be owned by this workspace.
Optional context steering what the agent opens with on an outbound conversation.
Outbound thread-keyed channels (sms/imessage) only: close any existing ACTIVE conversation on the computed provider thread (recipient + use case) before dispatching, so the opener materializes a brand-new conversation instead of continuing the old thread. Rejected with 422 on channel=web — every web create already starts a new conversation, so force_new is meaningless there.
falseSuccessful Response
HSM execution channel type.
Determines how the HSM engine communicates with end users. Each kind maps to one or more providers.
0Validation Error
Starting an Outbound Conversation
Send a Turn
Send a user message and receive the agent's response. Set Accept: text/event-stream to receive an SSE stream of typed TurnStreamEvent frames (token, tool_call_started, tool_call_completed, thinking, message, done, error) instead of the synchronous JSON response. For new integrations prefer POST /turns/stream, which is always SSE.
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Include tool call details in response
falsePoll for background results without sending a user message. Drains any background tool calls that completed since the last turn and reports them; returns empty output when nothing is pending. Must NOT be combined with a request-body message (422) or SSE streaming (422). Poll no more than once every ~5s per conversation — each poll loads session state.
false""Injected into the agent's prompt as caller/patient context for this turn.
Synchronous callers only: when a turn hands work to a background tool (background_pending), await the real answer inline (bounded, ~30s) instead of returning the acknowledgement immediately. On completion the response carries the final answer with background_pending=false; on timeout it returns background_pending=true — resolve it later with poll=true. null (default) inherits the channel policy (web = do not wait). Ignored with poll=true (422).
Synchronous callers only: when a turn ends background_pending, omit the filler/acknowledgement text from output so a batch caller never mistakes the ack for the answer (output is empty; background_pending=true is the poll-later signal). null (default) inherits the channel policy. Ignored with poll=true (422).
Successful Response
Identifier of the user exchange this turn created — or, for poll=true and greeting-kickoff turns (empty message), the latest exchange the returned messages attach to. Deterministic: matches the turn_id on this conversation's history turns, so it can anchor durable per-turn artifacts (e.g. feedback) across page reloads. Null only when the conversation has no user exchange yet (a poll or kickoff before the first user message).
Whether this turn's output is the final answer, or only an acknowledgement that
work is still running in the background.
false (default): output is the complete agent response for this turn.
true: a tool crossed the server's blocking window and was handed to a background
task, so output is NOT the final answer — the definitive assistant answer is
produced later, out-of-band. It is durable on the conversation: drain it by
re-issuing POST …/turns with poll=true (a no-message drain-and-report), by
sending the next user turn, or by reading the conversation back
(GET …/conversations/{id}). This is the per-conversation delivery contract — see
the web-integration paved path. (The workspace observer bus,
GET /v1/{workspace_id}/events/stream, mirrors this activity as text.agent_message
/ text.tool_started / text.background_result for dashboards watching many
conversations, but is not the per-chat delivery path.) A client that treats a
background_pending=true turn as complete without draining will miss the final answer.
falseValidation Error
Background (deferred) tool results
Streaming Turns (SSE)
Event Schema
Example wire format
Streaming behavior
Concurrency
Distinguishing "busy" from "closed"
Retry strategy
What if your HTTP client times out?
Lock release timing
List Conversations
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Filter by channel
Filter by status
200Successful Response
Validation Error
Switch Conversation Channel
Request Body
Response
Error Responses
Get Conversation Detail
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Include per-turn tool_calls[] in the returned turns. Off by default so the payload stays small and (potentially PHI-bearing) tool output is opt-in, matching POST /turns?include_tool_calls=true.
falseSuccessful Response
HSM execution channel type.
Determines how the HSM engine communicates with end users. Each kind maps to one or more providers.
0Validation Error
Close a Conversation
API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.
Successful Response
No content
Validation Error
No content
Example: Full REST Flow
WebSocket Sessions
Connect
Close codes
Message Queuing and Coalescing
Tool Call Details
Greeting Behavior
Outbound Text (SMS and iMessage)
Inbound SMS and WhatsApp
World Model Integration
Signal Processing
Intelligence
Switching Between REST and WebSocket
Graceful Degradation
Last updated
Was this helpful?

