Receive WhatsApp calls
Once your WhatsApp number is connected and calling is turned on, a call to it is answered the same way as a call to a phone number. Follow Make and receive calls to build your handler, either via SWML or via WebSocket (Relay), with the differences on this page:
- Every handler that runs on a Resource can answer.
- You connect the WhatsApp number to the handler from the Resource, not from Phone Numbers.
- You test from the WhatsApp app, and check the number’s voice fields if nothing answers.
- Your business number arrives with a
whatsapp:prefix.
Before you start
You need a WhatsApp business number that shows Registered in your Space, from Connect a WhatsApp business number, with calling turned on from Enable voice on a WhatsApp number. To test, you also need a phone with WhatsApp installed that can call the business number.
To connect the number in code, you also need your Space URL, the number’s SignalWire id from
List WhatsApp numbers, and a Project ID and API token from the Dashboard’s
API credentials page with the Voice permission, plus Numbers to list your
WhatsApp numbers.
WhatsApp calls are audio only, can’t be placed on hold, and only arrive inbound. The overview’s What WhatsApp calling supports lists what works and what doesn’t before you build.
Choose a handler
Any handler from Make and receive calls that runs on a Resource can answer: a SWML Script, served from your server or hosted in SignalWire, or a Relay Application. An AI Agent, a Call Flow, or a Video Room can answer too, with a Video Room caller joining by audio only.
The Browser SDK can’t answer a WhatsApp call today, because a WhatsApp number can’t be attached to a Subscriber. The REST Calling API can’t answer one either, and can’t place calls to WhatsApp users.
Build the handler in Make and receive calls up to its assign step, then come back here. That guide’s assign steps, including the Assign the number in code samples, connect a phone number and don’t apply to a WhatsApp number, with two catches:
- Relay Application. The Assign the topic to your phone number step also creates the Relay Application. Follow its Dashboard steps to create it, then skip the phone number assignment. To create it in code instead, see Connect the WhatsApp number via the REST API.
- SWML Script served from your server. The From your server tab says you can skip its Dashboard steps because Assign the number in code creates the script. That doesn’t hold for a WhatsApp number, so create the script with the tab’s Dashboard steps.
Connect the WhatsApp number to the handler
This replaces the guide’s Assign the script to your phone number or Assign the topic to your phone number step.
Neither the Dashboard picker nor the API checks that calling is turned on. A number you assign before enabling voice gets a handler but still can’t take calls.
Connect the WhatsApp number via the Dashboard
In your SignalWire Dashboard, open the Resource you want to answer the call and select its Addresses & Phone Numbers tab. Select + Add, then Assign a WhatsApp Phone Number, and select Add beside the number.
The picker lists Registered WhatsApp numbers that don’t already have an Address in your Space, whether that Address is for calling or for messaging. To point a number at a different Resource, delete its existing Address first.
Connect the WhatsApp number via the REST API
The Server SDKs don’t cover this endpoint yet, so call it directly. Put the Resource’s id in the
path. The Create the hosted script in code samples print it; for any other Resource, find it with
List Resources.
To create a Relay Application in code, send a topic that matches the contexts value in your
Relay client. The response’s id goes in the path. Create Relay application lists
every field:
In the body of the assign request, pass the WhatsApp number’s id as
whatsapp_number_id with calling as the handler:
The response is the Address SignalWire created for the number on that Resource:
Unlike the Dashboard picker, the API accepts a number that already has a calling Address and re-points it at the new Resource. A WhatsApp number holds one Address at a time, though, so assigning a calling handler removes any messaging Address the number had. The Assign Resource to WhatsApp number reference lists every field and error.
Call the number from WhatsApp
Open a chat with your business in WhatsApp and tap the call button. You hear your handler’s greeting, such as “Hello, welcome to SignalWire!”, then the call ends.
If nothing answers, list your WhatsApp numbers and read two fields on yours:
voice_capable is true only when calling is enabled and a handler is attached. If it is false and
voice_enabled is also false, calling was never turned on or Meta refused a renewal;
Enable voice on a WhatsApp number covers both. If voice_enabled is true,
check calling_handler_resource_id in the same response. Null means the handler never attached, or
its Address was deleted since: connect the number again and check that response for errors.
If both fields are true and the call still fails, the handler itself is the problem. Use the
troubleshooting in the matching section of Make and receive calls, but skip its
checks of the number’s Inbound Call Settings, which a WhatsApp number doesn’t have. For a Relay
Application, check instead that the WhatsApp number is attached to it and that your client’s
contexts matches the Resource’s topic.
Read the caller and business numbers
When SignalWire runs your Resource, it hands over the call with your business number as to and the
caller’s number as from. Your business number carries a whatsapp: prefix. The caller’s number is
plain E.164, the phone number their WhatsApp account is registered to, so you can look a customer up
the same way you would on an inbound phone call.
For an AI Agent or SWML Script served by the Server SDKs, both numbers arrive in the
JSON body SignalWire POSTs to your server before the call starts, nested under call. On a WhatsApp
call, call.to is whatsapp:+15557654321 and call.from is +15551234567. The
inbound call webhook reference documents every field of that body:
Read the caller’s number via SWML
Because the prefix only appears on to, one agent can serve both a phone number and a WhatsApp
number and adjust to how the call came in. Register a dynamic configuration callback with
set_dynamic_config_callback in Python or
setDynamicConfigCallback in TypeScript. It runs once per call with the request
body and an ephemeral copy of the agent, so the WhatsApp-specific section applies to that call only:
This agent runs on your own server, so SignalWire has to reach its URL. Create a SWML Script Resource that uses an External URL pointing at the agent, as the From your server tab of Create the SWML Script shows, then connect the WhatsApp number to that Resource.
Past that point the call is an ordinary call. Recording, transcription, and the rest of SWML work as they do on a phone call, with the hold exception noted above.
Find the calls in your logs
Find WhatsApp calls via the Dashboard
WhatsApp calls appear alongside the rest of your voice traffic in your
SignalWire Dashboard under Logs → Voice. The To column shows the
whatsapp:-prefixed business number, which is the quickest way to pick them out.
Find WhatsApp calls via the Voice Logs API
The same records come back from the Voice Logs API. A WhatsApp call is logged as a Relay PSTN call
whose to is the whatsapp:-prefixed business number:
The endpoint filters by date rather than by number, so request the window you need and match to
against your business number. See List voice logs for the date filters and every
field.