Map carrier SIP headers to Retell
Carriers often send useful data in SIP headers: the caller's display name, a
queue or location label, a CRM or conversation ID, diversion history, or the
original dialed number. sipsandwich can pass that data to your Retell agent
as X-* headers, which Retell exposes to the agent as dynamic variables.
There are three ways to do it. You can combine them on one number.
| Option | What reaches Retell | Added call-setup time |
|---|---|---|
| Forward every carrier header | Every eligible header as X-SIP-<Header>, plus From/To name, user, and host | None. Copied on the SIP edge |
| Copy one header | One carrier header under the X-* name you choose | None. Copied on the SIP edge |
| Extract part of a header | A new X-* header built from part of a carrier header | One internal lookup; skipped if it is slow or fails |
Each phone number holds up to 10 mapping entries. Forward-all counts as one entry, and so does each derived rule.
Open the mapping step
- Open Numbers and choose Manage on the number.
- Continue to Handoffs and turn on Read extra data from my carrier.

The Map carrier SIP headers step opens and starts a header capture. Place
one test call to the number within two minutes. sipsandwich records that call's
exact headers and rejects it with 486 Busy instead of sending it to Retell,
so nobody needs to answer. Raw values are shown exactly as received. They
expire after 10 minutes and are never stored with your mappings.

A capture is optional for forward-all, but it shows exactly what your carrier sends.
Forward every carrier header (fastest)
Select Forward every carrier header to Retell. The selected card shows a green outline and a check mark, plus a preview of exactly what Retell will receive from the captured call.

For each inbound call, the SIP edge copies headers as the call passes through. There is no lookup and no added setup time:
- Every eligible carrier header is sent as
<prefix><Header>, for exampleX-SIP-P-Asserted-IdentityorX-SIP-Diversion. - From and To are also split into parts:
X-SIP-From-Name,X-SIP-From-User,X-SIP-From-Host,X-SIP-To-Name,X-SIP-To-User, andX-SIP-To-Host. The display name is sent without quotes. - Headers that already start with
X-reach Retell unchanged, so they are not duplicated.
The default prefix is X-SIP-. You can change it, for example to X-Carrier-.
It must start with X-, end with -, contain only letters, numbers, and
hyphens, and cannot be X-SipSandwich-. Other mappings on the number cannot
use names inside the prefix.
Never forwarded: credentials (Authorization, Proxy-Authorization,
WWW-Authenticate, Proxy-Authenticate), routing headers (Via, Route,
Record-Route, Contact, Path, Max-Forwards, CSeq), message-body
headers (Content-*), and SIP capability and negotiation headers such as
Allow, Supported, Require, Accept, Session-Expires, and Expires.
Call-ID is withheld when topology hiding is on.
Limits: up to 24 forwarded headers, 512 characters per value. When a header
repeats, the first value is used. Leading spaces are trimmed, and empty values
and values containing line breaks are skipped. Compact header names such as
f, t, and i are expanded to From, To, and Call-ID.
Copy one header
Tick a header in the captured inventory and choose the X-* name Retell
should receive, for example X-Genesys-Conversation-Id to
X-Conversation-Id. Bidirectional mappings also return the header to the
carrier when a Retell transfer function sends it back. Copies run on the edge
with no lookup.
Extract part of a header with Composer AI
Use a derived rule when you only need part of a value. For example, a carrier sends this From header:
From: "Main Line Location Queue - A BEN-HANAN" <sip:+14155550155@carrier.example>;tag=as5f2c9e1b
To send just the location as X-Location-Name: main line location:
- Choose Extract part on the
Fromrow. - In Ask Composer, describe the result, for example: Keep everything before "-", drop the word "queue", make it lowercase, and send it as X-Location-Name.
- Choose Draft rule. Composer fills in the source part, the new header name, and ordered steps, and the preview shows each step applied to the captured value.
- Adjust any step if needed, then choose Save mappings.

A rule reads one part of a carrier header (display name, URI user, URI host, a header parameter, or the full value). It then applies up to 12 literal steps: keep text before or after a delimiter (first or last match), remove whole words, replace text, or change case. Rules never run tenant-supplied regular expressions. Composer sees only your instruction, the captured header names, the one sample value you are previewing, and the rule you are editing. Composer AI is included with every plan, like the AI carrier setup.
Derived values are computed during each call setup through one internal
lookup. If that lookup is slow or fails, the call still connects without the
derived headers. Credential headers cannot be a source, and targets cannot
use the X-SipSandwich- prefix.
Check what was saved
After saving, the Handoffs card lists every rule. Forward-all is marked Fastest.

Changes apply to the next inbound call. To see the result, open the call's SIP flow in Call logs, or read the dynamic variables in Retell.
Use the headers in Retell
Retell exposes each custom X-* header to the agent as a dynamic variable.
The variable name drops X- and uses lowercase with underscores; the preview
in the app shows each one:
| Header sent to Retell | Agent variable |
|---|---|
X-SIP-From-Name | {{sip_from_name}} |
X-SIP-P-Asserted-Identity | {{sip_p_asserted_identity}} |
X-Location-Name | {{location_name}} |
Reference them in the agent prompt or in functions, for example
The caller reached the {{location_name}} line.
Configure it with the API, SDK, CLI, or MCP
All three options use the same tenant-token API. See Developer tools for authentication. The endpoints are listed under Phone Numbers in the API reference.
Forward every header with curl:
curl --fail-with-body \
-X PUT "https://api.sipsandwich.ai/api/v1/phone-numbers/$PHONE_NUMBER_ID/sip-header-mappings" \
-H "Authorization: Bearer $SIPSANDWICH_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mappings":[{"providerHeader":"*","retellHeader":"X-SIP-","direction":"passthrough"}]}'
PUT replaces every mapping on the number, so include each entry you want to
keep. Forward-all plus a derived location rule:
{
"mappings": [
{ "providerHeader": "*", "retellHeader": "X-SIP-", "direction": "passthrough" },
{
"providerHeader": "From",
"retellHeader": "X-Location-Name",
"direction": "derived",
"transform": {
"source": "display_name",
"steps": [
{ "op": "keep_before", "delimiter": "-", "occurrence": "first" },
{ "op": "remove_words", "words": ["queue"] },
{ "op": "change_case", "mode": "lower" }
]
}
}
]
}
Draft a rule with Composer AI, then save it with the SDK:
import { SipSandwich } from "@sipsandwichai/sdk";
const client = new SipSandwich({ apiToken: process.env.SIPSANDWICH_API_TOKEN! });
const { draft } = await client.phoneNumbers.draftSipHeaderTransform(phoneNumberId, {
instruction: 'Keep everything before "-", drop the word queue, send as X-Location-Name',
providerHeader: "From",
sampleValue: '"Main Line Location Queue - A BEN-HANAN" <sip:+14155550155@carrier.example>'
});
// Review draft.preview (here "main line location") before saving.
await client.phoneNumbers.updateSipHeaderMappings(phoneNumberId, {
mappings: [
{ providerHeader: "*", retellHeader: "X-SIP-", direction: "passthrough" },
{
providerHeader: draft.providerHeader,
retellHeader: draft.retellHeader,
direction: "derived",
transform: draft.transform
}
]
});
The draft endpoint never saves anything. Its source is ai when Composer AI
drafted the rule, or local when the built-in interpreter did.
From the CLI:
sipsandwich update-sip-header-mappings PHONE_NUMBER_ID \
--body '{"mappings":[{"providerHeader":"*","retellHeader":"X-SIP-","direction":"passthrough"}]}'
sipsandwich get-sip-header-mappings PHONE_NUMBER_ID
sipsandwich draft-sip-header-transform PHONE_NUMBER_ID --body draft.json
MCP hosts get the same operations as tools: sipsandwich_get_sip_header_mappings,
sipsandwich_update_sip_header_mappings, sipsandwich_draft_sip_header_transform,
sipsandwich_start_sip_header_capture, sipsandwich_get_sip_header_capture,
and sipsandwich_cancel_sip_header_capture.
To inspect a carrier's headers from code, call startSipHeaderCapture, place
the test call, and poll getSipHeaderCapture until status is captured.
Responses are Cache-Control: no-store and contain the raw values for your own
tenant only.
The header-mapping operations require @sipsandwichai/sdk,
@sipsandwichai/cli, and @sipsandwichai/mcp version 0.2.0 or later.