Integration Examples
Updated: Dec 10, 2025 This guide explains integration of common VoIP platforms with WhatsApp Business Calling API. This guide is for information purposes only with no support or warranties of any kind from Meta or any vendor. There are many ways to integrate and the guide explains just one way exclusively for illustrative purposes.Asterisk using SIP
Overview
This guide explains how to set up WhatsApp Business Calling API using SIP signaling with Asterisk, an open-source PBX (Private Branch Exchange). You’ll learn how to configure your Asterisk server, connect SIP phones, and handle both incoming and outgoing WhatsApp calls.User-Initiated Calls
The WhatsApp user dials the business number. The call is received by Asterisk and routed through an IVR, prompting the user to enter an extension, registered to the same Asterisk server. The call is then connected to the specified extension.Business-Initiated Calls
The business agent/user registers with Asterisk using SIP credentials (see “ Configuring a VoIP Phone” section). The business user dials the b2c-sip (business to consumer) extension, which is handled by an IVR. The IVR prompts for the WhatsApp number to call. The call is then connected to the WhatsApp user. WA - Asterisk leg will be using SDES for media encryption key exchange and opus for audio codec Asterisk - Sip UA will be using SDES for media encryption key exchange and opus or G711 for audio codecPrerequisites
Asterisk Deployment: Asterisk is deployed (ex: on a public cloud instance) Operating System: Any OS compatible for Asterisk. Ex: CentOS 9 Domain: Asterisk server is reachable via a public domain with valid certificate WhatsApp Business API: A WhatsApp business phone number is registered and calling is enabled. SIP Support: SIP is enabled on the WhatsApp Business Number SDES: SDES is enabled on the WhatsApp Business NumberBuilding and Installing Asterisk
Refer to https://docs.asterisk.org/Getting-Started/Installing-Asterisk/Installing-Asterisk-From-Source/Building-and-Installing-Asterisk/ This guide was tested using Asterisk version 22.5.2Asterisk Configuration
These configuration files are placed under /etc/asterisk/extensions.conf
Replace the following placeholders with actual values : WhatsApp Business Phone Number : DNS name of your Asterisk SIP server incoming_welcome: incoming_welcome.wav (not provided) place this file under /var/lib/asterisk/sounds outgoing_welcome: outgoing_welcome.wav (not provided) place this file under /var/lib/asterisk/soundsPjsip.conf
Replace the following placeholders with actual values : the business phone number : local network of the Asterisk server : Public IP of the Asterisk server media : Public IP of the Asterisk server signaling : Chosen SIP User Agent password : domain name assigned to the Asterisk server Certificate files should be placed under /var/lib/asterisk/certs/fullchain.cer /var/lib/asterisk/certs/cer.keyrtp.conf
Configuring a VoIP Phone
Download and install a softphone client (ex: Linphone) for testing both business-initiated and user-initiated calls.Account Setup
Select an extension to register as a SIP UA (extensions 1001–1005). Open Preferences. Under “SIP Accounts,” click “Add account.” Enter the following details: SIP Address: e.g., sip:1001@ SIP Server Address: e.g., sip:;transport=tls Transport: TLS Disable ICE Enable AVPF Disable “Publish presence information” Confirm and save the account. Enter the password when prompted (viz. ) Once connected, return to Preferences and select the “Audio” tab. Enable all audio codecs. In the “Calls and Chat” tab: Select “Encryption” Choose “SRTP-SDES” Enable “Encryption is mandatory” Confirm settingsFinal Checklist
Double-check all configuration files for correct numbers, passwords, and domain names. Make sure your firewall allows SIP (5061/TLS) and RTP (10000-20000) ports. For more details on SIP password setup, see the WhatsApp Cloud API documentation.Troubleshooting
Cannot register SIP UA
Confirm that the SIP URL is correct and the domain is pointing to the Asterisk server. Run host to verify that the ip address is pointing to the Asterisk serverNot receiving ACK from Meta
For a user initiated call, Meta sends aSIP INVITE to your SIP server which then responds with 200 OK. Meta acks your 200 OK with an ACK but you never receive this ACK. So your SIP server keeps resending the 200 OK and ultimately the SIP dialog is terminated due to ACK timeout (typically 32s).
The most likely cause for this problem is incorrect Record-Route headers in your 200 OK to Meta. The 200 OK response is supposed to not modify the Record-Route headers included in the original INVITE. It can add new Record-Route headers but cannot modify those present in the INVITE
The solution to this problem is to change rewrite_contact=yes to rewrite_contact=no on the WhatsApp endpoint configuration in pjsip.conf file. After this make sure your 200 OK has following headers as the last 2 in the list of Record-Route headers
FreeSWITCH using SIP
Overview
This guide explains how to set up WhatsApp Business Calling API using SIP signaling with FreeSWITCH, an open-source communication framework. You’ll learn how to configure your FreeSWITCH server, connect SIP phones, and handle both user-initiated and business-initiated WhatsApp calls.User-Initiated Calls
The WhatsApp user dials the business number. The call is received by FreeSWITCH and routed through an IVR, which prompts the user to enter an agent’s extension registered on the same Freeswitch server. Once the extension is entered, the call is connected to the specified recipient agent.Business-Initiated Calls
The business agent or user registers with FreeSWITCH using SIP credentials (see the Configuring a VoIP Phone section for details). The business user dials the b2c-sip (business-to-consumer) extension, which is managed by an IVR. The IVR then prompts for the WhatsApp number to call. After the number is entered, the call is connected to the WhatsApp user via SIP WA - FreeSWITCH leg uses SDES for media encryption key exchange with Opus as the audio code. FreeSWITCH - SIP UA leg uses SDES for media encryption key exchange with Opus or G.711 audio codecsPrerequisites
FreeSWITCH Deployment: FreeSWITCH is deployed (ex: on a public cloud instance) Operating System: Any OS compatible with FreeSWITCH. Ex: CentOS 9 Domain: FreeSWITCH server is reachable via a public domain with a valid certificate WhatsApp Business API: A WhatsApp business phone number is registered and calling is enabled. SIP Support: SIP is enabled on the WhatsApp Business Number Note: FreeSWITCH is configured to listen on 5081 for TLS SDES: SDES is enabled on the WhatsApp Business NumberBuilding and Installing FreeSWITCH
Refer to https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Installation/ This guide was tested using FreeSWITCH version 1.10.12. FreeSWITCH uses sofia (an open-source SIP user agent library). Sofia v1.13.17 was used for this guideFreeSWITCH Configuration
These configuration files are placed under /usr/share/freeswitch/etc/freeswitch wa-biz-api-dialplan.xml Place the dial plan under /usr/share/freeswitch/etc/freeswitch/dialplan/default/wa-biz-api-dialplan.xmlnetwork-lists element
Final Checklist
Double-check all configuration files for correct numbers, passwords, and domain names. Make sure your firewall allows SIP (5081/TLS) and RTP (10000-20000) ports. For more details on SIP password setup, see the WhatsApp Cloud API documentation.Troubleshooting
Cannot register SIP UA
Confirm that the SIP URL is correct and the domain is pointing to the Freeswitch server. Run host to verify that the ip address is pointing to the Freeswitch serverTrace SIP messages
Start cli (/usr/share/freeswitch/bin/fs_cli) to view SIP messagesFreeSWITCH using Graph API with Janus
Overview
This guide explains how to set up WhatsApp Business Calling API using WhatsApp Cloud API signaling with FreeSWITCH, an open-source communication framework and Janus, a general purpose WebRTC server. You’ll learn how to configure your FreeSWITCH server, connect SIP phones, and handle both incoming and outgoing WhatsApp calls.
User-Initiated Calls
The WhatsApp user dials the business number. The call is received by Webhook server which forwards it to FreeSWITCH server via Janus SIP plugin. The call is received by FreeSWITCH and routed through an IVR, prompting the user to enter an extension, registered to the same FreeSWITCH server. The call is then connected to the specified extension.Business-Initiated Calls
The business agent/user registers with FreeSWITCH using SIP credentials (see “ Configuring a VoIP Phone” section). The business user dials the b2c-sip (business to consumer) extension, which is handled by an IVR. The IVR prompts for the WhatsApp number to call. FreeSWITCH bridges the call to extension registered to Janus SIP plugin which translates it to an API request to Meta The call is then connected to the WhatsApp user. Janus server sits between WA and FreeSWITCH and will convert media from WA (WebRTC complaint with DTLS key exchange) to FreeSWITCH negotiated media (SDES key exchange) FreeSWITCH - Sip UA will be using SDES for media encryption key exchange and opus or G711 for audio codecPrerequisites
FreeSWITCH Deployment: FreeSWITCH is deployed (ex: on a public cloud instance) Janus Deployment: Can be deployed on the same machine as FreeSWITCH Operating System: Any OS compatible with FreeSWITCH. Ex: CentOS 9 Domain: FreeSWITCH server and Webhook server are reachable via a public domain with valid certificate WhatsApp Business API: A WhatsApp business phone number is registered and calling is enabled. Webhooks: Configure Webhook callback URL pointing to domain name of the Webhook serverIntegration with Cloud API Signaling
You will need to implement an integration module which sits between WA and Janus and translates Cloud API Signalling messages to Janus SIP plugin messages and vice versa. You will need A webhook server to receive calls webhook events from Meta A Graph API module to send call messages to Meta An implementation of Janus SIP plugin to connect to Janus. The Janus plugin implementation will connect to FreeSWITCH using extension 1000 which is reserved for bridging Business initiated calls The module will receive a SIP INVITE via Janus SIP plugin on extension 1000. The SIP INVITE is converted to a Graph API request. The SDP received in the SIP INVITE is sent verbatim as the SDP offer to WA via the Graph API call When the call is accepted by the WA user, an accepted webhook is received. On receiving the webhook, the Janus SIP Plugin accepts the SIP INVITE passing the answer SDP in the connect webhook User Initiated calls The webhook server receives an incoming call via a webhook message containing the offer SDP. On receiving the call invite, the Janus SIP plugin sends an invite to FreeSWITCH via extension 1000. The destination extension is c2b-sip. When the the Janus SIP plugin receives the SIP 200 OK, a Graph API accept call request is sent to Meta to accept the incoming call by passing the SDP received as part of SIP answerBuilding and Installing Janus
Refer to https://github.com/meetecho/janus-gateway This guide was tested using version 1.2.3Janus Configuration
janus.jcfg Modify janus.jcfg which can be found at /usr/share/janus/etc/janus/janus.jcfg Set nat_1_1_mapping to the public ip of the Janus Server To start janusBuilding and Installing FreeSWITCH
Refer to https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Installation/ This guide was tested using FreeSWITCH version 1.10.12. FreeSWITCH uses sofia (an open-source SIP user agent library). Sofia v1.13.17 was used for this guide FreeSWITCH Configuration These configuration files are placed under /usr/share/freeswitch/etc/freeswitch wa-biz-api-dialplan.xml Place the dial plan under /usr/share/freeswitch/etc/freeswitch/dialplan/default/wa-biz-api-dialplan.xmlConfiguring a VoIP Phone
Refer to the earlier sectionFinal Checklist
Double-check all configuration files for correct numbers, passwords, and domain names. Make sure your firewall allows SIP (5061/TLS) and RTP (10000-20000) ports. For more details on SIP password setup, see the WhatsApp Cloud API documentation.Troubleshooting
Cannot register SIP UA
Confirm that the SIP URL is correct and the domain is pointing to the FreeSWITCH server. Run host to verify that the ip address is pointing to the FreeSWITCH serverTrace SIP messages
Start cli (/usr/share/freeswitch/bin/fs_cli) to view SIP messagesAsterisk using Graph API with RtpEngine
Overview
This guide explains how to set up WhatsApp Business Calling API using WhatsApp Cloud API signaling with Asterisk, an open-source PBX (Private Branch Exchange) and RtpEngine, an open-source proxy used for relaying, manipulating and controlling RTP streams. You’ll learn how to configure your Asterisk server, connect SIP phones, and handle both incoming and outgoing WhatsApp calls.User-Initiated Calls
The WhatsApp user dials the business number. The call is received by the Webhook server which after bridging media using RtpEngine, forwards it to Asterisk using SIP. The call is received by Asterisk and routed through an IVR, prompting the user to enter an extension, registered to the same Asterisk server. The call is then connected to the specified extension.Business-Initiated Calls
The business agent/user registers with Asterisk using SIP credentials (see “ Configuring a VoIP Phone” section). The business user dials the b2c-sip (business to consumer) extension, which is handled by an IVR. The IVR prompts for the WhatsApp number to call. Asterisk bridges the call to extension registered by the integration module (see “Integration with Cloud API Signalling”) On receiving the call, the integration module bridges the media using RtpEngine and then translates it to an API request to Meta The call is then connected to the WhatsApp user. RtpEngine acts as a media proxy and sits between the media stream of WA (WebRTC complaint with DTLS key exchange) and Asterisk (SDES key exchange)Prerequisites
Asterisk Deployment: Asterisk is deployed (ex: on a public cloud instance) RtpEngine Deployment: Can be deployed on the same machine as Asterisk Operating System: Any OS compatible with Asterisk and RtpEngine. Ex: CentOS 9 Domain: Asterisk server and Webhook server are reachable via a public domain with valid certificate WhatsApp Business API: A WhatsApp business phone number is registered and calling is enabled. Webhooks: Configure Webhook callback URL pointing to domain name of the Webhook serverIntegration with Cloud API Signaling
You will need to implement an integration module that acts as a bridge between WhatsApp and Asterisk. This module will: Translate Cloud API Signaling messages from WhatsApp to SIP for Asterisk, and vice versa Use SIP signaling for communication between the SIP UA inside the module and Asterisk Bridge the media between WhatsApp and Asterisk via RtpEngine You will need following components, which are part of the integration module for the purpose of this setup Webhook Server: Receives call webhook events from Meta (WhatsApp Cloud API) Graph API client: Sends call-related requests to Meta using the Graph API SIP User Agent (UA) such as PJSIP: Connects to Asterisk using extension 1000, which is reserved for bridging calls between WhatsApp and Asterisk. RtpEngineClient: To control RtpEngine via ng control protocol for bridging media
Business initiated calls
Business agent registered to the same Asterisk server dials b2c-sip extension to initiate a call to WhatsApp user
The extension prompts the business agent to enter WA user’s phone number
Asterisk sends a SIP INVITE request to extension 1000 with a custom header containing the dialed WA user phone number
The SIP UA inside the module would’ve registered at extension 1000 and hence receives the SIP INVITE from Asterisk
The SDP included in the SIP INVITE is sent to RtpEngine which returns a new SDP
The new SDP is included in the Graph API request to initiate a new call
When the WhatsApp user accepts the call, an “accepted” webhook is received
Upon receiving this webhook, the answer SDP received in the webhook is sent to RtpEngine which returns a new SDP
The SIP UA accepts the original SIP INVITE (step 3), passing along the new SDP received from RtpEngine
The call is now bridged between WA user, RtpEngine and Asterisk
User Initiated calls
The webhook server inside the module receives an incoming call webhook from Meta, which includes the offer SDP
Upon receiving this call invite, the SDP included in the offer is sent to RtpEngine which returns a new SDP
The SIP UA inside the module sends a SIP INVITE to Asterisk using extension 1000 passing the new SDP from RtpEngine in the SIP INVITE. The destination extension is c2b-sip.
The extension prompts WA user to dial the extension of the business agent to connect to
Asterisk dials the specified extension and waits for an answer
After the agent answers the call, Asterisk sends SIP 200 OK to the SIP UA extension 1000 inside the module. The SDP in SIP 200 OK is sent to RtpEngine which returns a new SDP
A Graph API request is sent to Meta to accept the incoming call, with the new SDP received from RtpEngine

