WhatsApp Voice Call Not Ringing? Troubleshoot from preparing to Connected
If creating a WhatsApp voice call returns 201 but the recipient’s phone does not ring, first find the last stage you can confirm. A response with state: preparing means the browser link is ready; it does not mean dialing has started. Repeating the create request can make the original attempt harder to trace.
This guide covers UnifyPort’s private-beta, human-initiated, one-to-one outbound voice calls through an unofficial interface. It is not a Meta WhatsApp Business Calling API guide. For initial setup and complete request examples, use the voice-call integration tutorial. Here, the goal is to locate a failure using evidence already available in your application.
1. Identify what your evidence actually proves
| Evidence | What it establishes | What it does not establish |
|---|---|---|
Create returns 201 and preparing | A call link was prepared | Dialing, ringing or connection |
Current-call query returns active | A managed call is currently connected | Its webhook reached your application |
You receive call.answered | The corresponding call connected | Your support ticket was updated |
You receive call.ended | The corresponding call ended | Zero duration means it was unanswered |
Current-call query returns data: {} | No current UnifyPort-managed call was found | The outcome of an earlier call or mobile-app availability |
Match the workspace, account_id and call identifier before combining these observations. API responses use call_id; call events use data.call.id. A different operator may have started another call on the same messaging account.
2. Created successfully, but no ringing
Check these points in order against the create-call contract:
- Confirm that your application selected the intended authorized WhatsApp messaging account and that its
runtime_statusisrunning. - Check the saved request:
to.idmust be the returnedconversation_idfrom that account,to.typemust beuser, andmedia_typemust bevoice. A phone-number string is not a substitute. - Compare the current time with the returned
expires_at. Preparation lasts two minutes from creation by default, but the server can adjust it. This deadline does not cap the duration of a connected call. - Confirm that the assigned agent opened the private, single-use
join_urland clicked Start call before expiry. Opening the page alone does not start dialing. Microphone permission is required; camera permission is optional. Permission being granted is not connection evidence.
If the link expired, do not reuse it. Query the current call before deliberately preparing a new attempt. If these checks pass but ringing still cannot be confirmed, preserve the request and browser evidence; do not label the cause as a recipient, browser or network failure without supporting evidence.
3. A timeout or conflict leaves the result uncertain
A create-request timeout is an unknown result, not proof that nothing was created. For a conflict response, retain the actual error body instead of assuming every conflict has the same cause. Use the read-only current-call query on your server:
curl 'https://api.unifyport.ai/v1/calls/active?account_id=acc_example' \
-H 'X-Api-Key: <YOUR_API_KEY>'
A connected outbound voice call can return:
{
"request_id": "req_example",
"data": {
"call_id": "call_example",
"state": "active",
"direction": "outbound",
"media_type": "voice"
}
}
No current managed call returns:
{
"request_id": "req_example",
"data": {}
}
The query can also report preparing, dialing, ringing or connecting; do not assume every attempt passes through every state. It does not restore a lost call link, provide call history, or detect whether either party is busy in the WhatsApp mobile app. A failed query must not be treated as an empty successful response.
Compare any returned identifier with your own call-to-ticket mapping. Do not automatically create another call, or hang up an unfamiliar call to clear the account. If the result remains uncertain, reconcile it with the agent before retrying. For an intentional hangup, both ended and failed are terminal response states; failed alone is not a reason to keep sending hangup requests.
4. The call connected, but the callback is missing
Follow the path from eligibility to your application’s stored state:
- Eligibility:
is_betais a read-only workspace flag enabled by support. A wildcard subscription does not grant beta access; an ineligible workspace receives403 beta_feature_not_enabledwhen explicitly subscribing to call events. - Subscription: for an eligible workspace,
subscribed_eventsmust include the needed event names, or*, or be empty or omitted. An explicit list includes only the listed events. Check both answered and ended. - Delivery: check the configured endpoint URL and status, receiver access logs and HTTP responses. A
2xxacknowledges delivery; it does not prove a support-ticket update succeeded. - Processing: follow the delivery and signature guide. With
signing_secretconfigured, verifyX-Device-SignatureusingX-Device-Timestampand the raw request body. Check eventiddeduplication, persistence and call-to-ticket association separately.
Delivery is not ordered. Preserve connection evidence when an answered event arrives after an ended event, but do not reopen a terminal call in your UI. Missing callbacks alone cannot establish that the call never connected.
5. Zero seconds and empty results need context
duration_seconds measures connected time rounded down to whole seconds. Zero therefore does not prove the call was unanswered. Keep answered-event evidence alongside the end reason. A synchronous creation failure may produce no ended event, so do not leave every failed create waiting indefinitely for a callback.
For a hypothetical troubleshooting example, suppose an agent starts a prepared call, the current-call query shows it connected, and the receiver stores an answered event, but the ticket still says “waiting.” The next check is your application’s association and state update. Redialing would not repair that record. If a later query is empty, it cannot reconstruct the missing history; use your saved events and requests.
6. Collect a useful escalation record
Record the workspace, messaging account, conversation and call identifiers, the request_id, UTC timestamps, redacted responses, the agent’s action and permission state, and available receiver logs. Label each point as confirmed or unknown. Exclude API keys, signing secrets and complete private call links from screenshots and shared logs.
Send that record to technical support if the remaining gap cannot be resolved. This guide does not imply support for incoming or group calls, recording, transcription, SIP/PBX integration or autonomous AI calling.
Turn messaging integration into a stable product pipeline.
Start by sending through one API, then bring every inbound message back into your business system with standard events.