Egress routing
Path: /admin-settings/egress
The Egress tab is a unified Trunks | Pools surface. Trunks are individual carrier or PBX destinations; pools group trunks for round-robin or priority-failover transfer routing. The same layout appears on the team Settings → Team tab for team-scoped objects — see Team overview.
Legacy deep links /admin-settings/egress-trunks and /admin-settings/egress-routes open this tab on the Trunks or Pools sub-tab respectively.
When a flow, managed LLM callback, failover policy, or AI tool requests a transfer, Kamailio uses egress state linked to the call's base number (or pool routing key) to determine carrier, transport, authentication, caller ID, codecs, and failover members.
Use Force re-sync in the tab bar only as a recovery action when Redis routing cache is suspected stale. Ordinary saves auto-sync trunks, pools, and base-number links.
How transfers use egress
Egress configuration answers one question for outbound transfers: how does Delphi reach the carrier or PBX for the outbound leg? That applies to canvas Transfer nodes, managed LLM transfer actions, failover handoffs, and provider callbacks — they all share the same runtime validation and TelPro routing path.
Before a transfer can work
- The call's endpoint should have an Egress Base Number when the endpoint type supports outbound transfers (Phone and Web Voice). That base number is the outbound identity Kamailio uses on the SIP leg.
- At least one trunk must exist, linked either directly to that base number or through a pool that references the base number.
- Platform or team transfer restrictions must allow the target (premium numbers, country codes, and so on).
- For managed LLM transfers, the flow must enable the managed transfer action and allow the requested method (
sip_refer,sip_invite, and so on).
If any of these are missing, the transfer fails at runtime even when the flow graph looks correct.
How the transfer target picks a route
| Target shape | Egress behavior |
|---|---|
Phone number or tel: URI | Requires egress routing. The flow can select an explicit pool (routingPool / Route ID) or fall back to the default base-number pool (trunks linked directly to the egress base number by priority). |
Full sip: or sips: URI | Routes by the URI host/domain. Pool selection is not used; TelPhi/TelSys send the outbound leg toward that SIP destination directly. |
Managed callback transferTarget | Same rules as above — number-like targets need a pool or default trunk link; full SIP URIs bypass pool lookup. See Managed callback actions. |
In the Flow Designer, the Egress route dropdown on transfer settings stores routingPool when you pick a pool. Leaving it on Default base-number pool uses trunks linked to the base number without naming a pool explicitly.
When a pool is selected for a number transfer, runtime carries the pool's Route ID (for example via X-Delphi-Egress-Route) together with the base-number context so Kamailio can resolve the correct member trunks.
What happens inside a pool
Once Kamailio resolves a pool, member trunks execute the actual outbound SIP:
- Priority / failover — try the highest-priority trunk first; move to the next member if the carrier or PBX rejects or does not answer.
- Round robin — spread attempts across healthy members.
Trunk-level settings (transport, digest/registration auth, caller ID mode, codecs) apply to whichever member trunk handles that attempt.
Runtime path
After validation, TelPhi hands off to TelSys, which presents the outbound INVITE (or REFER) to Kamailio with the base-number and pool context. Kamailio reads the synced Redis payload, picks the trunk (or pool member), and sends the carrier-facing SIP. Inspect the conversation Debug tab SIP ladder to confirm which trunk and headers were used.
Common failure modes
| Symptom | Likely cause |
|---|---|
| Transfer fails immediately | Target blocked by transfer restrictions, or managed transfer not enabled. |
| "No egress route" for a number target | No pool selected and no trunks linked to the egress base number. |
| Wrong carrier or caller ID | Stale Redis state, incorrect pool member priority, or trunk caller-ID mode. |
| SIP URI transfer fails differently | DNS/host routing issue — pool config is bypassed; check URI and carrier path. |
General
| Field | Required | Description |
|---|---|---|
| Name | Yes | Friendly name (e.g. "Deutsche Telekom"). |
| Trunk ID | Yes | Technical identifier (lowercase, unique). |
| SIP URI | Yes | Carrier SIP URI (e.g. sip:carrier.example.com:5060). |
| Enabled | Yes | Master toggle. |
| Priority | No | Higher = preferred when multiple trunks are linked. Default 50. |
Transport
| Field | Required | Description |
|---|---|---|
| Transport | Yes | udp / tcp / tls. |
Authentication
| Method | How it works | Prerequisites | Use case |
|---|---|---|---|
ip_only | Carrier trusts by IP. | — | Simple trusted carriers. |
digest | Standard SIP digest (401 / 407 challenge). | Auth User + Pass. | Most carriers. |
registration | Persistent SIP REGISTER with carrier. | Auth User + Pass. | Carriers that require register-before-invite. |
ip_and_digest | Both IP and digest. | Allowed IPs + Auth User + Pass. | Hardened. |
tls_mutual | Client TLS cert. | Transport=tls + TLS Cert variable. | mTLS carriers. |
| Field | Conditional | Description |
|---|---|---|
| Auth User | digest / registration | Username. |
| Auth Pass | digest / registration | Password (encrypted). |
| Auth Realm | digest / registration | SIP realm. |
| TLS Cert Variable | tls_mutual | Team variable (type secret) holding the client cert. |
Caller ID
| Field | Description |
|---|---|
| Caller ID Mode | passthrough (original caller), base_number (the base number itself), override (custom value). |
| Caller ID Override | Required when mode is override. |
The agent's transfer() tool can pass a callerId parameter that takes priority over the trunk's mode.
Technical
| Field | Default | Description |
|---|---|---|
| Max Concurrent Calls | 0 (unlimited) | Cap. |
| Codec Preferences | ["PCMA", "PCMU"] | Priority order. |
Base number linking
| Field | Description |
|---|---|
| Base Numbers | Multi-select. A base number can link multiple trunks; priority controls selection and failover order. |
You can also link from the Base numbers edit form via "Outbound Trunk (Egress)".
Changes to egress trunks and base-number links auto-sync to Kamailio's Redis routing state. If a transfer still follows an old route, check TelPro operations and verify the voiceai:egress:<num> payload.
Egress pools (Pools sub-tab)
Open the Pools sub-tab to manage egress route pools. A pool groups one or more trunks under a stable Route ID that flows and managed callbacks reference.
| Field | Required | Description |
|---|---|---|
| Name | Yes | Friendly label (e.g. "Twilio staging"). |
| Route ID | Yes | Technical key (twilio_staging) used in flow transfer settings and managed callback routingPool fields. |
| Base Number | Yes | Outbound identity and fallback route key for the pool. |
| Strategy | Yes | round_robin or priority_failover. |
| Enabled | Yes | Master toggle. |
| Priority | No | Pool priority when multiple pools compete. Default 50. |
| Member trunks | Yes | One to sixteen trunks, each with a member priority. No duplicate trunk per pool. |
| Strategy | Behavior |
|---|---|
| Priority / failover | Try the highest-priority available member first, then fall through when routing fails. |
| Round robin | Rotate across healthy members to spread transfer attempts. |
Managed callbacks can select a pool with transferRoutingPool / routingPool. Full sip: or sips: URI targets route by URI host instead of using a number-only pool lookup.
Create an egress pool
- Open Pools → New.
- Set Name, Route ID, base number, and strategy.
- Add member trunks (create trunks first on the Trunks sub-tab if needed).
- Enable and save — Redis sync runs automatically.
Workflows
Create an egress trunk
Open the Trunks sub-tab, then:
Click Create → Name + Trunk ID + SIP URI → Transport → Auth Method + credentials → Caller ID Mode → optional Codec Preferences / Max Concurrent → link base numbers → enable → save. Changes auto-sync to Redis; for registration trunks, Kamailio kicks off REGISTER automatically.
Verify transfer routing
After changing a trunk or base-number link:
- Place a transfer test call from a published flow or managed LLM callback.
- Open the conversation's Debug tab and inspect the SIP ladder.
- Check whether the outbound leg used the expected trunk, caller ID, and transfer headers.
- If the ladder is missing or stale, ask the operator to inspect
voiceai:egress:<num>on Redis.
Reference examples
Deutsche Telekom (digest)
| Setting | Value |
|---|---|
| SIP URI | sip:sip-trunk.telekom.de:5060 |
| Transport | udp |
| Auth Method | digest |
| Caller ID Mode | base_number |
| Codec Preferences | ["PCMA", "PCMU"] |
Twilio (IP auth + TLS)
| Setting | Value |
|---|---|
| SIP URI | sip:your-trunk.pstn.twilio.com |
| Transport | tls |
| Auth Method | ip_only |
| Caller ID Mode | override |
| Caller ID Override | +14155551234 |
Carrier with registration
| Setting | Value |
|---|---|
| SIP URI | sip:registrar.carrier.example.com |
| Transport | udp |
| Auth Method | registration |
| Caller ID Mode | passthrough |
See also
- Team overview — team-scoped trunks and pools.
- SIP trunks — inbound counterpart.
- Base numbers — link from the base-number side.
- TelPro operations — runtime.
- Managed callback actions — pool and transfer fields.