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"
}
]
}
}
]
}
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 two 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. |
A single webhook can contain both change types — for example, when a node sends a message and then transfers the conversation 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.
Text
A plain text message.
{
"type": "text",
"text": {
"body": "Your order #12345 has been shipped!"
}
}
| Field | Type | Description |
|---|
text.body | string | The text content. |
A file attachment (image, video, audio, or document).
{
"type": "media",
"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, or document. |
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. |
A message with tappable buttons (up to 3).
{
"type": "interactive",
"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. |
Interactive — List
A scrollable list with sections and rows.
{
"type": "interactive",
"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. |
Interactive — CTA URL
A message with a link button.
{
"type": "interactive",
"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. |
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"
}
| Field | Type | Description |
|---|
type | string | Always "transfer". |
targetType | string | "sector" or "agent". |
targetId | string | UUID of the target sector or agent. |
Finish
The session was finalized.
| Field | Type | Description |
|---|
type | string | Always "finish". |
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"
}
]
}
}
]
}
Delivery
| Property | Value |
|---|
| Method | POST |
| Content-Type | application/json |
| Timeout | 10 seconds per attempt |
| Retries | 3 attempts with exponential backoff (1s, 2s, 4s) |
Your endpoint must respond with a 2xx status code. Non-2xx responses are treated as failures and will be retried up to 3 times.