Skip to main content

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.

OptionWhat reaches RetellAdded call-setup time
Forward every carrier headerEvery eligible header as X-SIP-<Header>, plus From/To name, user, and hostNone. Copied on the SIP edge
Copy one headerOne carrier header under the X-* name you chooseNone. Copied on the SIP edge
Extract part of a headerA new X-* header built from part of a carrier headerOne 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​

  1. Open Numbers and choose Manage on the number.
  2. Continue to Handoffs and turn on Read extra data from my carrier.

Read extra data from my carrier toggle

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.

Map carrier SIP headers step with a captured call

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.

Forward every carrier header with the X-SIP- prefix and a preview

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 example X-SIP-P-Asserted-Identity or X-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, and X-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:

  1. Choose Extract part on the From row.
  2. 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.
  3. 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.
  4. Adjust any step if needed, then choose Save mappings.

Derived rule drafted by Composer with a step-by-step preview

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.

Saved mappings summary

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 RetellAgent 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.