> For a complete page index, fetch https://docs.synthflow.ai/llms.txt. For full documentation content, fetch https://docs.synthflow.ai/llms-full.txt.

# Pass Call Context

> Pass caller and routing data into Synthflow on inbound SIP calls with custom X-headers, the X-EI header, or the Diversion header, and use it in prompts, custom actions, and transfers.

Your SBC, PBX, or carrier can attach data to an inbound call's SIP `INVITE`, and the agent can use it from the first turn. This lets the agent greet a caller by name, look up their account, or route them, without asking for details your system already has.

| Method                                | Use it when                                                                               |
| ------------------------------------- | ----------------------------------------------------------------------------------------- |
| [Custom X-headers](#custom-x-headers) | You want to send any data. Recommended for new integrations.                              |
| [X-EI header](#x-ei-header)           | Your integration already sends `X-EI`, or you need your call ID in the post-call webhook. |
| [Diversion header](#diversion-header) | The call was forwarded, and the agent needs the original destination or the reason.       |

To pull more data from your own API before the agent speaks, [use a before-the-call action](#before-the-call-actions).

## Custom X-headers

Add any `X-*` header to the `INVITE`. Synthflow turns each one into a variable with the same name, including the `X-` prefix.

```
INVITE sip:+12065551234@sip.us.synthflow.ai:32681 SIP/2.0
X-Customer-Name: Jane Doe
X-Account-ID: ACC-98765
X-Language: es
X-Priority: high
```

This `INVITE` creates four variables: `{X-Customer-Name}`, `{X-Account-ID}`, `{X-Language}`, and `{X-Priority}`. Values resolve before the agent's first turn.

### Header rules

| Rule  | Detail                                                                                                                 |
| ----- | ---------------------------------------------------------------------------------------------------------------------- |
| Name  | Starts with `X-`, then letters, digits, `-`, or `_` only. Pattern: `^X-[A-Za-z0-9\-_]+$`                               |
| Value | No carriage return (`\r`), line feed (`\n`), or null (`\0`) characters.                                                |
| Case  | Names are case-sensitive. If your SBC sends `x-customer-name`, reference `{x-customer-name}`, not `{X-Customer-Name}`. |

Send only the headers the agent needs. Every header adds to the size of the `INVITE`, and a large `INVITE` can fragment and fail on UDP trunks with a small MTU.

Headers travel in plain text unless your trunk uses TLS. If a header carries sensitive data, such as an account ID, turn on [secure signaling](/connect-over-sip#encryption) or encrypt the value before you send it.

## Header values

Reference a header as `{X-Header-Name}` anywhere Synthflow accepts variables. You can combine header values with [system variables](/system-variables#system-variables) such as `{call_id}` and `{from_phone_number}`, and with [action results](/system-variables#action-result-variables).

| Where                       | Example                                                |
| --------------------------- | ------------------------------------------------------ |
| Agent prompt                | `The caller's name is {X-Customer-Name}.`              |
| Before-the-call action body | `{"account_id": "{X-Account-ID}"}`                     |
| During-the-call action body | `{"priority": "{X-Priority}", "call_id": "{call_id}"}` |
| Transfer X-header value     | Header `X-Account-ID` with value `{X-Account-ID}`      |

In a prompt, the values give the agent context from the start of the call:

```
You are a support agent for Acme Corp.
The caller's name is {X-Customer-Name} and their account ID is {X-Account-ID}.
Their preferred language is {X-Language}.
If {X-Priority} is "high", escalate unresolved issues immediately.
```

To pass the same data to the next leg of a call, add the headers in the call transfer action under **Custom X-Headers**, with the incoming header as the value. You can also add fixed headers, such as `X-Handled-By` set to `synthflow-ai`. See [SIP transfers](/sip-transfers#custom-x-headers).

## X-EI header

`X-EI` is an older header that carries up to three values in a single header. Custom X-headers cover the same cases with less setup, but `X-EI` still works, and it is required to [hand off a live call](/route-sip-calls#live-call-handoff).

Each value starts with a one-letter prefix and a dot, and ends with a semicolon. Send any combination, in any order:

```
X-EI: S.abc123;E.crm456;O.+15551234567;
```

| Token        | Contains                                              | Placeholder in actions |
| ------------ | ----------------------------------------------------- | ---------------------- |
| `S.<value>;` | The Synthflow call ID                                 | `<call_id>`            |
| `E.<value>;` | Your own call ID from a PBX, CRM, or ticketing system | `<external_id>`        |
| `O.<value>;` | The original caller, or the diversion history         | `<diversion>`          |

Use the placeholders in before-the-call and during-the-call custom actions. The `E.` value also appears as `call.external_id` in the [post-call webhook](/webhooks), so you can match Synthflow calls to your own records.

This TwiML example passes an external ID alongside the Synthflow call ID:

![Twilio Dial SIP configuration passing an X-EI header with an external ID](https://storage.googleapis.com/granular-changelog/doc-images/x-ei-sip-header.png)

```python
voice.dial().sip(
    f"sip:{custom_number}@sip.us.synthflow.ai:32681?X-EI=S.{synthflow_call_id};E.someExternalID;"
)
```

When you send `X-EI`:

* Do not use semicolons inside a value. Each semicolon ends a token.
* Keep values short, especially on UDP trunks.
* URL-encode the header when you add it to the query string of a SIP URI, and encode it only once.
* Make sure your SBC forwards custom SIP headers end to end. Some strip them by default.

## Diversion header

When a call was forwarded before it reached Synthflow, its `Diversion` header records where it was going and why, for example `reason=unconditional`. Synthflow exposes that header as the `<diversion>` placeholder in before-the-call and during-the-call custom actions. Diversion is only available on inbound calls.

Some carriers strip `Diversion`. If yours does, send the same value in an `X-Diversion` header, and Synthflow uses it instead.

```
INVITE sip:+12065551234@sip.us.synthflow.ai:32681 SIP/2.0
From: <sip:+14155550199@caller.net>;tag=9fxced76sl
To: <sip:+12065551234@sip.us.synthflow.ai>
X-Diversion: <sip:+15559876543@acmebank>;reason=unconditional;brand=AcmeBank;journey_stage=loan-apps
```

A common pattern is a before-the-call action that sends `<diversion>` to your API, which reads parameters such as `brand` and returns variables for the prompt. One agent can then switch persona by brand.

```json
{
  "diversion_header": "<diversion>",
  "brand": "AcmeBank",
  "journey_stage": "loan-apps"
}
```

Your API returns a JSON object whose keys match the variable names in your prompt.

When you build parameters into the Diversion header:

* Keep the header under about 1 KB, or it can fragment on UDP.
* Use only letters and digits in parameter names. Some SBCs reject other characters.
* If another platform adds its own Diversion entry, keep yours last, so your API always reads the same position.
* Keep parameter names in sync with your prompt variables. If you rename one, update the header, your API, and the prompt together.

## Before-the-call actions

A before-the-call custom action calls your API as the call connects, and fills prompt variables with the response before the agent speaks. Use it when the SIP headers carry an ID, and your API holds the rest of the data.

1. Create a [custom action](/about-custom-actions) that sends a `POST` request and runs before the call starts. Through the API, [create the action](/api-reference/platform-api/actions/create-action) with `run_action_before_call_start` set to `true`.
2. In the request body, include the values your API needs, such as `<external_id>`, `<diversion>`, or `{X-Account-ID}`.
3. Return a JSON object whose keys match the variable names in your prompt. For example, if your prompt uses `{name}`, return `{"name": "John"}`. You do not need to change the prompt.
4. [Attach the action](/api-reference/platform-api/actions/attach-action) to the agent.