> ## Documentation Index
> Fetch the complete documentation index at: https://docs.autocalls.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Conversation Ended Webhook

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

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-reference/assistants/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

<ResponseField name="id" type="integer">
  Numeric identifier of the conversation (the same id shown in the dashboard conversation URL). Use `conversation_id` (UUID) when calling the API.
</ResponseField>

<ResponseField name="conversation_id" type="string">
  Unique identifier (UUID) of the conversation
</ResponseField>

<ResponseField name="assistant_id" type="string">
  Unique identifier (UUID) of the assistant that handled the conversation
</ResponseField>

<ResponseField name="type" type="string">
  The type of conversation. Possible values: `widget`, `whatsapp`
</ResponseField>

<ResponseField name="message_count" type="integer">
  Total number of messages exchanged in the conversation
</ResponseField>

<ResponseField name="status" type="string">
  Status of the conversation. Value: `ended`
</ResponseField>

<ResponseField name="extracted_variables" type="object">
  Variables extracted by AI based on your assistant's post-call schema configuration

  <Expandable title="Example extracted variables">
    <ResponseField name="status" type="boolean">
      Whether the conversation objective was achieved
    </ResponseField>

    <ResponseField name="summary" type="string">
      Conversation summary
    </ResponseField>

    <ResponseField name="custom_variable" type="string|number|boolean">
      Any custom variables you defined in the assistant configuration
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="input_variables" type="object">
  Variables that were passed to the assistant at the start of the conversation (e.g., from pre-chat form fields or automation flows)
</ResponseField>

<ResponseField name="transcript" type="array">
  Array of message objects representing the full conversation, ordered oldest to newest

  <Expandable title="Message properties">
    <ResponseField name="role" type="string">
      The sender role: `user`, `assistant`, or `system` (system messages mark events such as a human agent taking over the chat)
    </ResponseField>

    <ResponseField name="content" type="string">
      The message text. For media messages this is the caption or a short placeholder (e.g. `[Image]`); audio notes contain the transcribed text
    </ResponseField>

    <ResponseField name="timestamp" type="string">
      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)
    </ResponseField>

    <ResponseField name="timestamp_unix" type="integer">
      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
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="formatted_transcript" type="string">
  Human-readable formatted transcript with `AI:` and `Customer:` prefixes
</ResponseField>

<ResponseField name="attachments" type="array">
  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.

  <Expandable title="Attachment properties">
    <ResponseField name="type" type="string">
      The media category. Possible values: `image`, `video`, `audio`, `document`
    </ResponseField>

    <ResponseField name="url" type="string">
      Direct URL to download the media file
    </ResponseField>

    <ResponseField name="filename" type="string">
      Original file name of the media
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="customer_phone" type="string">
  Customer phone number (available for WhatsApp conversations, `null` for widget conversations)
</ResponseField>

<ResponseField name="customer_name" type="string">
  Customer name if provided (e.g., from pre-chat form), or `null`
</ResponseField>

<ResponseField name="sender" type="object">
  WhatsApp sender information (only present for WhatsApp conversations, `null` for widget)

  <Expandable title="Sender properties">
    <ResponseField name="phone_number" type="string">
      The WhatsApp sender phone number
    </ResponseField>

    <ResponseField name="display_name" type="string">
      The WhatsApp sender display name
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp when the conversation started (in the user's configured timezone)
</ResponseField>

<ResponseField name="ended_at" type="string">
  ISO 8601 timestamp when the conversation ended (in the user's configured timezone)
</ResponseField>

<ResponseExample>
  ```json Conversation Ended Webhook Payload theme={null}
  {
    "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"
  }
  ```

  ```json WhatsApp Conversation Ended Webhook theme={null}
  {
    "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"
  }
  ```
</ResponseExample>

## 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)
