How to send BYE signal with Custom X-headers when call disconnects?

I want to set custom X-name headers for when terminating call.
Currently I have done mapping of attributesToHeaders and headersToAttributes and sending this way from agent.

Is it right way or not not sure or does livekit supports it. I checked livekit-server and Kamailio logs using sngrep but in BYE signal not getting any X-headers.

Deployed using EKS.

Thanks in advance.

code:

attrs = {
  “five9RouteType”: “Queue”,
  “five9RouteValue”: “Queue”,
  “five9Queue”: “True”,
  “five9IvaSessionId”: sesion_id
  “five9PersonId”: person_id,
  “five9Language”: “en-US”,
  “five9TransferReason”: str(reason or “”),
}

res = await job_ctx.api.room.update_participant(
  api.UpdateParticipantRequest(
  room=job_ctx.room.name,
  identity=sip_participant.identity,
  attributes=attrs,
  )
)

Yes, LiveKit does support attributes_to_headers — and your general approach is correct. The attributes_to_headers mapping on the trunk is specifically designed to map participant attributes to SIP X-* headers on BYE and REFER requests. This is confirmed directly in the LiveKit protocol definitions:

"Map LiveKit attributes to SIP X- headers when sending BYE or REFER requests. Keys are the names of attributes and values are the names of X-* headers they will be mapped to."*

So your approach of updating participant attributes via update_participant is the right idea. However, here are the key things to check if you’re not seeing the headers in the BYE:

1. The mapping must be configured on the trunk, not just set as attributes.

attributes_to_headers is a trunk-level configuration (on the inbound or outbound trunk), not something you set per-call. You need to configure it when creating/updating the trunk. For example, on your inbound trunk:

json

{
  "trunk": {
    "name": "My Five9 trunk",
    "numbers": ["+15105550100"],
    "headers_to_attributes": {
      "X-Five9-Session-Id": "five9IvaSessionId"
    },
    "attributes_to_headers": {
      "five9RouteType": "X-Five9-Route-Type",
      "five9RouteValue": "X-Five9-Route-Value",
      "five9Queue": "X-Five9-Queue",
      "five9IvaSessionId": "X-Five9-Iva-Session-Id",
      "five9PersonId": "X-Five9-Person-Id",
      "five9Language": "X-Five9-Language",
      "five9TransferReason": "X-Five9-Transfer-Reason"
    }
  }
}

The keys are the attribute names (matching what you set on the participant), and the values are the SIP header names (must be X-* headers).

2. Timing matters — set attributes before the call ends.

Your code updates attributes via update_participant which is correct. Just make sure you’re doing it before the call is terminated (before the BYE is sent). The SIP server reads the participant’s attributes when it constructs the BYE.

3. Verify your trunk configuration.

Use the LiveKit CLI or API to inspect your trunk and confirm attributes_to_headers is actually set:

bash

lk sip inbound list   # or outbound list

4. Check SIP server version.

The attributes_to_headers feature was added relatively recently. If you’re self-hosting on EKS, make sure your LiveKit SIP server image is up to date. The fix to ensure attributes are available during BYE (issue #404) was merged into later versions.

5. Kamailio may be stripping headers.

If LiveKit is sending the headers but Kamailio sits between LiveKit and Five9, check whether Kamailio’s routing rules are stripping unknown X-* headers from the BYE. You may need to add passthrough rules in your Kamailio config for those specific headers.

In summary, your approach of setting attributes and then relying on attributes_to_headers them is the correct pattern. The most likely issues are either the trunk not having the attributes_to_headers mapping configured, a SIP server version that predates the feature/fix, or an intermediary (Kamailio) stripping the headers.

Sources:

Thank you for quick reply.

I have already set trunk with attributes_to_headers mapping, but not sure how that will look like in lk sip inbound list command. currently getting only headers_to_attributes names there.

For SIP server version, I am pulling latest version.

I am suspecting Kamailio is stripping headers, However I have checked this point before also to remove headers changing part.

Is there any good way to test these things ?I am running sngrep commands for checking sip ladder in each pods.

What do you mean by that? Is this a self-hosted LiveKit server? I am not sure if that is a feature in Self hosted or not. That is a pretty new feature in LiveKit cloud and I am not sure if it has made its way to Self hosted distro yet.

Thank you for you response!

We would like to confirm our current deployment setup and validate compatibility.

We have deployed both the LiveKit server and LiveKit SIP server in a self-hosted environment on Amazon EKS. The deployment is using the below available container images:

  • LiveKit Server: livekit/livekit-server:v1.9.12

  • LiveKit SIP Server: livekit/sip:v1.2.0

Could you please confirm whether the versions we are using — LiveKit Server v1.9.12 and LiveKit SIP v1.2.0 — fully support the attributes_to_headers functionality, particularly for propagating participant attributes into SIP headers during BYE requests?

Also, we noticed issue #404 is still open, but a related fix in #540 has been merged — could you please confirm if the functionality is expected to be working now?

This confirmation will help us plan further troubleshooting and stabilization efforts accordingly.

Thank you in advance for your guidance.

Sorry, I am not familiar with the self-hosted functionality. I think you should be able to find the information you are looking for here: