Skip to content

Carriers & Outbound Routing

Describe how Get2Dial models SIP carriers and DID inventory, and how an outbound call is matched to a carrier and turned into a FreeSWITCH gateway.

Three tables work together:

  • carriers — the SIP trunks/PSTN parties a tenant uses. Key columns: name, type (sip_trunk/register_trunk/iax2/webrtc), direction (inbound/outbound/bidirectional), status, remote_host/remote_port, transport, inbound_ips (IP allow-list), digest auth_*, strip_prefix/ add_prefix, and origin (platform = “provided by get2dial” vs tenant).
  • outbound_routes — per-tenant dial-prefix → carrier mapping: match_type (prefix/regex), prefix/regex, carrier_id, priority (lower is tried first), and optional per-route strip_prefix/add_prefix.
  • phone_numbers — DID inventory (the number, a delivering carrier_id, capabilities). This is an inbound/inventory concept; routing of inbound calls is owned by routing_rules (joined on the number), and it plays no part in outbound carrier selection.

Carriers, routes and numbers are managed through their REST endpoints (admin/platform_admin); tenant-created carriers and routes are gated by the self_service_carriers feature plus the carriers:write / outbound_routes:write capabilities.

Method Path Purpose
GET·POST /api/v1/carriers List / create carriers (DELETE archives, not hard-deletes)
GET·PATCH·DELETE /api/v1/carriers/{id} Read / update / archive
GET·POST /api/v1/phone-numbers List / create DIDs
GET·POST /api/v1/outbound-routes List / create routes

The outbound carrier-selection flow:

flowchart LR
  C[Campaign] -->|metadata.carrier_id?| F{Forced carrier?}
  F -- yes --> G[Use that carrier]
  F -- no --> R[Match outbound_routes by priority]
  R -->|prefix / regex match| G
  G --> GW["sofia/gateway/<name>"]
  GW --> Carrier[(Upstream carrier)]

The full caller-ID chain: the presented CLI comes from lead_lists.caller_id (not the campaign or the phone-number row); the destination is the lead’s primary_phone; that destination matches an outbound route (or a per-campaign metadata.carrier_id override) to pick a carriers row; the carrier becomes a FreeSWITCH sofia/gateway/<name> whose caller-id-in-from=true puts the per-call CLI into the SIP From.

  • A prefix route does not auto-strip the prefix — the full E.164 number is dialed unless strip_prefix is set explicitly.
  • outbound_routes.carrier_id is ON DELETE RESTRICT (protects live routes); phone_numbers.carrier_id is ON DELETE SET NULL (inbound DIDs survive a carrier being archived).
  • If a forced carrier_id lookup fails, the call engine falls back to prefix routing rather than failing the call.
  • STIR/SHAKEN: a campaign’s stir_shaken_attestation (A/B/C) rides out as the SIP Identity header; the actual signing is the carrier’s/SBC’s job — Get2Dial only carries the level.
  • Gateway params are reloaded via reloadxml + sofia profile external rescan; refreshing changed params on an existing gateway is the known sharp edge (may need a recreate).