← All posts
Guide

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

EvidenceWhat it establishesWhat it does not establish
Create returns 201 and preparingA call link was preparedDialing, ringing or connection
Current-call query returns activeA managed call is currently connectedIts webhook reached your application
You receive call.answeredThe corresponding call connectedYour support ticket was updated
You receive call.endedThe corresponding call endedZero duration means it was unanswered
Current-call query returns data: {}No current UnifyPort-managed call was foundThe 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:

  1. Confirm that your application selected the intended authorized WhatsApp messaging account and that its runtime_status is running.
  2. Check the saved request: to.id must be the returned conversation_id from that account, to.type must be user, and media_type must be voice. A phone-number string is not a substitute.
  3. 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.
  4. Confirm that the assigned agent opened the private, single-use join_url and 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_beta is a read-only workspace flag enabled by support. A wildcard subscription does not grant beta access; an ineligible workspace receives 403 beta_feature_not_enabled when explicitly subscribing to call events.
  • Subscription: for an eligible workspace, subscribed_events must 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 2xx acknowledges delivery; it does not prove a support-ticket update succeeded.
  • Processing: follow the delivery and signature guide. With signing_secret configured, verify X-Device-Signature using X-Device-Timestamp and the raw request body. Check event id deduplication, 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.

UnifyPort API

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.