VoxLink.ai

API Reference

Conversation Ended Webhook

Webhook sent after a chat conversation ends containing transcript, extracted variables, and customer data

Updated 30 June 2026

The Conversation Ended Webhook is automatically sent to your specified webhook URL after a chat conversation (WhatsApp or Web Widget) ends. This webhook contains the full transcript, extracted variables, customer information, and sender details.

Webhook Configuration

To enable conversation ended webhooks:

  1. Use the Enable Conversation Ended Webhook API endpoint
  2. Provide your webhook URL where notifications will be sent
  3. Optionally configure post-call variables on your assistant to extract structured data from conversations

Request Format

The webhook is sent as a POST request to your configured URL with the following JSON payload:

Payload Structure

idinteger

Numeric identifier of the conversation (the same id shown in the dashboard conversation URL). Use conversation_id (UUID) when calling the API.

conversation_idstring

Unique identifier (UUID) of the conversation

assistant_idstring

Unique identifier (UUID) of the assistant that handled the conversation

typestring

The type of conversation. Possible values: widget, whatsapp

message_countinteger

Total number of messages exchanged in the conversation

statusstring

Status of the conversation. Value: ended

extracted_variablesobject

Variables extracted by AI based on your assistant's post-call schema configuration

statusboolean

  Whether the conversation objective was achieved

summarystring

  Conversation summary

custom_variablestring|number|boolean

  Any custom variables you defined in the assistant configuration

input_variablesobject

Variables that were passed to the assistant at the start of the conversation (e.g., from pre-chat form fields or automation flows)

transcriptarray

Array of message objects representing the full conversation, ordered oldest to newest

rolestring

  The sender role: `user`, `assistant`, or `system` (system messages mark events such as a human agent taking over the chat)

contentstring

  The message text. For media messages this is the caption or a short placeholder (e.g. `[Image]`); audio notes contain the transcribed text

timestampstring

  ISO 8601 timestamp of the individual message, in the user's configured timezone. Lets you order messages and see how long a conversation spanned (useful for chats that run over several days)

timestamp_unixinteger

  Unix timestamp (seconds since epoch) of the individual message. Convenient for arithmetic — e.g. computing the gap between two messages without parsing the ISO string

formatted_transcriptstring

Human-readable formatted transcript with AI: and Customer: prefixes

attachmentsarray

Media files (images, videos, documents) shared during the conversation. Each entry includes a direct URL you can pass to external services (for example, image or video analysis). This is an empty array when no media was shared — media is typically present on WhatsApp conversations.

typestring

  The media category. Possible values: `image`, `video`, `audio`, `document`

urlstring

  Direct URL to download the media file

filenamestring

  Original file name of the media

customer_phonestring

Customer phone number (available for WhatsApp conversations, null for widget conversations)

customer_namestring

Customer name if provided (e.g., from pre-chat form), or null

senderobject

WhatsApp sender information (only present for WhatsApp conversations, null for widget)

phone_numberstring

  The WhatsApp sender phone number

display_namestring

  The WhatsApp sender display name

created_atstring

ISO 8601 timestamp when the conversation started (in the user's configured timezone)

ended_atstring

ISO 8601 timestamp when the conversation ended (in the user's configured timezone)

{
  "id": 8842,
  "conversation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "assistant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "type": "widget",
  "message_count": 8,
  "status": "ended",
  "extracted_variables": {
    "status": true,
    "summary": "Customer asked about pricing plans and was interested in the Pro plan"
  },
  "input_variables": {
    "name": "John Doe",
    "email": "john@example.com"
  },
  "transcript": [
    {
      "role": "assistant",
      "content": "Hi! How can I help you today?",
      "timestamp": "2026-02-23T09:30:00+01:00",
      "timestamp_unix": 1771835400
    },
    {
      "role": "user",
      "content": "I have a question about your service.",
      "timestamp": "2026-02-23T09:31:12+01:00",
      "timestamp_unix": 1771835472
    },
    {
      "role": "assistant",
      "content": "Of course! I'd be happy to help. What would you like to know?",
      "timestamp": "2026-02-23T09:31:15+01:00",
      "timestamp_unix": 1771835475
    },
    {
      "role": "user",
      "content": "What are your pricing plans?",
      "timestamp": "2026-02-23T09:58:40+01:00",
      "timestamp_unix": 1771837120
    }
  ],
  "formatted_transcript": "AI: Hi! How can I help you today?\nCustomer: I have a question about your service.\nAI: Of course! I'd be happy to help. What would you like to know?\nCustomer: What are your pricing plans?",
  "attachments": [],
  "customer_phone": null,
  "customer_name": "John Doe",
  "sender": null,
  "created_at": "2026-02-23T09:30:00+01:00",
  "ended_at": "2026-02-23T10:00:00+01:00"
}
{
  "id": 8843,
  "conversation_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "assistant_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "type": "whatsapp",
  "message_count": 12,
  "status": "ended",
  "extracted_variables": {
    "status": true,
    "summary": "Customer scheduled an appointment for next week"
  },
  "input_variables": {},
  "transcript": [
    {
      "role": "user",
      "content": "Hello, I'd like to book an appointment",
      "timestamp": "2026-02-23T14:00:05+01:00",
      "timestamp_unix": 1771851605
    },
    {
      "role": "assistant",
      "content": "Hi! I'd be happy to help you book an appointment. What date works best for you?",
      "timestamp": "2026-02-23T14:00:08+01:00",
      "timestamp_unix": 1771851608
    }
  ],
  "formatted_transcript": "Customer: Hello, I'd like to book an appointment\nAI: Hi! I'd be happy to help you book an appointment. What date works best for you?",
  "attachments": [
    {
      "type": "image",
      "url": "https://example.com/media/public/20032/product-photo.jpg",
      "filename": "product-photo.jpg"
    },
    {
      "type": "document",
      "url": "https://example.com/media/public/20031/order-receipt.pdf",
      "filename": "order-receipt.pdf"
    }
  ],
  "customer_phone": "+1234567890",
  "customer_name": null,
  "sender": {
    "phone_number": "+19876543210",
    "display_name": "My Business"
  },
  "created_at": "2026-02-23T14:00:00+01:00",
  "ended_at": "2026-02-23T14:25:00+01:00"
}

Retry Behavior

If your webhook endpoint returns a non-2xx status code or the request fails, the system will retry:

Attempt Delay
1st retry 30 seconds
2nd retry 60 seconds
3rd retry 120 seconds

After 3 failed attempts, the webhook delivery is marked as failed and no further retries are attempted.

Important Notes

  • The conversation_id and assistant_id are UUIDs, not integer IDs
  • The sender field is only populated for WhatsApp conversations — it will be null for web widget conversations
  • The customer_phone is only available for WhatsApp conversations
  • The customer_name comes from pre-chat form data or conversation context
  • Timestamps use the user's configured timezone (ISO 8601 format)
  • The extracted_variables are populated from your assistant's post-call schema evaluation
  • The input_variables contain data from pre-chat forms (web widget) or automation flows
  • The attachments array lists media (images, videos, documents) shared during the conversation, each with a downloadable url — useful for forwarding to external analysis tools. It is an empty array when no media was shared (most common on web widget conversations)

Related guides