Chat
POST /api/v1/{organisation}/widgets/{widget}/chat
Auth: widget domain, widget secret, or organisation API key with chat
Widget type: chatbot
Billing: uses one answer from your plan. When you have no answers left, the API returns 402. The official embed falls back to search in that case.
Body
| Field | Type | Required | Description |
|---|---|---|---|
query |
string | yes | Visitor message, max 2048 characters |
conversation_id |
string | no | Continue an existing conversation |
session_id |
string | no | Analytics session |
browser_language |
string | no | Language hint from the visitor's browser |
context |
object | no | Up to 10 string keys with simple values (for example page URL or title) |
user |
object | no | { "id": "…", "hash": "…" } signed visitor identity |
stream |
bool | no | Set true for a streamed response instead of one JSON payload |
JSON response (stream false or omitted)
{
"data": {
"text": "…answer in markdown…",
"conversation_id": "…",
"answer_id": "…",
"sources": [
{
"id": "0194b…",
"external_id": "wp-42",
"name": "Hello world",
"url": "https://example.com/hello-world",
"snippet": "…",
"score": 0.91,
"meta": null
}
]
},
"session_id": "…"
}
Streaming ("stream": true)
The response is a stream of server-sent events (text/event-stream):
| Event | Data | When |
|---|---|---|
status |
{ "step": "searching", "query": "…" } |
Looking up sources |
token |
{ "text": "…" } |
Next piece of the answer |
done |
{ "conversation_id", "session_id", "answer_id", "sources": […] } |
Finished |
error |
{ "message": "…" } |
Something failed mid-stream |
Identity and conversation ownership
- With a valid
user.idanduser.hash, the conversation belongs to that verified visitor. - Continuing a verified conversation without the same proof returns 403.
- A bad hash returns 422.
See Conversations for listing history, reading transcripts, keeping conversations, and deletion.