PJSIP Settings for a WhatsApp SIP Bridge
The PJSIP settings for a WhatsApp bridge are shorter than most people expect — because the hard part, converting WhatsApp's audio, happens before the call ever reaches Asterisk. This post explains which pjsip.conf settings matter for the WhatsMCP bridge, why, and the handful of mistakes that cause most "the call connects but…" reports.
For the full walkthrough — linking the number by QR code, the console settings and the dialplan — follow Connect Asterisk to WhatsApp with a QR code.
Where the transcoding actually happens
WhatsApp carries voice as wideband Opus (and its newer codecs) inside its own encrypted transport. The WhatsMCP bridge terminates that, decodes it, and hands your PBX ordinary RTP in a codec every phone system speaks: G.722 first, then G.711 μ-law and A-law — payload types 9, 0 and 8. It does the reverse for audio going to WhatsApp.
So Asterisk doesn't transcode Opus at all. It doesn't need the codec_opus module, and the bridge never offers Opus on the SIP side. If your phones speak G.722 or G.711, Asterisk can pass the audio straight through.
Codec order: put what your phones speak first
[whatsapp]
type=endpoint
disallow=all
allow=g722,ulaw,alaw
- G.722 is wideband (16 kHz) and noticeably clearer than G.711. If your desk phones support it — most modern ones do — keep it first and the call stays wideband end to end.
- μ-law / A-law are the fallbacks. Put the one your phones use first among the two so Asterisk doesn't convert between them.
- Don't add
allow=opus. The bridge won't offer it, and a codec list with nothing in common ends in488 Not Acceptable Here.
If a phone only speaks G.711 while the bridge leg negotiates G.722, Asterisk converts between them. That's cheap, but it's still a conversion per call; matching codecs avoids it.
The bridge is an endpoint, not a provider trunk
The WhatsMCP bridge registers to your Asterisk with a username and password you create, exactly like a desk phone. So its configuration is an endpoint plus auth plus aor — not a registration section pointing at a provider.
[whatsapp]
type=auth
auth_type=userpass
username=whatsapp
password=a-long-random-password
[whatsapp]
type=aor
max_contacts=1
remove_existing=yes
qualify_frequency=60
[whatsapp]
type=endpoint
transport=transport-udp
context=from-whatsapp
disallow=all
allow=g722,ulaw,alaw
auth=whatsapp
aors=whatsapp
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
Name the endpoint after the username: Asterisk recognises the bridge's incoming calls by the username in them. max_contacts=1 with remove_existing=yes lets a re-registration replace the old contact cleanly. The bridge answers Asterisk's OPTIONS keep-alives, so qualify_frequency is safe and tells you quickly if it drops off.
The settings everyone forgets
direct_media=no. Without it Asterisk may try to send RTP directly between the bridge and the phone. Across the internet and NAT that rarely works, and the symptom is audio that works on the first test and fails in production.
The NAT trio: rtp_symmetric, force_rport, rewrite_contact. The bridge reaches Asterisk from the internet. These three make Asterisk reply to the address the packets actually came from, rather than whatever was written in the SIP headers. Combined with local_net and external_media_address / external_signaling_address on your transport, they prevent almost every one-way-audio problem.
An open RTP range. Open the range from rtp.conf (for example UDP 10000–20000) as well as 5060, and turn off SIP ALG on the router.
Concurrency: one call per WhatsApp number
Capacity here isn't set by CPU or by anything in pjsip.conf: each WhatsApp number carries one call at a time, and a second call to or from the same number gets 486 Busy Here. For more simultaneous calls, link more numbers — each gets its own bridge and its own endpoint — and spread them across a queue or ring group.
Because Asterisk isn't transcoding Opus, CPU per call stays low; a modest server handles many bridged numbers.
What doesn't cross the bridge
- DTMF. Keypad tones aren't passed to or from WhatsApp, whatever
dtmf_modesays. An IVR that waits for "press 1" won't hear a WhatsApp caller — use time-based routing, queues or speech instead. - Hold and transfer requests. The bridge doesn't accept re-INVITEs or REFER, so plan call handling inside Asterisk and test any transfer flow you depend on.
- Video. Voice only.
- SRTP. Audio to your own PBX is plain RTP, even when signalling uses TLS.
Quick checklist
-
allow=g722,ulaw,alaw— no Opus - Endpoint name = the bridge's username, with
authandaor -
direct_media=no,rtp_symmetric=yes,force_rport=yes,rewrite_contact=yes -
local_netandexternal_*set on the transport if Asterisk is behind NAT - UDP 5060 and the RTP range reachable from the internet; SIP ALG off
- Plan one call per WhatsApp number; no IVR that depends on keypad tones
Ready to set it up? Create a WhatsMCP workspace and follow the step-by-step Asterisk tutorial.
About WhatsMCP Engineering
Engineering Team at WhatsMCP. The team building WhatsMCP's MCP server and SIP bridge — the people who wrote the code these posts describe.