The Chat object
The Chat API reads and works the website chat queue: the conversations visitors start from the chat widget on your site. It is the same queue as the Chat screen in the app. A conversation closed, assigned or tagged through the API reads the same way there, and the other way round.
Who is answering
Every conversation has a handler:
handler | Meaning |
|---|---|
WAITING | The team has been notified and nobody has picked it up. The visitor is waiting for a person |
HUMAN | A named rep, handlerUser, is answering. Only that rep can write into the conversation |
AI | The AI agent is answering. In a workspace without an AI agent, it means nobody is, and the visitor has been asked to leave their details |
A rep moves a conversation to HUMAN by taking it over or simply by replying. Handing it back returns it to WAITING inside the site's team hours, or to the AI agent outside them.
Separately from who is answering, each conversation has a place in the team queue: open or closed, an assignee, tags, and the Spam and Trash folders.
Conversation fields
| Field | Type | Notes |
|---|---|---|
id | string | The conversation ID |
threadKey | string | The conversation's key in the team inbox: chat: followed by the ID |
status | string | OPEN or CLOSED. Closed means handled, for the whole team |
spam | boolean | In the Spam folder |
trashed | boolean | In the Trash folder |
handler | string | AI, HUMAN or WAITING, described above |
handlerUser | object or null | { id, name } of the rep answering, when handler is HUMAN |
waitingReason | string or null | Why a person is needed, when handler is WAITING |
waitingSince | string (ISO 8601) or null | When the conversation started waiting for a person |
waitingMins | integer or null | How many minutes the visitor has waited. Only set while handler is WAITING |
live | boolean | The visitor wrote in the last two minutes and is probably still on the page |
hot | boolean | The AI agent flagged the visitor as a likely buyer |
site | object | { id, name } of the chat site the conversation came from |
visitor | object | What the visitor told us and where they were. See below |
contact | object or null | { id, name, email } of the contact the visitor is linked to |
lead | object or null | { id, name, email } of the lead the visitor is linked to |
assignee | object or null | { id, name } of the conversation's owner. null is Unassigned |
tags | array | { id, name, color } for each tag, sorted by name |
subject | string | The visitor's latest message, shortened, or New chat before they have written |
snippet | string | The latest message from the visitor or a rep, shortened |
messageCount | integer | Messages written by the visitor and by reps. AI and system lines are not counted |
lastMessageAt | string (ISO 8601) | The newest message of any kind |
lastVisitorAt | string (ISO 8601) or null | When the visitor last wrote |
lastAgentAt | string (ISO 8601) or null | When a rep or the AI agent last wrote to the visitor |
createdAt | string (ISO 8601) | When the visitor opened the chat |
The visitor object
| Field | Type | Notes |
|---|---|---|
name, email, phone | string or null | What the visitor typed in, as they typed it |
pageUrl | string or null | The page the conversation started on |
referrer | string or null | The page that sent them there |
locale, timezone | string or null | From the visitor's browser |
blocked | boolean | The visitor is blocked from starting new conversations on this site, after being marked as spam |
blockedUntil | string (ISO 8601) or null | When the block ends |
Example object
{
"id": "cmq5chat0alk34567890",
"threadKey": "chat:cmq5chat0alk34567890",
"status": "OPEN",
"spam": false,
"trashed": false,
"handler": "HUMAN",
"handlerUser": { "id": "cmq1user0alk34567890", "name": "Kevin Rep" },
"waitingReason": null,
"waitingSince": null,
"waitingMins": null,
"live": true,
"hot": false,
"site": { "id": "cmq4site0alk34567890", "name": "Main website" },
"visitor": {
"name": "Ann",
"email": "ann@buyer.example",
"phone": null,
"pageUrl": "https://example.com/pricing",
"referrer": "https://www.google.com/",
"locale": "en-CA",
"timezone": "America/Toronto",
"blocked": false,
"blockedUntil": null
},
"contact": null,
"lead": { "id": "cmq2lead0alk34567890", "name": "Ann", "email": "ann@buyer.example" },
"assignee": { "id": "cmq1user0alk34567890", "name": "Kevin Rep" },
"tags": [{ "id": "cmq3tag00alk34567890", "name": "Pricing", "color": null }],
"subject": "Do you ship to Canada?",
"snippet": "Yes, we ship to Canada. Most orders arrive in 3 to 5 business days.",
"messageCount": 2,
"lastMessageAt": "2026-09-27T14:03:10.000Z",
"lastVisitorAt": "2026-09-27T14:02:00.000Z",
"lastAgentAt": "2026-09-27T14:03:10.000Z",
"createdAt": "2026-09-27T14:01:40.000Z"
}Message fields
GET /api/v1/chats/{id} returns the transcript as a list of messages, oldest first.
| Field | Type | Notes |
|---|---|---|
id | string | The message ID. Pass it as after to fetch only newer messages |
role | string | VISITOR, USER (a rep), AI (the AI agent) or SYSTEM |
userId | string or null | The rep who wrote a USER message |
userName | string or null | That rep's name |
body | string | The text |
createdAt | string (ISO 8601) | When it was written |
SYSTEM messages are narration, such as "Kevin joined the conversation". Nobody typed them.
Conversations are created by visitors through the chat widget. The API cannot start a conversation, and it has no delete endpoint: use spam for junk.