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

# Webhooks

> Implement webhook consumers with correct contract boundaries, retry behavior, and idempotent processing.

# Separate inbound and outbound webhook flows clearly.

Callaro integrations can involve two webhook directions:

* **Webhooks sent by Callaro** to your systems (for example post-call notifications).
* **Webhooks received by Callaro** from providers/integrations (for example billing or telephony callbacks).

This page documents consumer guidance for webhooks sent by Callaro and links receiver-side endpoints separately.

## Webhooks sent by Callaro (to your endpoint)

### Event families in active use

* `call.completed` (post-call operational payload)
* campaign lifecycle events where configured per tenant integration policy
* compliance and number-health events where enabled

### Canonical `call.completed` payload shape

```json theme={null}
{
  "event": "call.completed",
  "call_id": "vs_12345",
  "voice_session_id": 9001,
  "call_sid": "CA123...",
  "tenant_id": 44,
  "agent_id": 42,
  "direction": "outbound",
  "from_e164": "+14155550100",
  "to_e164": "+919900000001",
  "extracted_data": {},
  "runtime_vars": {},
  "tool_calls": []
}
```

## Delivery contract (current public status)

<Warning>
  The current public webhook contract does not guarantee a signature header. Do not build hard dependency on `X-Callaro-Signature` unless your tenant has a separately documented private contract.
</Warning>

* Delivery model: at least once
* Dedupe key: `call_id` (and optionally `voice_session_id`)
* Ordering: not guaranteed across calls
* Success response expected: any 2xx status
* Retry behavior: automatic retries for transient failures/non-2xx

### Receiver implementation template

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://your-app.example.com/callaro/webhooks" \
    -H "Content-Type: application/json" \
    -d @payload.json
  ```

  ```javascript Node.js theme={null}
  import express from 'express';

  const app = express();
  app.use(express.json({ limit: '2mb' }));

  app.post('/callaro/webhooks', async (req, res) => {
    const event = req.body;
    const dedupeKey = `${event.call_id}:${event.event}`;

    // Persist before side effects to make retries safe.
    const alreadyProcessed = await hasProcessed(dedupeKey);
    if (alreadyProcessed) return res.status(200).json({ ok: true, duplicate: true });

    await storeRawWebhook(event);
    await processWebhook(event);
    await markProcessed(dedupeKey);

    return res.status(200).json({ ok: true });
  });

  function hasProcessed(_dedupeKey) {
    return Promise.resolve(false);
  }
  function storeRawWebhook(_event) {
    return Promise.resolve();
  }
  function processWebhook(_event) {
    return Promise.resolve();
  }
  function markProcessed(_dedupeKey) {
    return Promise.resolve();
  }
  ```
</CodeGroup>

## Webhooks received by Callaro (from external systems)

These are callback endpoints on Callaro that providers/integrations call. Typical examples include:

* telephony provider callbacks
* billing/payment status callbacks
* integration-specific event relays

Common telephony ingress endpoints:

* `POST /api/v1/webhooks/telephony/{vendor_slug}`
* `POST /api/v1/webhooks/telephony/{vendor_slug}/sample`

Treat these as separate contracts from outbound webhooks to your app. Their auth and payload verification rules are endpoint-specific and documented on those endpoint pages.

## Reliability checklist

<Steps>
  <Step title="Persist raw payloads with receipt timestamp">
    Keep an audit log to support replay and incident analysis.
  </Step>

  <Step title="Deduplicate before side effects">
    Upsert by `call_id` and event type to prevent duplicate CRM writes.
  </Step>

  <Step title="Make downstream writes idempotent">
    Use external IDs and conditional updates in CRM/warehouse sinks.
  </Step>

  <Step title="Set explicit processing SLOs">
    Alert on backlog growth, non-2xx response rates, and replay volume.
  </Step>
</Steps>
