Documentation Index
Fetch the complete documentation index at: https://docs.whatabot.app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
When a session processes a message, whatabot sends a POST request to the callback URL configured on your API Key. This is how your system receives the bot’s responses — text messages, media, interactive menus, transfers, and session finalization.
Configuration
The webhook URL is set per API Key via the callbackUrl field. See Create API Key or Update API Key.
The callback URL must use HTTPS and cannot point to localhost, loopback
addresses, or private IP ranges (10.x.x.x, 192.168.x.x, etc.).
Payload Structure
Every webhook is a POST request with the following JSON body:
{
"sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"changes": [
{
"field": "messages",
"value": {
"messages": [
{
"type": "text",
"text": {
"body": "Hello! How can I help you today?"
}
},
{
"type": "interactive",
"interactive": {
"type": "button",
"body": { "text": "Choose an option:" },
"action": {
"buttons": [
{ "id": "btn-1", "title": "Track Order" },
{ "id": "btn-2", "title": "Talk to Agent" }
]
}
}
}
]
}
},
{
"field": "function",
"value": {
"functions": [
{
"type": "transfer",
"targetType": "sector",
"targetId": "sector-uuid",
"timestamp": 1745039000123456
}
]
}
},
{
"field": "event",
"value": {
"events": [
{
"domain": "kanban",
"type": "card.stage.changed",
"payload": {
"cardId": "card-uuid",
"pipelineId": "pipeline-uuid",
"stageId": "new-stage-uuid",
"previousStageId": "old-stage-uuid"
},
"timestamp": 1745039000234567
}
]
}
}
]
}
Top-level Fields
| Field | Type | Description |
|---|
sessionId | string | UUID of the session. |
messageId | string | UUID of the inbound message that triggered this flow step. |
changes | array | One or more changes produced by the flow. Each change has a field and a value. |
The changes Array
The changes array tells your system what happened during this flow step. There are three possible change types:
field | When it appears | What value contains |
|---|
"messages" | The flow produced messages to send to the user. | { "messages": [...] } — an array of outgoing messages. |
"function" | The flow triggered an action (transfer or finish). | { "functions": [...] } — an array of function calls. |
"event" | The flow emitted domain events (e.g., kanban). | { "events": [...] } — an array of domain events. |
A single webhook can contain multiple change types — for example, when a node sends a message, transfers the conversation, and emits a kanban event in the same step.
Message Types
When field is "messages", the value.messages array contains one or more messages. Each message has a type that determines its structure.
All messages may contain an optional tags field (string[]) with the tags configured on the flow node that produced the message. Use tags to categorize or route messages in your system.
Text
A plain text message.
{
"type": "text",
"tags": ["orders"],
"text": {
"body": "Your order #12345 has been shipped!"
}
}
| Field | Type | Description |
|---|
text.body | string | The text content. |
tags | string[]? | Tags configured on the flow node (optional). |
A file attachment (image, video, audio, document, or sticker).
{
"type": "media",
"tags": ["catalog"],
"media": {
"type": "image",
"mimeType": "image/png",
"url": "https://example.com/catalog.png",
"caption": "Our latest catalog"
}
}
| Field | Type | Description |
|---|
media.type | string | image, video, audio, document, or sticker. |
media.mimeType | string | MIME type (e.g., image/png, application/pdf). |
media.url | string | Public URL of the file. |
media.caption | string? | Optional text displayed with the media. |
tags | string[]? | Tags configured on the flow node (optional). |
Template
A pre-approved WhatsApp message template.
{
"type": "template",
"tags": ["welcome"],
"template": {
"id": "welcome_message",
"params": ["John", "12345"]
}
}
| Field | Type | Description |
|---|
template.id | string | ID of the template registered in WhatsApp Business. |
template.params | string[] | Interpolated parameters in the order defined by the template. |
tags | string[]? | Tags configured on the flow node (optional). |
A message with tappable buttons (up to 3).
{
"type": "interactive",
"tags": ["support"],
"interactive": {
"type": "button",
"body": {
"text": "How can we help you?"
},
"footer": {
"text": "Choose an option"
},
"action": {
"buttons": [
{ "id": "btn-1", "title": "Track Order" },
{ "id": "btn-2", "title": "New Purchase" },
{ "id": "btn-3", "title": "Talk to Agent" }
]
}
}
}
| Field | Type | Description |
|---|
interactive.type | string | Always "button". |
interactive.body.text | string | Main message text. |
interactive.footer.text | string? | Optional footer text. |
interactive.action.buttons | array | Array of button objects with id and title. |
tags | string[]? | Tags configured on the flow node (optional). |
Interactive — List
A scrollable list with sections and rows.
{
"type": "interactive",
"tags": ["menu"],
"interactive": {
"type": "list",
"body": {
"text": "Browse our departments:"
},
"footer": {
"text": "Tap to see options"
},
"action": {
"button": "View Departments",
"sections": [
{
"title": "Sales",
"rows": [
{
"id": "row-1",
"title": "New Orders",
"description": "Place a new order"
},
{
"id": "row-2",
"title": "Promotions",
"description": "Current deals"
}
]
}
]
}
}
}
| Field | Type | Description |
|---|
interactive.type | string | Always "list". |
interactive.body.text | string | Main message text. |
interactive.footer.text | string? | Optional footer text. |
interactive.action.button | string | Label of the button that opens the list. |
interactive.action.sections | array | Array of sections, each with title and rows. |
rows[].id | string | Row identifier. |
rows[].title | string | Row label. |
rows[].description | string? | Optional secondary text. |
tags | string[]? | Tags configured on the flow node (optional). |
Interactive — CTA URL
A message with a link button.
{
"type": "interactive",
"tags": ["website"],
"interactive": {
"type": "cta_url",
"body": {
"text": "Visit our website for more details"
},
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Open Website",
"url": "https://example.com"
}
}
}
}
| Field | Type | Description |
|---|
interactive.type | string | Always "cta_url". |
interactive.body.text | string | Main message text. |
interactive.action.parameters.display_text | string | Button label. |
interactive.action.parameters.url | string | URL the button opens. |
tags | string[]? | Tags configured on the flow node (optional). |
Function Types
When field is "function", the value.functions array contains one or more actions triggered by the flow.
Transfer
The conversation was transferred to a human agent or sector.
{
"type": "transfer",
"targetType": "sector",
"targetId": "sector-uuid",
"timestamp": 1745039000123456
}
| Field | Type | Description |
|---|
type | string | Always "transfer". |
targetType | string | "sector" or "agent". |
targetId | string | UUID of the target sector or agent. |
timestamp | number | Microseconds since Unix epoch. Ensures collision-free ordering. |
Finish
The session was finalized.
{
"type": "finish",
"timestamp": 1745039000234567
}
| Field | Type | Description |
|---|
type | string | Always "finish". |
timestamp | number | Microseconds since Unix epoch. Ensures collision-free ordering. |
Event Types
When field is "event", the value.events array contains domain events emitted during flow processing. Each event has domain, type, payload, and timestamp.
Kanban
Events emitted when the flow interacts with the kanban (Kanban Move node) or when operations are performed on cards linked to active sessions.
{
"domain": "kanban",
"type": "card.created",
"payload": {
"cardId": "card-uuid",
"pipelineId": "pipeline-uuid",
"stageId": "stage-uuid"
},
"timestamp": 1745039000345678
}
type | When |
|---|
card.created | A card was created by the flow. |
card.stage.changed | A card was moved to another stage. |
card.updated | Card values or tags were updated. |
card.deleted | A card was removed. |
| Field | Type | Description |
|---|
domain | string | Always "kanban" for kanban events. |
type | string | Event type (see table above). |
payload | object | Event-specific data (card, pipeline, stage IDs). |
timestamp | number | Microseconds since Unix epoch. Ensures collision-free ordering. |
Complete Example
A typical webhook where the bot sends a greeting and presents buttons:
{
"sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"changes": [
{
"field": "messages",
"value": {
"messages": [
{
"type": "text",
"text": {
"body": "Welcome to Acme Store! 👋"
}
},
{
"type": "interactive",
"interactive": {
"type": "button",
"body": { "text": "What would you like to do?" },
"footer": { "text": "Select an option" },
"action": {
"buttons": [
{ "id": "btn-track", "title": "Track Order" },
{ "id": "btn-support", "title": "Talk to Support" }
]
}
}
}
]
}
}
]
}
A webhook where the bot transfers the conversation:
{
"sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"changes": [
{
"field": "messages",
"value": {
"messages": [
{
"type": "text",
"text": {
"body": "Transferring you to our support team..."
}
}
]
}
},
{
"field": "function",
"value": {
"functions": [
{
"type": "transfer",
"targetType": "sector",
"targetId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": 1745039000123456
}
]
}
}
]
}
A webhook with kanban events (card created and moved during the flow):
{
"sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"changes": [
{
"field": "messages",
"value": {
"messages": [
{
"type": "text",
"text": {
"body": "Your order has been added to the sales pipeline."
}
}
]
}
},
{
"field": "event",
"value": {
"events": [
{
"domain": "kanban",
"type": "card.created",
"payload": {
"cardId": "550e8400-e29b-41d4-a716-446655440000",
"pipelineId": "660e8400-e29b-41d4-a716-446655440000",
"stageId": "770e8400-e29b-41d4-a716-446655440000"
},
"timestamp": 1745039000345678
},
{
"domain": "kanban",
"type": "card.stage.changed",
"payload": {
"cardId": "550e8400-e29b-41d4-a716-446655440000",
"pipelineId": "660e8400-e29b-41d4-a716-446655440000",
"stageId": "880e8400-e29b-41d4-a716-446655440000",
"previousStageId": "770e8400-e29b-41d4-a716-446655440000"
},
"timestamp": 1745039000456789
}
]
}
}
]
}
Delivery
| Property | Value |
|---|
| Method | POST |
| Content-Type | application/json |
| Timeout | 5 seconds per attempt |
| Retries | 3 attempts with exponential backoff (1s, 2s, 4s) |
Your endpoint must respond within 5 seconds. After that, the request is
considered a failure and will be retried. Make sure your server processes
requests quickly or use queues to handle the data asynchronously.
Your endpoint must respond with a 2xx status code. Non-2xx responses are
treated as failures and will be retried up to 3 times.