Skip to main content

WhatsApp Calling API

WhatsApp Business voice/video call capability management Base path: /api/v1/whatsapp Endpoint count: 3

title: “Errors worth branching on” description: “Per-endpoint failure templates matching the envelope — what actually fires, what to retry, what to surface to the operator.”

Errors worth branching on

These five failures cover the call initiate (POST /api/v1/whatsapp-calling/calls), on every click-to-call. Each block below is a full { error, meta } envelope as the API returns it, and the matrix at the bottom answers retry vs surface for the same five classes. For the platform-wide decision table these branches plug into, see the error handling guide.

401 — Unauthorized

A 401 on this page is the bearer key failing before the route ran — it never means the resource is wrong. Rotate the key or re-mint the scoped token; retrying the same request changes nothing.

403 — Forbidden

A 403 means the key authenticated but the operation is gated by scope — check the key’s scopes on the developer page; a 403 is never a data-not-found shape.

422 — Schema

A 422 means the payload did not match the request schema — branch on error.details.field and resend with the MSISDN in E.164 form instead of blind-retrying the same body.

429 — Rate

The Retry-After header and error.details.retry_after are both set on every 429 — resend the SAME request after the lower of the two.

402 — Feature gate

Surface the WABA enablement screen; the voice fallback still works for the number.

60-second retry matrix


WhatsApp Business Calling KPIs

GET /api/v1/whatsapp/calling/analytics
Returns aggregated KPIs (totals, answered, declined, missed, failed, avg duration, total cost) plus a per-day call-volume trend over a configurable window (1-365 days, default 30).
string
—
string
—
integer
—
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List WhatsApp Business Call logs

GET /api/v1/whatsapp/calling/calls
Cursor-paginated list of wa_call_logs rows. Phone columns are masked for viewer/billing roles; owner/admin/developer see raw E.164. The q search covers phone + contact_name + conversation_id columns.
string
CSV of statuses to include. Allowed: queued, ringing, in_progress, completed, failed, missed.
string (enum: inbound|outbound)
—
string
—
string
—
string
—
string
—
string
—
string
—
integer
—
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Initiate an outbound WhatsApp Business Call (Phase 5)

POST /api/v1/whatsapp/calling/calls
Initiate a WhatsApp Business outbound call. Walks pre-flight gates: connection lookup + access-token decrypt, country block-list (WA_CALLING_BLOCKED_COUNTRIES), calling-enabled flag on the WABA, and recipient call-permission grant. Permission-missing returns 422 with code WHATSAPP_CALLING_NO_PERMISSION; the dashboard surfaces a CTA to send the call-permission template first.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
required
Recipient phone number (E.164, optional leading +).
string
required
Meta phone_number_id of the sender WABA number.
string
—
—
string
Echoed back on every webhook event for the call (correlation handle).
string
SDP offer for browser-side WebRTC. Omit for server-bridged calls.