Exotel vSIP
Point an Exotel SIP trunk at Tone — PoPs, transports, the X-Exotel headers, and the Exophone rule that rejects outbound calls.
Exotel's SIP trunking product (vSIP) connects a SIP stack straight to their voice network, instead of the WebSocket streaming their Voicebot applet uses. This page configures it against Tone.
Exotel classes vSIP as Alpha and puts no SLA behind it. There is no self-serve API: trunks are provisioned by hand by your account manager, and SIP traffic is blocked until your account is KYC-verified and upgraded to a full account. Budget for a few days of email.
Before you start
- A full, KYC-verified Exotel account (
my.in.exotel.comormy.exotel.com). - At least one Exophone — the number your calls will present. Procured through hello@exotel.com.
- A Tone organization with KYC verified and SIP trunking enabled by Tone support.
Which PoP
Exotel terminates on regional edge PoPs. Pick the one your account is on — ask your account manager if you are not sure, because it is set per account, not per trunk.
| Region | SIP proxy | Media IPs |
|---|---|---|
| Mumbai | pstn.in2.exotel.com | 182.76.143.61, 122.15.8.184 |
| Mumbai Cloud | pstn.in4.exotel.com | — |
| Karnataka | pstn.in1.exotel.com | 14.194.10.247, 61.246.82.75 |
| Singapore | pstn.sgp1.exotel.com | 18.142.150.245, 122.248.223.73 |
🔴 A Singapore PoP sends your call audio out of India. Tone keeps media in Mumbai
(ap-south-1), but the leg between Exotel and the PSTN is Exotel's, and on sgp1 it is not in
country. If your compliance position depends on media staying in India, ask Exotel to move the
account to in2 or in4 before you build on it.
Transports
| Transport | Port | Encryption |
|---|---|---|
| TLS | 443 | SIP over TLS + SRTP (a=crypto) — recommended |
| TCP | 5070 | none |
SIP over UDP is not supported, and neither is REGISTER authentication. Exotel authenticates
you by source IP (or by FQDN), which lines up with Tone's ip_acl inbound mode.
Media is UDP 10000–40000, though Exotel asks you to narrow to 10000–20000 — two ports per
call, and their media servers cap at 3000 concurrent. Codecs are PCMA (G.711 A-law) preferred,
PCMU as fallback; DTMF is RFC 2833. Rate limit is 200 calls per minute per trunk.
What to send Exotel
Email your account manager with all of it at once — each round trip costs a day:
- your Account SID
- the Exophones to route
- Inbound to Tone (Exotel → Tone): Tone's signalling IPs, shown on your trunk's page in the
dashboard. Transport
TLS/443orTCP/5070. - Outbound from Tone (Tone → Exotel): the same Tone IPs, as source addresses to allow.
- the transport you chose
Ask them to confirm which source addresses their signalling actually comes from. The media IPs
above are published; signalling can egress from a different address, and an ipAcl built from the
wrong list refuses every call with a 403.
Create the trunk in Tone
Use ip_acl — Exotel cannot present digest credentials.
POST /v1/sip-trunks
{
"name": "Exotel vSIP (Mumbai)",
"inboundAuth": "ip_acl",
"ipAcl": ["182.76.143.61/32", "122.15.8.184/32"],
"outboundHost": "pstn.in2.exotel.com",
"outboundPort": 443,
"outboundTransport": "tls",
"outboundNumberFormat": "e164",
"callerIdPolicy": "did",
"codecs": ["PCMA", "PCMU"],
"customHeaders": { "X-Exotel-AccountSid": "your-account-sid" },
"maxConcurrent": 20
}Two fields are doing real work here.
customHeaders carries X-Exotel-AccountSid, which Exotel requires on an INVITE routed
into their network so they can find your tenant. It is the only X-Exotel-* header you may send:
do not add X-Exotel-CallSid, X-Exotel-LegSid or X-Exotel-TrunkSid — Exotel injects those,
and sending them is an error.
callerIdPolicy: "did" pins From to the trunk number. Exotel rejects any outbound INVITE
whose From is not a registered Exophone, so the permissive any_e164 policy fails every call
on this carrier.
Then import each Exophone:
POST /v1/sip-trunks/{id}/numbers
{ "e164": "+918044001234", "agentId": "…" }Log the call SID
On inbound legs Exotel injects X-Exotel-CallSid — the global call ID, and the only join key
between your SIP capture and Exotel's own dashboard and CDR. Tone records the inbound SIP headers
on the call, so when you open a ticket with Exotel you can hand them the SID from your own call log
instead of reconstructing it from timestamps.
Testing
POST /v1/sip-trunks/{id}/test— a SIPOPTIONSping to the PoP. Expect reachable, with an RTT in the low tens of milliseconds from Mumbai.- Call the Exophone from a mobile. Your agent should answer.
POST /v1/callswith the Exophone asnumberId.
To watch the wire, Exotel's own suggestion is sngrep or Wireshark; SIPp works for synthetic calls.
When it does not work
| What you see | Why |
|---|---|
Inbound 403 from Tone | Exotel's signalling source is not in your ipAcl. Ask for the signalling addresses, not the media ones. |
| Outbound rejected by Exotel | From is not a registered Exophone — check callerIdPolicy is did and the number is live on the account. |
| Outbound tenant error at Exotel | X-Exotel-AccountSid missing or wrong in customHeaders. |
| Nothing at all, on TLS | You are on 5070 with transport: tls, or 443 with tcp. The two do not cross. |
| Works, then stalls at volume | 200 calls/min per trunk is an Exotel-side limit. Tone's maxConcurrent is separate and cannot raise it. |
FQDN mode
If your side is not on a fixed address, Exotel can resolve an FQDN per call instead. It resolves DNS on every call, so keep the TTL at 30–60 seconds, use A/AAAA records — not a CNAME — and for TLS make sure the certificate CN or SAN matches the name Exotel dials. Tone's gateway runs on a fixed Elastic IP, so you will not normally need this.
Not this page
If you want a Tone number delivered to Exotel, or Exotel's Voicebot applet streaming to a Tone agent, neither is this product — see Inbound calls and Tone Media Streams.