plain-angle-54201
03/18/2026, 6:33 AMtall-airline-16756
03/18/2026, 6:33 AMtall-airline-16756
03/18/2026, 6:34 AMplain-angle-54201
03/18/2026, 6:36 AMtall-airline-16756
03/18/2026, 6:36 AMX-Transfer-To: queue123, X-Agent-Login: agent42)
High-level plan (what to implement)
1. Ensure your AI agent signals the desire to transfer to your application control plane (not directly sending SIP to the carrier).
◦ The AI should trigger a transfer action in your application (for example: call a control API that will arrange the BYE + headers).
1. Have your application tell LiveKit to update participant/session metadata so the room/UI reflects the transfer (optional but recommended).
◦ Use participant metadata or room state to indicate transfer target, agent presence, etc.
1. Make the SIP BYE flow through LiveKit’s SIP gateway to Kamailio, not directly from the AI.
◦ The BYE must originate from a component that the LiveKit SIP server will relay to Kamailio. That means the BYE should be sent by the LiveKit SIP component (or by a control adapter that calls the SIP gateway API exposed to Kamailio), not by a separate SIP client that bypasses Kamailio.
1. Insert custom SIP headers into the BYE at the point where signaling can be modified.
◦ Two places to add headers:
▪︎ In your application/control adapter before handing the BYE to LiveKit’s SIP gateway (if that gateway accepts and forwards supplied headers).
▪︎ Or in Kamailio (SBC) as it forwards the BYE to the carrier — Kamailio can add or rewrite headers reliably.
Recommended architecture for your requirements (self-hosted on EKS)
• Keep Kamailio as your signaling front-end for PSTN and as the single source of truth for outbound carrier signaling.
• LiveKit SIP server should be behind Kamailio so all external SIP to carrier goes Kamailio -> LiveKit -> Kamailio -> carrier (Kamailio on both ingress and egress can be configured to ensure correct routing).
• Use a small control adapter service (can run in EKS) that:
a. Receives the transfer command from the AI agent.
b. Calls LiveKit to update participant metadata/state (so room/UI reflects the transfer).
c. Calls Kamailio’s management API or your SIP gateway API to send a BYE with the required custom headers toward the carrier (so Kamailio is the originator/handler of the carrier-bound BYE).
• This avoids bypassing Kamailio and gives you a place to set headers precisely.
Where to add the custom headers (two practical options)
• Option A — Add headers in Kamailio before sending to carrier:
◦ Kamailio has flexible scripting (cfg) to detect BYE requests and add headers like append_hf("X-Transfer-To: queue123\r\n"); or hdr_append() depending on module. This guarantees headers are injected at the last hop and preserved for carrier routing.
◦ Advantage: centralized control at the SBC level; no dependency on LiveKit supporting header injection.
• Option B — LiveKit/gateway accepts headers to forward:
◦ If your LiveKit SIP gateway supports passing through custom SIP headers from application-level control (via an API or session metadata), your control adapter can set the headers and LiveKit will forward them to Kamailio which then forwards to the carrier.
◦ Confirm LiveKit SIP gateway will forward arbitrary BYE headers unchanged; if not, use Option A.
Practical sequence (example flow)
1. PSTN -> Kamailio (ingress) -> LiveKit SIP server -> LiveKit room (AI agent).
2. AI agent decides to transfer and calls your control adapter: POST /transfer { participantId, targetQueue, headers: { X-Transfer-To: queue123 } }.
3. Control adapter updates LiveKit participant metadata so UI/agent know call is transferring.
4. Control adapter instructs Kamailio (via management API or by sending a controlled SIP BYE through your SIP gateway) to send BYE to the carrier. Kamailio injects the custom headers and forwards to carrier.
5. Carrier routes to queue/agent per header. Once carrier connects, update LiveKit participants/state so the UI switches to agent audio.
EKS specifics and deployment notes
• Run Kamailio as a StatefulSet or Deployment with stable networking and necessary SIP ports open (UDP/TCP/WS/TLS depending on transport).
• Ensure NAT, RTP, and firewall rules allow media between LiveKit pods and Kamailio and between Kamailio and carrier.
• Run the control adapter as a Deployment with a secure API endpoint the AI can call.
• Use ConfigMaps/Secrets for Kamailio cfg and any credentials needed to call carrier APIs.
• For reliability, use health checks and configure SIP transaction timers inside Kamailio to match carrier expectations.
Validation and testing steps
1. Test header injection locally: have Kamailio log outgoing BYE headers to verify X- headers are set.
2. Simulate AI transfer flow: trigger the control adapter to perform the sequence and trace SIP messages with sngrep or tcpdump on Kamailio to confirm BYE passes through with custom headers.
3. Confirm carrier behavior in a staging trunk before production.
Next action I can take for you
• If you share the exact header names/values, I can give a sample Kamailio config snippet to append headers on BYE.
• If you prefer LiveKit to carry headers, tell me whether your LiveKit SIP gateway exposes a control API or session metadata channel; I’ll outline the exact API calls you need.
• If you want the control adapter pattern, I can provide a minimal sequence and sample pseudo-API for your service to implement.
Tell me which option you prefer (Kamailio header injection vs LiveKit-forwarded headers) and the header names you need, and I’ll produce the specific Kamailio config or control-adapter sample.
, with interactive elementsplain-angle-54201
03/18/2026, 6:40 AMtall-airline-16756
03/18/2026, 6:41 AMX-Transfer-To: queue123, X-Agent-Login: agent42).
◦ Any required header formatting, or whether the carrier requires these headers only on BYE (vs other methods).
1. Control API availability
◦ Does your LiveKit SIP gateway expose any control API or session metadata channel that your control adapter can call to attach SIP headers to outbound SIP messages? If yes, which API?
1. SIP trace/testing access
◦ Can you run sngrep/tcpdump on Kamailio to capture SIP traces for a test call and share a redacted BYE trace? This helps confirm whether LiveKit currently forwards BYE headers.
1. Deployment/security constraints
◦ Any compliance/security constraints that would prevent adding arbitrary headers at Kamailio or LiveKit (for example, header whitelists, logging policies, or carrier restrictions)?
If you prefer, start with the header names/values (question 5) and the answer to who should originate the BYE (question 3). With those two I can immediately produce:
• A sample Kamailio snippet to append headers on BYE (Option A).
• A sample control-adapter flow and the exact places to call LiveKit/Kamailio APIs if you want Option B and it’s supported.
Pick one of:
• Send header names + BYE originator now and I’ll provide the config snippet and control flow.
• Or provide answers to all questions above and I’ll produce step-by-step EKS deployment and trunk/inbound changes for your exact environment., with interactive elementsplain-angle-54201
03/18/2026, 7:07 AMlivekit/sip:latest, helm repo add livekit <https://helm.livekit.io> we use helm repo or chart for livekit and update our configuration file like that currently we do
3. Type: Using the standard LiveKit SIP gateway component deployed as a separate sip-server service within the EKS cluster.
4. SIP transport between LiveKit and Kamailio
5. Protocol: Internal communication between Kamailio and LiveKit is handled over UDP/TCP on port 5060.
6. Proxy Flow: Kamailio acts as the entry/exit point: Five9 (TLS 5061) ↔️ Kamailio ↔️ LiveKit (UDP 5060).
7. BYE originator in the desired flow
8. Current: The ai-agent triggers a room deletion via the LiveKit API, which causes the LiveKit SIP Gateway to generate the BYE so currently BYE generated in Sip server and its directly send to carrier thats happend but also no any custom header i see in tcpdump or sngrep when i do in the sip server pod.
9. Requirement: The BYE must traverse Kamailio to ensure it reaches Five9 via the correct Elastic IP (EIP) and TLS transport.
10. Existing Kamailio header handling
11. Mechanics: Kamailio uses record_route_preset with double Record-Route headers (one for the external EIP and one for the internal pod IP) to force the SIP path.
12. Filtering: It has an OPTIMIZE_HEADERS route prepared for stripping/whitelisting, and it manually rewrites the Contact header in both directions to maintain the signaling path through Kamailio.
13. Carrier header requirements
14. Headers: Five9 expects specific data for transfers (e.g., five9RouteType, five9RouteValue).
15. Mapping: The agent sets these as participant attributes in LiveKit, which the SIP gateway maps to custom SIP headers (e.g., X-Five9-Route-Type) on the BYE message.
16. Control API availability
17. API: The system uses the LiveKit Server SDK (Python) to dynamically update participant metadata and signal call termination/transfers.
18. SIP trace/testing access
19. Tooling: sngrep and tcpdump are available on the Kamailio pods to capture and verify SIP message flow and header integrity.
20. Deployment/security constraints
21. Environment: EKS-based deployment with hostNetwork: true for predictable SIP routing.
Addressing: Uses AWS Elastic IPs (EIPs) mapped via an NLB to provide stable public entry points for Five9.tall-airline-16756
03/18/2026, 7:09 AMtrunk_config = api.SIPInboundTrunkInfo(
name="Five9-Trunk",
numbers=["+your_number"],
attributes_to_headers={
"five9.route.type": "X-Five9-Route-Type",
"five9.route.value": "X-Five9-Route-Value"
},
# other trunk settings...
)
• Behavior: When a SIP participant attribute such as five9.route.type is present on the SIP participant, LiveKit will include X-Five9-Route-Type: <value> on generated BYE messages.
2) AI agent / control flow: set participant attributes before terminating
• Before you delete the room / end the call, set the participant attributes via the LiveKit Server SDK:
await participant.set_attributes({
"five9.route.type": "transfer",
"five9.route.value": "supervisor_queue"
})
# Then delete the room (or call the API that triggers BYE)
await api.room.delete_room(api.DeleteRoomRequest(room=room_name))
• Confirm attributes are attached to the SIP participant (you can log attribute changes or subscribe to participant attribute events).
3) Ensure LiveKit’s SIP gateway respects Kamailio’s Record-Route path
• You already have double Record-Route in Kamailio which forces responses to traverse Kamailio. Ensure LiveKit’s SIP server does not strip Record-Route and will honor it.
• Keep LiveKit SIP settings so signaling_ip/sip_port match your internal Kamailio endpoint (UDP/TCP 5060). In Helm values, ensure sip.port and signaling/network settings reflect your cluster networking.
4) Kamailio: whitelist/pass X-* headers and preserve routing
• Kamailio’s OPTIMIZE_HEADERS route must allow X-Five9 headers and not strip them. Update header whitelisting or add explicit header append logic if needed:
◦ If Kamailio strips unknown headers, add rules to preserve X-Five9-Route-Type and X-Five9-Route-Value.
◦ If you want to assert values or add/modify them at the last hop, do that here so Five9 sees the expected names/values.
• Example: in the BYE handling path (cfg), ensure you do not remove X-* headers and that you call t_relay() so BYE follows the recorded route:
if (is_method("BYE")) {
if (loose_route()) {
# Keep custom X-* headers
route(OPTIMIZE_HEADERS); # ensure this doesn't strip X-Five9-*
t_relay();
}
}
• If OPTIMIZE_HEADERS strips custom headers by default, explicitly append them:
append_hf("X-Five9-Route-Type: ${hdr(custom_attr)}\r\n");
(Use your actual variable/logic to build values.)
5) Ensure BYE leaves Kamailio to Five9 over TLS/EIP
• Confirm Kamailio selects the outbound route that uses your EIP/NLB -> Five9 TLS 5061 path. Your double Record-Route approach should force responses through Kamailio; verify routing table and lookup logic selects the TLS next hop.
• If needed, route selection can be forced by matching topmost Record-Route and using t_on_branch or next_hop selection logic.
6) Testing & verification (recommended order)
• Step A — Attribute propagation check:
◦ Set attributes on the SIP participant and inspect LiveKit’s internal state or logs to confirm attributes exist before termination.
• Step B — Trigger BYE from LiveKit and capture on Kamailio:
◦ On Kamailio pod run: sngrep or tcpdump and filter BYE to confirm LiveKit’s BYE arrives at Kamailio with X-Five9-Route-* present.
◦ Example sngrep commands:
▪︎ sngrep -c "BYE" -H "X-Five9"
▪︎ tcpdump -i any -s 0 -A port 5060 | grep -A 10 "BYE"
• Step C — Confirm Kamailio forwards BYE to Five9 over TLS (port 5061) and that Five9 receives the X-* headers:
◦ Capture on Kamailio egress interface or on your NLB logs (if available).
• Step D — End-to-end: Ensure Five9 behavior (queue/transfer) is triggered by the header values.
7) Common issues and how to resolve them
• Missing headers at Kamailio: verify LiveKit mapping is configured correctly and that attributes are actually set on the SIP participant before the BYE.
• Kamailio strips headers: update OPTIMIZE_HEADERS or routing cfg to whitelist X-Five9-*.
• BYE bypasses Kamailio and goes directly out: ensure Record-Route sequencing and that LiveKit does not choose an alternate route. Double-check the Via/Record-Route stack in a SIP trace — BYE should have the Kamailio Record-Route entries.
• Transport mismatch (UDP vs TLS): LiveKit sends to Kamailio UDP 5060; Kamailio must translate/relay to Five9 TLS 5061. Ensure Kamailio’s t_relay selects the TLS socket for that destination.
8) Sample validation sequence you can run now
1. On a test call, set participant attributes:
◦ five9.route.type=transfer
◦ five9.route.value=supervisor_queue
1. Trigger the room deletion so LiveKit generates BYE.
2. On Kamailio pod:
◦ Run sngrep/tcpdump and capture the incoming BYE from LiveKit. Confirm BYE contains X-Five9 headers.
◦ Confirm kamailio forwards BYE to Five9 over TLS 5061 and that headers are present in the outbound packet.
1. If headers are missing outbound, inspect OPTIMIZE_HEADERS and any rewrite logic that touches BYE/Contact/Record-Route.
If you want, I can provide:
• A specific Kamailio cfg snippet to ensure X-Five9 headers are preserved and t_relay to TLS is used.
• A short LiveKit Helm values YAML example for sip config fields you should verify.
• A minimal control-adapter example (if you want Kamailio to add or override headers instead).
Which of the following would you like next?
• Kamailio cfg snippet to preserve and/or append X-Five9 headers on BYE.
• LiveKit Helm values snippet showing the relevant sip settings (signaling_ip, sip_port, and a reminder where to add attribute->header mapping).
• Both snippets together and a short checklist for your staging test.
Tell me which snippet(s) you want and I’ll produce them with exact lines you can paste into your configs.
Sources: SIP Lifecycle Management Agent | LiveKit Documentation, with interactive elements