Skip to main content

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

FieldTypeDescription
sessionIdstringUUID of the session.
messageIdstringUUID of the inbound message that triggered this flow step.
changesarrayOne 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:
fieldWhen it appearsWhat 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!"
  }
}
FieldTypeDescription
text.bodystringThe text content.
tagsstring[]?Tags configured on the flow node (optional).

Media

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"
  }
}
FieldTypeDescription
media.typestringimage, video, audio, document, or sticker.
media.mimeTypestringMIME type (e.g., image/png, application/pdf).
media.urlstringPublic URL of the file.
media.captionstring?Optional text displayed with the media.
tagsstring[]?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"]
  }
}
FieldTypeDescription
template.idstringID of the template registered in WhatsApp Business.
template.paramsstring[]Interpolated parameters in the order defined by the template.
tagsstring[]?Tags configured on the flow node (optional).

Interactive — Button

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" }
      ]
    }
  }
}
FieldTypeDescription
interactive.typestringAlways "button".
interactive.body.textstringMain message text.
interactive.footer.textstring?Optional footer text.
interactive.action.buttonsarrayArray of button objects with id and title.
tagsstring[]?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"
            }
          ]
        }
      ]
    }
  }
}
FieldTypeDescription
interactive.typestringAlways "list".
interactive.body.textstringMain message text.
interactive.footer.textstring?Optional footer text.
interactive.action.buttonstringLabel of the button that opens the list.
interactive.action.sectionsarrayArray of sections, each with title and rows.
rows[].idstringRow identifier.
rows[].titlestringRow label.
rows[].descriptionstring?Optional secondary text.
tagsstring[]?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"
      }
    }
  }
}
FieldTypeDescription
interactive.typestringAlways "cta_url".
interactive.body.textstringMain message text.
interactive.action.parameters.display_textstringButton label.
interactive.action.parameters.urlstringURL the button opens.
tagsstring[]?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
}
FieldTypeDescription
typestringAlways "transfer".
targetTypestring"sector" or "agent".
targetIdstringUUID of the target sector or agent.
timestampnumberMicroseconds since Unix epoch. Ensures collision-free ordering.

Finish

The session was finalized.
{
  "type": "finish",
  "timestamp": 1745039000234567
}
FieldTypeDescription
typestringAlways "finish".
timestampnumberMicroseconds 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
}
typeWhen
card.createdA card was created by the flow.
card.stage.changedA card was moved to another stage.
card.updatedCard values or tags were updated.
card.deletedA card was removed.
FieldTypeDescription
domainstringAlways "kanban" for kanban events.
typestringEvent type (see table above).
payloadobjectEvent-specific data (card, pipeline, stage IDs).
timestampnumberMicroseconds 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

PropertyValue
MethodPOST
Content-Typeapplication/json
Timeout5 seconds per attempt
Retries3 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.