# Outbound SIP via Plivo Zentrunk: callee hears complete silence for the whole call while the agent receives the caller's audio fine (200 OK, PCMU negotiated, agent track publishing 298 KB)

**URL:** <https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010>\
**Category:** Telephony\
**Tags:** sip-trunking, livekit-cloud\
**Created:** [September 6, 2026, 2:21pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010 "2026-09-06T14:21:47Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gurbir\_Singh](https://sea1.discourse-cdn.com/flex001/user_avatar/community.livekit.io/gurbir_singh/32/2451_2.png) [@Gurbir\_Singh](https://community.livekit.io/u/Gurbir_Singh)\
**Post date:** [September 6, 2026, 2:21pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/1 "2026-09-06T14:21:47Z")

</div>

Outbound SIP call via Plivo Zentrunk. Agent audio is confirmed good (published track, 298 KB upstream, SIP participant received 141 KB downstream, 0% packet loss) but the callee hears complete silence for the entire call. Inbound audio works — the agent transcribes the caller correctly. SIP response 200, codec PCMU/8000, TLS signaling, India region.

Call ID: `SCL_vnNa6E33QroX`  
Session: `aicall-6a9d43700e4d242821a0bf18`  
Trunk: `ST_Dic82uX53bAt`  
Provider call ID: `eV6HufDwu8rhhsiMM7iUQ5VvD0i`  
Time: 6 Sept 2026, 16:12:01 IST

PCAP shows as unavailable on the call page. Could you check whether RTP was sent toward Plivo for this call, and whether the Opus→PCMU transcode succeeded?

Plivo’s CDR reports codec G722 while the LiveKit call page shows PCMU/8000.

---

<div class="post-metadata">

**Author:** ![abidullahcs.uk](https://avatars.discourse-cdn.com/v4/letter/a/ba8739/32.png) [@abidullahcs.uk](https://community.livekit.io/u/abidullahcs.uk)\
**Post date:** [September 6, 2026, 4:17pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/2 "2026-09-06T16:17:39Z")

</div>

@Gurbir_Singh That codec discrepancy you spotted is the most likely cause, and worth chasing before the RTP question.

LiveKit SIP offers PCMU, PCMA and G722 by default. So if Plivo’s CDR says G722 while the LiveKit call page says PCMU, the two ends disagree about what is in the stream. The docs are explicit about what that produces: “the call might connect, but audio exchange fails between endpoints or requires an external service to transcode the audio.” That matches your symptoms exactly, including healthy byte counts and 0% loss, since packets flow fine when only the decode is wrong.

Quick test, pin the offer to PCMU on the outbound trunk or on CreateSIPParticipant:

```auto

  {
    "media": {
      "onlyListedCodecs": true,
      "codecs": [{ "name": "PCMU" }]
    }
  }

```

If the callee starts hearing audio, that was it.

The rest of what you asked, whether RTP actually left toward Plivo and why the PCAP shows unavailable, needs server-side visibility. That part is one for LiveKit staff with your call ID.

---

<div class="post-metadata">

**Author:** ![Gurbir\_Singh](https://sea1.discourse-cdn.com/flex001/user_avatar/community.livekit.io/gurbir_singh/32/2451_2.png) [@Gurbir\_Singh](https://community.livekit.io/u/Gurbir_Singh)\
**Post date:** [September 6, 2026, 6:52pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/3 "2026-09-06T18:52:51Z")

</div>

Thank you @abidullahcs.uk . That’s a very useful pointer, and the onlyListedCodecs option looks like exactly the right thing to try. I’ll pin the outbound trunk to PCMU and report back with the result.

One detail that may narrow it further: I pulled the SIP PCAP from Plivo’s side, and the Plivo↔carrier leg negotiates cleanly - Plivo offers RTP/AVP 8 0 101, the carrier answers RTP / AVP 0 8 101 (PCMU first), both sendrecv, valid port, 0% loss reported on the LiveKit side. So the disagreement isn’t on that leg. It has to be on the LiveKit↔Plivo leg, which is where Plivo’s CDR reports G722 while the LiveKit call page shows PCMU/8000 for the same call.

That also matches livekit/sip#95, where LiveKit’s SDP answered with m=audio … RTP/AVP 0 while still sending a=rtpmap:9 G722/8000 - an m-line and rtpmap that disagree. Packets flow, the decode is wrong, and you get exactly what we see: healthy byte counts and total silence.

Two things I’d still value your view on:

1. If pinning to PCMU fixes it, is the underlying issue worth reporting - a default codec set that can produce a mismatch against a provider that itself negotiates correctly?
2. On the ordering side, the PCAP shows 183 Session Progress with P-Early-Media: sendonly at 16:11:59.42 and 200 OK at 16:12:01.11, while our worker considered the call answered at 16:11:56. Is waitUntilAnswered on CreateSIPParticipant the intended gate for “don’t speak yet”, or is watching sip.callStatus reach active the more reliable signal? We’re fixing that side regardless.

---

<div class="post-metadata">

**Author:** ![abidullahcs.uk](https://avatars.discourse-cdn.com/v4/letter/a/ba8739/32.png) [@abidullahcs.uk](https://community.livekit.io/u/abidullahcs.uk)\
**Post date:** [September 6, 2026, 6:59pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/4 "2026-09-06T18:59:38Z")

</div>

Glad that helped @Gurbir_Singh, and thanks for pulling the PCAP, that narrows it a lot.

On whether to report it, worth checking your reference first. sip#95 ([Codec negotiation issue · Issue #95 · livekit/sip · GitHub](https://github.com/livekit/sip/issues/95)) was closed by PR #97 ([Fix SDP codec selection by dennwc · Pull Request #97 · livekit/sip · GitHub](https://github.com/livekit/sip/pull/97)) back in May 2024, so that m-line/rtpmap disagreement got fixed a while ago. A report leaning on it will probably  
just get closed as already fixed.

What would make it stick is the piece you don’t have yet. Your PCAP covers Plivo↔carrier and clears that leg nicely. The disagreement is on LiveKit↔Plivo, so it’s the SDP for that leg you want, and Plivo support can usually pull it. With that you’ve got a real report. Without it, it’s a CDR field disagreeing with a dashboard.

On the gating, they’re not alternatives, the SDK leans on both. From the AMD docstring in voice/amd/detector.py:

> For SIP participants, the no-speech timer and audio/transcript processing are deferred until sip.callStatus == “active” so pre-answer audio (ringback, carrier early media, dialtone) does not poison the classifier or burn the no-speech budget.

And its recommended pattern still passes wait\_until\_answered=True. So one gates when the API call returns, the other is what the framework itself trusts before touching media. Your 183 with P-Early-Media: sendonly is precisely the case that docstring is describing, so I’d use both.

One small thing from your timeline: your worker called it answered at 16:11:56, ahead of the 183 at 16:11:59.42 and the 200 OK at 16:12:01.11. Whatever it’s keying on there isn’t either of them.

---

<div class="post-metadata">

**Author:** ![Gurbir\_Singh](https://sea1.discourse-cdn.com/flex001/user_avatar/community.livekit.io/gurbir_singh/32/2451_2.png) [@Gurbir\_Singh](https://community.livekit.io/u/Gurbir_Singh)\
**Post date:** [September 6, 2026, 7:27pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/5 "2026-09-06T19:27:28Z")

</div>

Fair correction on sip#95 - I’d checked the issue and not its close state. Good to know it’s long fixed.

I’ve asked Plivo for the LiveKit-facing leg’s SDP. Agreed that without it there’s no report worth filing, just two dashboards disagreeing.

The gating answer is the useful part - thank you. Deferring media handling until sip.callStatus == “active” while still passing waitUntilAnswered is exactly the shape I needed, and your point that our 16:11:56 lines up with neither the 183 nor the 200 OK is right. It’s keying on something else entirely, most likely the SIP participant joining the room, which happens well before the carrier answers. That’s the bug on our side and it’s being fixed now.

I’ll report back with the PCMU pin result and the LiveKit-side SDP once Plivo sends it.

---

<div class="post-metadata">

**Author:** ![abidullahcs.uk](https://avatars.discourse-cdn.com/v4/letter/a/ba8739/32.png) [@abidullahcs.uk](https://community.livekit.io/u/abidullahcs.uk)\
**Post date:** [September 6, 2026, 9:03pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/6 "2026-09-06T21:03:09Z")

</div>

That lines up @Gurbir_Singh. Room join and carrier answer are two different moments, and it’s an easy one to conflate, so good catch on your side.

Please do report back, I’d be interested to see what that SDP turns up.

---

<div class="post-metadata">

**Author:** ![CWilson](https://sea1.discourse-cdn.com/flex001/user_avatar/community.livekit.io/cwilson/32/135_2.png) [@CWilson](https://community.livekit.io/u/CWilson)\
**Post date:** [September 8, 2026, 2:41pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/7 "2026-09-08T14:41:41Z")

</div>

Do you have a PCAP for the call? You can get one from LiveKit side if you disable TLS and try it. You will see the PCAP on your dashboard for that call.

---

<div class="post-metadata">

**Author:** ![Gurbir\_Singh](https://sea1.discourse-cdn.com/flex001/user_avatar/community.livekit.io/gurbir_singh/32/2451_2.png) [@Gurbir\_Singh](https://community.livekit.io/u/Gurbir_Singh)\
**Post date:** [September 8, 2026, 5:26pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/8 "2026-09-08T17:26:13Z")

</div>

Thanks @CWilson

that explains the blank PCAP field: our trunk uses TLS signaling, so there’s nothing capturable. I’ll try a plain-signaling call to get one, but not yet - I’ve just pinned the offer to PCMU only via CreateSIPParticipant’s media config, and I want that tested in isolation before changing a second variable.

---

<div class="post-metadata">

**Author:** ![Gurbir\_Singh](https://sea1.discourse-cdn.com/flex001/user_avatar/community.livekit.io/gurbir_singh/32/2451_2.png) [@Gurbir\_Singh](https://community.livekit.io/u/Gurbir_Singh)\
**Post date:** [September 8, 2026, 5:56pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/9 "2026-09-08T17:56:25Z")

</div>

@abidullahcs.uk - will do. If the PCMU pin doesn’t fix it, the TLS-off PCAP is exactly what gets us the LiveKit-facing SDP that Plivo support hasn’t sent yet, and I’ll post what it shows.

Two notes for anyone who finds this thread later:  
SIPMediaConfig in livekit-server-sdk@2.17.0 is a protobuf message class, not a plain object - passing an object literal type-errors rather than silently doing nothing, which is the failure mode you’d want here.

And on the timing: we already passed waitUntilAnswered: true. What was missing was the media-side half - deferring anything that produces audio until the sip.callStatus attribute reaches active. Those really are two separate gates, as you said.

---

<div class="post-metadata">

**Author:** ![abidullahcs.uk](https://avatars.discourse-cdn.com/v4/letter/a/ba8739/32.png) [@abidullahcs.uk](https://community.livekit.io/u/abidullahcs.uk)\
**Post date:** [September 8, 2026, 6:09pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/10 "2026-09-08T18:09:55Z")

</div>

@Gurbir_Singh Makes sense to keep those separate, the TLS-off call will still be there afterwards.

Worth having your SIPMediaConfig note in the thread. The docs show that block as JSON, which is what I pasted, so anyone on the typed SDK is going to hit exactly what you hit. Type-erroring beats a config that quietly does nothing.

Curious what the pin turns up.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex001/user_avatar/community.livekit.io/system/32/26_2.png) [@system](https://community.livekit.io/u/system)\
**Post date:** [September 10, 2026, 6:10pm UTC](https://community.livekit.io/t/outbound-sip-via-plivo-zentrunk-callee-hears-complete-silence-for-the-whole-call-while-the-agent-receives-the-callers-audio-fine-200-ok-pcmu-negotiated-agent-track-publishing-298-kb/2010/11 "2026-09-10T18:10:45Z")

</div>

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.
