> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.anthropod.in/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.anthropod.in/_mcp/server.

# Webhooks

> Configure real-time result pushes from the dashboard.

Configure webhooks in **Dashboard → Developer Hub → Configuration** to receive analytics and Voice Agent results at your backend. Anthropod sends an HTTP `POST` with JSON to your callback URL and includes the custom headers you configure.

Webhooks deliver results after processing.

## Choose a callback

| Product                        | Dashboard section           | What is pushed                                                      |
| ------------------------------ | --------------------------- | ------------------------------------------------------------------- |
| Conversation Analytics — calls | Call Analytics Callback URL | Call batch processing results, including analysis and record errors |
| Conversation Analytics — chats | Chat Analytics Callback URL | Chat batch processing results, including analysis and record errors |
| Voice Agents                   | Voice Agents Callback URL   | Post-call conversation results and available analytics              |

Each callback uses the payload format documented below.

## Set up in the dashboard

#### Open Configuration

Sign in with an account that can manage Developer Hub configuration, then open the callback section for calls, chats, or Voice Agents.

#### Enter your receiver URL

Set the URL to an HTTPS endpoint on your backend, such as <code>[https://api.example.com/webhooks/anthropod](https://api.example.com/webhooks/anthropod)</code>.

#### Configure authentication

Set the Header field to a secret your receiver checks. For example, `Authorization: Bearer YOUR_WEBHOOK_SECRET`. Separate multiple headers with a semicolon.

#### Save the configuration

Click Save Changes for the callback section. Confirm the services or agents covered by the configuration; contact support if you need help with routing.

| Setting          | What to provide                                                                                                |
| ---------------- | -------------------------------------------------------------------------------------------------------------- |
| Callback type    | Call Analytics, Chat Analytics, or Voice Agents                                                                |
| URL              | Your HTTPS endpoint that accepts JSON POST requests                                                            |
| Header           | Authentication headers expected by your receiver, for example `Authorization: Bearer YOUR_WEBHOOK_SECRET`      |
| Multiple headers | Semicolon-separated entries, for example `Authorization: Bearer YOUR_WEBHOOK_SECRET; X-Integration: anthropod` |

Use a dedicated webhook secret, separate from the private API key used to call Anthropod. Validate it on every incoming request and keep it in your backend's secret store. Callbacks use your configured headers for authentication; HMAC signatures are not provided.

## HTTP input and output

| Direction                 | Contract                                                                                                                                       |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Input to your receiver    | HTTP `POST` to your configured URL, `Content-Type: application/json`, your configured authentication headers, and one of the JSON bodies below |
| Output from your receiver | Any HTTP `2xx` acknowledges delivery; return `204 No Content` with an empty body, or `200` after durable receipt                               |
| Receiver failure          | Authentication failure, a non-`2xx` response, or a timeout is not a successful acknowledgement. Automatic retries are not guaranteed.          |

Example request headers:

```http
POST /webhooks/anthropod HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer YOUR_WEBHOOK_SECRET
```

Example acknowledgement from your server, with no response body:

```http
HTTP/1.1 204 No Content
```

No particular JSON response fields are required from your receiver. Authenticate, durably accept the payload, and then acknowledge.

## What your receiver gets

### Conversation Analytics

Call and chat batch callbacks use the following top-level fields:

| Field                    | Type             | Presence | Meaning                                                                                             |
| ------------------------ | ---------------- | -------- | --------------------------------------------------------------------------------------------------- |
| `processing_id`          | string           | Required | Correlates the result to the original batch acknowledgement                                         |
| `status`                 | string           | Required | `completed` means the batch processing stage has finished; individual records can still have failed |
| `timestamp`              | integer          | Required | Result timestamp in Unix epoch seconds                                                              |
| `request_status`         | object           | Required | Processing counts                                                                                   |
| `request_status.total`   | integer          | Required | Number of records counted by the processing stage                                                   |
| `request_status.success` | integer          | Required | Number of records processed successfully                                                            |
| `request_status.failed`  | integer          | Required | Number of failed records                                                                            |
| `processed_data`         | array of objects | Required | Individual processing results; do not assume every input record has a successful result object      |

#### Per-record fields

The result shape depends on the stage reached. A failure can contain only identifiers and an error. On completed analysis, module-specific values are included when available.

| Field in each result            | Type                         | Presence and meaning                                                                       |
| ------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------ |
| `id`                            | string                       | Source call or chat identifier, when available                                             |
| `anthro_id`                     | string                       | Processing reference, when available                                                       |
| `api_version`                   | string                       | `v2` on the normal result branch                                                           |
| `timestamp`                     | integer                      | Result time in epoch seconds on the normal result branch                                   |
| `request_data`                  | object                       | Original record context when available; customer correlation is `request_data.customer_id` |
| `audio_to_text.transcript`      | string                       | Call transcript when transcription succeeds                                                |
| `chat_transcription.transcript` | string                       | Chat transcript when processing succeeds                                                   |
| `conversation_type`             | string or null               | Classification when available; for example `Proper Conversation` or `Not Connected`        |
| `meta_analytics`                | object                       | Available call or chat metrics; nested fields differ by channel                            |
| `conversation_analytics`        | object                       | Enabled analysis modules; each module can include `version` and `analytics`                |
| `customer_analytics`            | object or null               | Current customer analysis when this stage has run                                          |
| `error`                         | string                       | Failure reason on an unsuccessful record; success-only fields can be absent                |
| `error_type`, `http_status`     | string, integer respectively | Optional error details from the stage that failed                                          |

Responses can include additional custom fields. Treat unknown fields as extensions and tolerate documented absent or null values.

The following examples show the core integration fields for a service with the summary module enabled. Additional request context, usage, timeline, and configured analytics fields can be present. In the legacy chat result, summary field names still use the `call_summary` prefix.

#### Example: successful call analytics callback

```json
{
  "request_status": {
    "total": 1,
    "failed": 0,
    "success": 1
  },
  "status": "completed",
  "timestamp": 1788307200,
  "processing_id": "processing_call_demo_001",
  "processed_data": [
    {
      "api_version": "v2",
      "id": "call_demo_001",
      "anthro_id": "anthro_demo_001",
      "timestamp": 1788307200,
      "request_data": {
        "id": "call_demo_001",
        "customer_id": "customer_demo_001",
        "employee_id": "employee_demo_001",
        "call_time": 1788220800,
        "call_record_link": "https://recordings.example/call_demo_001.mp3",
        "call_answer_status": "Connected",
        "call_direction": "Outbound"
      },
      "conversation_type": "Proper Conversation",
      "audio_to_text": {
        "transcript": "Customer: Please arrange a callback."
      },
      "conversation_analytics": {
        "conversation_summary": {
          "version": 1,
          "analytics": {
            "call_summary_with_source": [
              {
                "title": "Conversation Summary",
                "text": "The customer requested a callback.",
                "sources": []
              }
            ],
            "call_summary_short_with_source": [
              {
                "text": "Callback requested.",
                "sources": []
              }
            ],
            "call_summary": "The customer requested a callback.",
            "call_summary_short": "Callback requested."
          }
        }
      },
      "customer_analytics": null
    }
  ]
}
```

#### Example: successful chat analytics callback

```json
{
  "request_status": {
    "total": 1,
    "failed": 0,
    "success": 1
  },
  "status": "completed",
  "timestamp": 1788307200,
  "processing_id": "processing_chat_demo_001",
  "processed_data": [
    {
      "api_version": "v2",
      "id": "chat_demo_001",
      "anthro_id": "anthro_demo_001",
      "timestamp": 1788307200,
      "request_data": {
        "id": "chat_demo_001",
        "customer_id": "customer_demo_001",
        "employee_id": "employee_demo_001",
        "conversation_time": 1788220800,
        "reopened": 0
      },
      "conversation_type": "Proper Conversation",
      "chat_transcription": {
        "transcript": "Customer: Please arrange a callback."
      },
      "conversation_analytics": {
        "conversation_summary": {
          "version": 1,
          "analytics": {
            "call_summary_with_source": [
              {
                "title": "Conversation Summary",
                "text": "The customer requested a callback.",
                "sources": []
              }
            ],
            "call_summary_short_with_source": [
              {
                "text": "Callback requested.",
                "sources": []
              }
            ],
            "call_summary": "The customer requested a callback.",
            "call_summary_short": "Callback requested."
          }
        }
      },
      "customer_analytics": null
    }
  ]
}
```

#### Example: completed batch containing a failed record

```json
{
  "request_status": {
    "total": 1,
    "failed": 1,
    "success": 0
  },
  "status": "completed",
  "timestamp": 1788307200,
  "processing_id": "processing_demo_001",
  "processed_data": [
    {
      "id": "call_demo_001",
      "anthro_id": "anthro_demo_001",
      "error": "Failed to Transcribe",
      "error_type": "Processing Error"
    }
  ]
}
```

The same envelope is used for chat batches. The batch is complete even though this example's one record failed. Successful records carry the applicable transcript and enabled analysis fields from the table above; those nested module schemas follow the service configuration.

Inspect each result for success or failure and use its source record and customer identifiers for correlation. A successful batch submission is an acknowledgement, not the final analysis result. See [batch analytics](/create-analysis).

### Voice Agents

The Voice Agent callback sends the post-call result object directly. Available fields depend on the agent configuration and outcome, including conversation and customer identifiers, call outcome, analytics, and recording information when available. It does not use the Conversation Analytics batch wrapper above. See [outbound call results](/outbound-calls#results-and-callbacks).

#### Core Voice Agent fields

The normal post-call result uses the fields below. Minimal or failed-call results can omit enrichment fields; accept `null` where marked and do not infer that a call was answered from `status: completed` alone.

| Field                                                  | Type             | Presence and meaning                                                                                  |
| ------------------------------------------------------ | ---------------- | ----------------------------------------------------------------------------------------------------- |
| `api_version`                                          | string           | `v2` on the normal result branch                                                                      |
| `client_id`, `agent_id`, `conversation_id`             | string           | Account, agent, and conversation identifiers on the normal result branch                              |
| `customer_id`                                          | string           | Present when customer context is available                                                            |
| `status`                                               | string           | Post-processing outcome; normal branches use `completed` or `error`                                   |
| `conversation_type`                                    | string or null   | Call classification; use this with the outcome details to distinguish connected and unconnected calls |
| `conversation_time`                                    | integer or null  | Conversation start time in epoch seconds, when available                                              |
| `phone_number`, `agent_phone_number`                   | string           | Numbers when provided by the calling context                                                          |
| `transcript`                                           | string           | Formatted transcript when available; can be empty                                                     |
| `tool_calls`                                           | array of objects | Tool execution records when available; object fields depend on the tool                               |
| `request_data`                                         | object           | Request context when supplied                                                                         |
| `meta_analytics`                                       | object           | Available call metrics and recording reference                                                        |
| `meta_analytics.duration`                              | number           | Duration in seconds, when available                                                                   |
| `meta_analytics.start_time`, `meta_analytics.end_time` | integer          | Epoch seconds, when available                                                                         |
| `meta_analytics.recording_url`                         | string or null   | Available recording URL, otherwise null; treat it as opaque                                           |
| `inbuilt_analytics`                                    | object           | Configured analytics modules, including summary or business insights when available                   |
| `inbuilt_analytics.<module>.version`                   | integer          | Module configuration version; `-1` can indicate skipped or unavailable analysis                       |
| `inbuilt_analytics.<module>.analytics`                 | object           | Module results; nested keys depend on the agent configuration                                         |
| `telephony_provider_call_id`                           | string or null   | Provider correlation identifier when available                                                        |
| `call_transfer_details`                                | object           | Transfer information when present                                                                     |
| `call_transfer_details.call_transfer_status`           | string or null   | Recorded transfer status when available                                                               |
| `call_transfer_details.call_transfer_details`          | object           | Provider-specific transfer details, or an empty object                                                |

Conversation text is returned in `transcript`. There is no shared `event_id`, `event_type`, or `data` wrapper in the documented legacy body.

#### Example: Voice Agent post-call result

Example response. Additional fields depend on your agent configuration.

```json
{
  "api_version": "v2",
  "client_id": "client_demo_001",
  "agent_id": "agent_demo_001",
  "conversation_id": "voice_demo_001",
  "customer_id": "customer_demo_001",
  "status": "completed",
  "conversation_type": "Proper Conversation",
  "conversation_time": 1788220800,
  "phone_number": "+12025550123",
  "agent_phone_number": "+12025550124",
  "transcript": "User: Please arrange a callback.",
  "tool_calls": [],
  "meta_analytics": {
    "duration": 42,
    "start_time": 1788220800,
    "end_time": 1788220842,
    "recording_url": null
  },
  "inbuilt_analytics": {
    "conversation_summary": {
      "version": 1,
      "analytics": {
        "call_summary_with_source": [
          {
            "title": "Conversation Summary",
            "text": "The customer requested a callback.",
            "sources": []
          }
        ],
        "call_summary_short_with_source": [
          {
            "text": "Callback requested.",
            "sources": []
          }
        ]
      }
    },
    "business_insights": {
      "version": 1,
      "analytics": {}
    }
  },
  "telephony_provider_call_id": null,
  "call_transfer_details": {
    "call_transfer_status": null,
    "call_transfer_details": {}
  }
}
```

## Receive reliably

| Receiver behavior        | Guidance                                                                                                                                                                                      |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Acknowledge promptly     | Authenticate and durably store or enqueue the JSON, then return `200` or `204`. Process CRM updates and other slow work asynchronously.                                                       |
| Handle repeated delivery | Make processing idempotent using the callback type, available record identifiers, and payload or result version. Allow a later revised result for the same conversation to update the record. |
| Handle ordering          | Do not depend on exactly-once delivery or delivery order. Record when a result was received and reconcile revisions.                                                                          |
| Handle failed delivery   | Contact support with the processing or conversation ID if a delivery is missing.                                                                                                              |
| Handle load              | Webhook pushes are separate from your API-key request allowance. Size your receiver for bursts, including results from a completed batch.                                                     |

[Contact support](/contact-support) for callback routing, example payloads, and delivery troubleshooting. Never share your API key or webhook secret in a support request.