Skip to content

Widget messages API

Visitor messages from the web widget are posted to this endpoint. Supports synchronous JSON and SSE streaming.

POST /api/v1/widget/messages
AuthMechanism
Deploymentdeployment_id in body
DomainOrigin header must match allowlist
Identity (optional)Authorization: Bearer <jwt> when JWT verification is enabled

No organization API key is used from the browser.

{
"deployment_id": "dep_abc123",
"conversation_id": "conv_8mN4pQ1r",
"content": "Do you ship to Canada?"
}

Omit conversation_id to start a new conversation. The response includes conversation_id for follow-up messages.

Response:

{
"id": "msg_4pQ8rS2t",
"conversation_id": "conv_8mN4pQ1r",
"role": "assistant",
"content": "Yes, we ship to all Canadian provinces…",
"citations": [],
"created_at": "2026-07-16T10:12:00Z"
}

Set stream: true:

{
"deployment_id": "dep_abc123",
"conversation_id": "conv_8mN4pQ1r",
"content": "Show me your summer offers",
"stream": true
}

Response Content-Type: text/event-stream.

EventPurpose
step_messageProgress text, e.g. “Searching knowledge base…”
tool_callTool invocation started
tool_resultTool completed
doneFinal message with content and optional rich_content
errorTerminal failure

Full payload reference: Widget SSE events.

Example stream:

event: step_message
data: {"message":"Thinking…"}
event: tool_call
data: {"name":"get_offers","message":"Running get_offers…"}
event: tool_result
data: {"name":"get_offers","success":true}
event: done
data: {"content":"Here are our summer offers:","rich_content":{"type":"carousel","items":[…]}}

When the deployment requires identity verification, include a signed JWT:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs…

See JWT embed verification.

Widget message requests share the Widget rate limit bucket (120 req/min per deployment). Heavy traffic may also hit per-visitor throttles.