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

# Webhooks overview

> Get call, chat, and email results pushed to your systems in real time. Configure webhooks per agent or per account, choose events, and handle delivery.

A webhook is an HTTPS request Callers sends to your server when something happens in a conversation: a call connects, a contact hangs up, post-call analysis finishes, or a contact runs out of attempts. Use webhooks to update your CRM, alert your team, start follow-up workflows, or store transcripts, without polling the API.

<ol />

## Where to configure webhooks

| Scope | Where | Fires for |
| - | - | - |
| Agent | Agent → **Webhooks** in the settings sidebar, or the **Webhook** stage on the workflow canvas | That agent's conversations. |
| Agent (API) | `POST /agents/{agentId}/webhook/subscribe`, or `webhooks` in `POST`/`PUT`/`PATCH /agents` | That agent's conversations. |
| Account | **Settings** → **Subaccounts** → open a subaccount → **Webhooks**, or `webhooks` when creating a subaccount with the API | Every agent in that subaccount. |

An agent can have several webhooks, each with its own URL and events. Account-level webhooks are sent in addition to the agent's own webhooks.

### Account-level webhooks

Agencies often want one endpoint per client instead of configuring every agent. Add the webhook to the subaccount and it fires for all of its agents, including agents created later. See [Subaccounts and SIP](https://docs.callers.ai/api-reference/guides/subaccounts-and-sip.md#create-a-subaccount).

## Simple and advanced webhooks

Each webhook has a **Mode**: **Simple** or **Advanced**.

| | Simple | Advanced |
| - | - | - |
| Request | `POST` with the full payload as JSON | Your choice of method, URL, headers, query parameters, and body |
| Body | The complete [webhook payload](https://docs.callers.ai/documentation/webhook/webhook-payload.md) | A template you write, with values from the payload |
| Signature | `X-Signature`, RSA-SHA256, verified with the Callers public key | Custom webhooks created with **Create Custom Webhook** add `X-Signature` and `X-Signature-Type` (HMAC-SHA256 with your account secret by default) |
| Best for | Your own backend | Third-party APIs that expect a specific format, or sending only a few fields |

Simple webhooks need only an HTTPS URL. To set one up in an agent:

**1. Open the agent's webhooks**

Open the agent and select **Webhooks** in the settings sidebar (or the **Webhook** stage on the workflow canvas).

**2. Add a webhook**

Click **Add Webhook**, keep **Mode** on **Simple**, and enter your **Webhook Url**. It must start with `https://`.

**3. Choose events**

Under **Send the webhook for**, select the events you want. See [Choosing events](#choosing-events).

**4. Save and test**

Save the agent and place a test call. The delivery appears on the call in the dashboard.

For custom requests, see [Advanced webhooks](https://docs.callers.ai/documentation/webhook/advanced-webhook.md). App Center integrations (for example, a CRM or Slack action) can also run as webhooks on the same events; see [App Center](https://docs.callers.ai/documentation/integrations/app-center.md).

## Choosing events

Each webhook fires only for the events selected for it. Events cover the whole lifecycle:

* **Before and during the call:** `DIALING`, `CONNECTED`, `COULD_NOT_CONNECT:BUSY`, `COULD_NOT_CONNECT:NO_ANSWER`, `FAILED`, `HANG_UP`, `FORWARDED`, `FORWARDED_CALL_FINISHED`.
* **After the call:** `POST_PROCESSING_FINISHED:<outcome>` for each outcome and each custom success criterion, `CALL_FINISHED`, `CONTACT_UNREACHED`, `CONTACT_LAST_DAILY_ATTEMPT`.
* **Text and Email agents:** `POST_PROCESSING_FINISHED:<outcome>`, plus `CONTACT_UNREACHED` and `FAILED` for Text agents.

If you create a webhook through the API without `events`, it subscribes to the five main outcomes: `POST_PROCESSING_FINISHED:INTERESTED`, `NOT_INTERESTED`, `CALL_ME_LATER`, `WRONG_NUMBER`, and `DO_NOT_CALL`.

See [Webhook events](https://docs.callers.ai/documentation/webhook/webhook-events.md) for when each event fires and which to pick.

> [!TIP]
>
> Most integrations need just two: `CALL_FINISHED` for a complete record of every call (transcript, summary, recording), and one or more `POST_PROCESSING_FINISHED:*` events for the outcomes you act on.

## Create a webhook with the API

```bash cURL theme={"dark"}
curl -X POST "https://api.callers.ai/agents/$AGENT_ID/webhook/subscribe" \
  -H "Authorization: $CALLERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CRM sync",
    "url": "https://example.com/callers/webhook",
    "events": ["CALL_FINISHED", "POST_PROCESSING_FINISHED:INTERESTED"]
  }'
```

```javascript Node.js theme={"dark"}
await fetch(`https://api.callers.ai/agents/${agentId}/webhook/subscribe`, {
  method: "POST",
  headers: {
    Authorization: process.env.CALLERS_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "CRM sync",
    url: "https://example.com/callers/webhook",
    events: ["CALL_FINISHED", "POST_PROCESSING_FINISHED:INTERESTED"],
  }),
});
```

```python Python theme={"dark"}
requests.post(
    f"https://api.callers.ai/agents/{agent_id}/webhook/subscribe",
    headers={"Authorization": os.environ["CALLERS_API_KEY"]},
    json={
        "name": "CRM sync",
        "url": "https://example.com/callers/webhook",
        "events": ["CALL_FINISHED", "POST_PROCESSING_FINISHED:INTERESTED"],
    },
)
```

| Field | Description |
| - | - |
| `name` | Optional label, up to 30 characters. |
| `url` | Required. HTTPS URL. |
| `events` | Events to send. Defaults to the five main outcomes. |
| `isAdvanced` | `true` to send a custom request defined in `advancedWebhook`. |
| `advancedWebhook` | `url`, `method` (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`), `headers` and `parameters` (`[{ "name", "value" }]`), and `body` (a template string). See [Advanced webhooks](https://docs.callers.ai/documentation/webhook/advanced-webhook.md#advanced-webhooks-through-the-api). |

Subscribing a URL the agent already has merges the new events into the existing webhook. To replace or remove webhooks, send the full list with `PATCH /agents/{agentId}` (`"webhooks": []` removes all).

> [!NOTE]
>
> The API accepts the standard call events. `CONTACT_UNREACHED`, `CONTACT_LAST_DAILY_ATTEMPT`, and events for custom success criteria can be selected in the dashboard.

## Delivery and retries

* Respond with any `2xx` status to acknowledge a delivery. Anything else, or a timeout, counts as a failure.
* Failed call webhook deliveries are retried automatically, up to 5 attempts in total, with increasing delays starting at about 10 seconds.
* Deliveries for the same call are sent one at a time, in event order. Deliveries for different calls can arrive in parallel and out of order.
* The same event can occasionally be delivered more than once (for example, when your server processed a request but the response was lost). Make your handler idempotent: use the call `id` plus `webhookEvent` as a deduplication key.

> [!TIP]
>
> Acknowledge first, process later. Return `200` as soon as you've verified and stored the request, then do slow work (CRM updates, downstream API calls) in a background job. Slow responses risk timeouts and duplicate deliveries.

Custom webhooks created with **Create Custom Webhook** can also be set to stop retrying on some or all errors (for example, retry only on `5xx` responses).

## Logs

Every delivery attempt is logged on the call. Open the call from the agent's results or the contact's interactions to see each webhook that fired, the request that was sent, and your server's response status and body. Use this first when a webhook doesn't arrive.

## Testing

* **Test calls.** Calls you place with **Test Call** in the agent send webhooks like any other call, with `isTestCall: true` in the payload. Filter these out in production handlers.
* **Send Test Request.** In the advanced webhook editor, **Send Test Request** sends the configured request and shows the response.
* **Replay a payload.** `GET /agents/{agentId}/calls/{callId}/webhook-payload` returns the payload for any past call, which is handy for building and testing your handler.
* **Local development.** Expose your local server with a tunneling tool and use its HTTPS URL.

## Network and security

Callers sends webhooks from these IP addresses. If your endpoint is behind a firewall, allow both:

```text theme={"dark"}
35.245.204.86
35.221.61.75
```

The same addresses are used for HTTP actions your agents call during and after conversations.

To confirm a request really came from Callers, verify its signature. See [Validating webhook signatures](https://docs.callers.ai/documentation/webhook/validating-webhook-signatures.md). Webhook URLs must be public: requests to private or internal addresses are blocked.

## Troubleshooting

> [accordion] The webhook never arrives
>
> Check that the agent has the event selected, the URL is public HTTPS, and your firewall allows the IPs above. Then open the call's webhook log to see the response your server returned.

> [accordion] I get the same event twice
>
> A previous attempt failed or timed out from Callers' side and was retried. Deduplicate on `id` + `webhookEvent`, and respond faster.

> [accordion] POST\_PROCESSING\_FINISHED:INTERESTED never fires but calls succeed
>
> If your agent uses custom success criteria, subscribe to their events (`POST_PROCESSING_FINISHED:<criterion name>`), or use `CALL_FINISHED` and read `successCriteria` from the payload.

> [accordion] Signature verification fails
>
> Verify against the raw request body, before any JSON parsing or re-serialization, and use the right scheme for the webhook type. See [Validating webhook signatures](https://docs.callers.ai/documentation/webhook/validating-webhook-signatures.md#troubleshooting).

## Related

> [card] [Webhook events](https://docs.callers.ai/documentation/webhook/webhook-events.md)
>
> Every event and when it fires.

> [card] [Webhook payload](https://docs.callers.ai/documentation/webhook/webhook-payload.md)
>
> Every field Callers sends.

> [card] [Advanced webhooks](https://docs.callers.ai/documentation/webhook/advanced-webhook.md)
>
> Custom method, headers, and body.

> [card] [Validating signatures](https://docs.callers.ai/documentation/webhook/validating-webhook-signatures.md)
>
> Verify requests come from Callers.

> [card] [Troubleshooting](https://docs.callers.ai/documentation/resources/troubleshooting.md#webhooks-and-actions)
>
> Webhooks that never arrive, time out, or fail signature checks.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.