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

# Post call webhook

> After each analyzed call, OSVI sends the post-call analysis results to every webhook integration configured on the agent (Agent → Post-Call Analysis → Integrations). The HTTP method, custom headers, and request body are all configurable per integration. The schema below describes the default **Auto** body mode with every data section enabled — each section can be toggled off individually, or replaced entirely with a **Custom Template** body. A section that is enabled but has no data for the call is omitted from the payload.

After every analyzed call, OSVI can send the post-call analysis results to any HTTP endpoint you control. Webhooks are configured per agent in the dashboard under **Agent → Post-Call Analysis → Integrations**, and an agent can have multiple webhook integrations — each one fires independently after each analyzed call.

<Note>
  Post-call webhooks fire only for calls that were answered and produced a transcript (`call_status: picked`), and only when Post-Call Analysis is enabled on the agent.
</Note>

## Configuring a webhook

Each integration lets you configure:

| Setting          | Description                                                                                                                                                                                  |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Name**         | A label for the integration, shown in the dashboard and Integration Logs.                                                                                                                    |
| **HTTP method**  | `POST` (default), `PUT`, `PATCH`, `GET`, or `DELETE`. For `GET` and `DELETE` the request is sent without a body.                                                                             |
| **URL**          | The endpoint to call. Supports `{{placeholder}}` values resolved from the call trigger data — e.g. `https://api.example.com/leads/{{crm_id}}/calls`. Unresolved placeholders are left as-is. |
| **Request body** | `Auto` (toggle data sections on/off) or `Custom Template` (write your own JSON body).                                                                                                        |
| **Headers**      | Custom request headers, e.g. an `Authorization` token for your endpoint. `Content-Type: application/json` is always set.                                                                     |
| **Active**       | Enable or disable the integration without deleting it.                                                                                                                                       |

## Request body modes

### Auto mode

In Auto mode you choose which data sections to include. Each enabled section contributes its fields to a flat JSON body; sections with no data for a given call are omitted.

| Section               | Fields                                                                                                                                                                  |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Call Info**         | `call_log_id`, `phone_number`, `agent_name`, `call_status`, `call_type`                                                                                                 |
| **AI Summary**        | `call_summary` — natural-language summary generated from the transcript                                                                                                 |
| **Data Extraction**   | `data_capture` — values for the fields defined in the agent's Data Extraction tab                                                                                       |
| **Structured Output** | `structured_output` — custom JSON from your Output Schema (simple or conditional)                                                                                       |
| **Call Trigger Data** | `call_trigger_data` — data from the source that triggered the call: the original API request body for API-triggered calls, or the row metadata for campaign (CSV) calls |

### Custom Template mode

In Custom Template mode you write the JSON body yourself, using `{{expression}}` placeholders that are resolved against the call's data at delivery time:

```json theme={null}
{
  "customer_name": "{{data_capture.name}}",
  "intent": "{{structured_output.intent}}",
  "slot_date": "{{structured_output.appointment.date}}",
  "phone": "{{call_info.phone_number}}",
  "all_output": "{{structured_output}}",
  "summary": "{{call_summary}}",
  "source": "osvi"
}
```

Available expression sources:

| Source              | Fields                                                                  | Example                                  |
| ------------------- | ----------------------------------------------------------------------- | ---------------------------------------- |
| `call_info`         | `call_log_id`, `phone_number`, `agent_name`, `call_status`, `call_type` | `{{call_info.phone_number}}`             |
| `call_summary`      | The full AI-generated summary text                                      | `{{call_summary}}`                       |
| `data_capture`      | Any label defined in the Data Extraction tab                            | `{{data_capture.email}}`                 |
| `structured_output` | Any key from your Output Schema; nested paths supported                 | `{{structured_output.appointment.date}}` |
| `call_trigger_data` | Any key from the original trigger payload; nested paths supported       | `{{call_trigger_data.meta.campaign_id}}` |

When a value is *only* an expression (e.g. `"{{structured_output}}"`), the raw type is preserved — objects stay objects, numbers stay numbers. When an expression is embedded in a longer string, it is interpolated as text. Expressions that don't resolve become `null`.

## Delivery, logging, and retries

* Your endpoint should respond with any **2xx** status within 15 seconds to acknowledge receipt.
* Every delivery attempt — including the request payload, response status, and response body — is recorded in **Integration Logs** on the agent's Post-Call Analysis tab.
* Failed deliveries (non-2xx responses, timeouts, connection errors) are not retried automatically, but can be retried manually from the Integration Logs view, individually or in bulk.
* Use the **Test** button on an integration to send a sample payload and verify your endpoint before going live.


## OpenAPI

````yaml WEBHOOK /webhook
openapi: 3.1.0
info:
  title: OSVI AI API
  description: REST API for the OSVI AI voice and chat platform
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://api.osvi.ai
security:
  - ApiToken: []
paths: {}
components:
  securitySchemes:
    ApiToken:
      type: apiKey
      in: header
      name: API-Token
      description: >-
        16-character API token associated with your OSVI account. Find it in
        your dashboard under Settings → API.

````