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

# Webhooks

> Receive a server-to-server notification with the full call result when an in-app agent call ends.

## Overview

When an in-app agent call finishes, RevRag can send a **`call.ended`** webhook — a `POST` request to an HTTPS endpoint on your server — containing the complete result of that call: status, duration, summary, transcript, recording URL, and your `app_user_id`.

The [payload](#payload) below shows exactly what your server receives when an in-app call ends.

<Note>
  Webhooks are **server-to-server**. They are delivered to your backend, not to the SDK running in your app. The in-app SDK's own [agent lifecycle events](#in-app-events-vs-webhooks) (e.g. `agent_start` / `agent_end`) are a separate, in-process mechanism — they are not the same as this webhook.
</Note>

## Enabling webhooks

Webhooks are **opt-in** and configured per agent. They are not enabled by default.

To turn them on for your in-app agent, contact **[contact@revrag.ai](mailto:contact@revrag.ai)** with:

* **Webhook URL** — the HTTPS endpoint that will receive the `POST` (HTTP is not supported).
* **Signing secret** — a shared secret used to verify each request (see [Security & headers](#security--headers)).

## Security & headers

In-app webhooks use the **same** signing scheme as every RevRag webhook — HMAC-SHA256 computed over `"{timestamp}.{raw_body}"` with your shared secret. Each request carries:

| Header                | Purpose                                       |
| --------------------- | --------------------------------------------- |
| `X-Webhook-Event`     | Event type (`call.ended`)                     |
| `X-Webhook-Timestamp` | Unix timestamp (seconds) the webhook was sent |
| `X-Webhook-Signature` | `t=<timestamp>,v1=<hmac_sha256_hex>`          |
| `X-Webhook-ID`        | Unique id for deduplication                   |

<Warning>
  Always verify the signature before trusting a payload. See [Webhook Security](/api-reference/webhook-security) for the full verification steps and ready-to-use Python / Node.js examples.
</Warning>

## Payload

The webhook body is the same JSON shape as the [Get Call Status](/api-reference/campaigns-api#get-call-status) response. For an in-app call it carries your **`app_user_id`** as a top-level correlation field.

```json theme={null}
{
  "call_status": "ENDED",
  "call_id": "123e4567-e89b-12d3-a456-426614174000",
  "agent_id": "33333333-3333-3333-3333-333333333333",
  "summary": "User asked about their loan eligibility and was guided to the application.",
  "start_time": "2026-05-27T03:05:00+00:00",
  "end_time": "2026-05-27T03:06:12+00:00",
  "duration": 72,
  "disconnection_reason": "user_hangup",
  "recording_url": "https://.../recording.mp3",
  "transcription": {
    "messages": [
      { "role": "assistant", "content": "Hi! How can I help you today?" },
      { "role": "user", "content": "What documents do I need for a loan?" }
    ]
  },
  "custom_variables": [
    { "key": "interested_in_loan", "type": "boolean", "value": true }
  ],
  "variables_fields": { "plan": "gold" },
  "app_user_id": "user_12345"
}
```

### Payload parameters

| Field                     | Type           | Description                                                                   |
| ------------------------- | -------------- | ----------------------------------------------------------------------------- |
| `call_status`             | string         | Final call status — `ENDED` once the call has finished                        |
| `call_id`                 | string (uuid)  | The call this notification is for                                             |
| `agent_id`                | string (uuid)  | The in-app agent that handled the call                                        |
| `summary`                 | string         | LLM-generated call summary (when a transcript exists)                         |
| `start_time` / `end_time` | string \| null | ISO-8601 timestamps                                                           |
| `duration`                | number         | Call duration in seconds                                                      |
| `disconnection_reason`    | string \| null | Normalized hangup reason                                                      |
| `recording_url`           | string \| null | Presigned recording URL (for transcribed calls)                               |
| `transcription`           | object \| null | Turn-by-turn `messages` (`role`, `content`)                                   |
| `custom_variables`        | array          | Post-call variables extracted by the agent (`key`, `type`, `value`)           |
| `variables_fields`        | object \| null | Variables associated with the call                                            |
| `app_user_id`             | string \| null | Your user id, echoed back top-level — see [Correlation IDs](#correlation-ids) |

## Correlation IDs

To tie a webhook back to the right user in your own system, use **`app_user_id`** together with **`call_id`**.

The `app_user_id` you pass when requesting an in-app call token is echoed back top-level in every webhook, so you can attribute the call to the exact user who initiated it.

## In-app events vs webhooks

Don't confuse these two mechanisms:

|             | In-app SDK events                                     | Webhooks (this page)                                       |
| ----------- | ----------------------------------------------------- | ---------------------------------------------------------- |
| **Where**   | In your app process (browser / mobile)                | Server-to-server, to your backend                          |
| **When**    | Live, during the call (`agent_start`, `agent_end`, …) | After the call ends (`call.ended`)                         |
| **Use for** | Driving UI, real-time state                           | Persisting the call result, transcript, summary, analytics |

For the in-process events, see your platform's integration guide.

## Related

<CardGroup cols={2}>
  <Card title="Webhook Security" icon="shield-halved" href="/api-reference/webhook-security">
    Full HMAC-SHA256 verification steps with Python and Node.js examples.
  </Card>

  <Card title="Campaigns Webhooks" icon="paper-plane" href="/api-reference/campaigns-api#webhook-notifications">
    The same payload contract as documented for campaign calls.
  </Card>
</CardGroup>
