Calling API Reference

Consolidated WhatsApp Calling reference: every endpoint, every webhook, WebRTC and ICE guidelines, DTLS certificate recommendations, SDP requirements, bandwidth budget, IP allowlisting.

What This Page Covers

A consolidated reference for the Calling API: every endpoint, every webhook, and the media-path guidelines you need to build a working WebRTC integration. For task-oriented walkthroughs see Business-Initiated Calls, User-Initiated Calls, Configuration, Permissions, and SIP.

Endpoints Summary

All calling endpoints are scoped to a business phone number.

Method + EndpointPurpose
POST /<PHONE_NUMBER_ID>/settingsConfigure call settings (status, call_hours, callback_permission_status, audio codecs, SIP, SRTP key exchange)
GET /<PHONE_NUMBER_ID>/settingsRead current settings. Add ?include_sip_credentials=true to include SIP password
POST /<PHONE_NUMBER_ID>/callsAll call actions: connect (BIC), pre_accept/accept/reject (UIC), terminate (both)
GET /<PHONE_NUMBER_ID>/call_permissions?user_wa_id=<USER_WHATSAPP_ID>Get call permission state — current status, expiration, action limits
POST /<PHONE_NUMBER_ID>/messages (interactive voice_call)Send a free-form call button message
POST /<PHONE_NUMBER_ID>/messages (interactive call_permission_request)Send a free-form permission request
POST /<WABA_ID>/message_templates (with voice_call button)Create a call-button template
POST /<WABA_ID>/message_templates (with call_permission_request component)Create a permission-request template
GET /<WABA_ID>/?fields=call_analyticsGet cost, completed-call counts, average call duration (Pricing)

POST /<PHONE_NUMBER_ID>/calls carries different payloads depending on action. Common shape:

{
  "messaging_product": "whatsapp",
  "to": "12015550123",                         // BIC only
  "call_id": "wacid.HBgL...",                  // pre_accept/accept/reject/terminate
  "action": "connect | pre_accept | accept | reject | terminate",
  "session": {
    "sdp_type": "offer | answer",
    "sdp": "<<RFC 8866 SDP>>"
  },
  "biz_opaque_callback_data": "0fS5cePMok"     // optional
}

session is required on connect (offer), pre_accept (answer), accept (answer). Not used on reject or terminate.

Webhooks Summary

Subscribe to the calls webhook field to receive these. In Dualhook setups they're delivered directly to your endpoint via Webhook Override — Dualhook does not ingest them.

WebhookWhenNotes
Call Connect (UIC)User initiates a callContains SDP offer to apply to your WebRTC stack
Call Connect (BIC)After your POST /calls connect succeedsContains SDP answer from Meta
Call Status (BIC)RINGING, ACCEPTED, REJECTEDACCEPTED typically arrives after media is already established — for auditing
Call TerminateEither party hangs up, you call terminate/reject, or call failsIncludes start_time, end_time, duration if call was answered. errors[] if it failed.
User Call Permission Reply (messages field)User accepts, rejects, or auto-revokes permissionCarries is_permanent, expiration_timestamp, response_source

Note: the user permission reply arrives on the messages field (not calls) because it's a user response to your message. Subscribe to both fields.

The account_settings_update webhook field tracks changes to calling.status, calling.call_icon_visibility, calling.callback_permission_status, calling.sip.status, and calling.srtp_key_exchange_protocol. See Configuration → Settings Webhook.

Media Path Guidelines

Mandatory for all media — failures here either cause call failure during signaling or media decoding:

  • OPUS audio codec only (or PCMA/PCMU if explicitly enabled in audio.additional_codecs for transcoding interop).
  • Media clock rate: 48 kHz.
  • DTMF clock rate: 8 kHz (only).
  • ptime: 20ms.
  • Single audio SSRC. Meta's relay overwrites your business audio SSRC to a fixed value before relaying to the WhatsApp client. Multiple SSRCs cause undefined behavior — corruption, glitches, total media failure.

Recommended (not mandatory but produces good call quality):

  • ECDSA certificates for DTLS (faster cert generation, shorter handshake, no fragmentation).
  • Pre-accept (UIC) to frontload the WebRTC connection before media flows.

ICE and WebRTC

Meta's WebRTC stack is ICE-LITE. Your stack should be ICE-FULL to maintain compatibility:

  • Initiate ICE connectivity checks via STUN.
  • Take the CONTROLLING role. Meta only takes CONTROLLED. Starting CONTROLLED can stall and timeout, or take longer due to role-conflict resolution.
  • Use regular nomination, not aggressive nomination (RFC 5245).
  • Wait for the ICE process to complete before nominating the candidate and starting DTLS.
  • Don't switch the candidate mid-call.

ICE Trickle is supported — Meta will accept STUN connectivity checks from addresses not included in your initial SDP, as long as STUN message integrity passes.

Meta does not provide STUN/TURN servers and has no recommendations on third-party providers. If your media terminates in your own infra (typical for IVR/contact center setups), STUN/TURN often isn't needed — your VIP behind a load balancer can serve as the ICE candidate.

DTLS Certificates

  • Use ECDH keys to prevent packet fragmentation during handshake transmission.
  • Your business should act as the DTLS client (RFC 6347 Section 4.2).
  • Common DTLS retry intervals (1s, 2s, 4s) cause ~3 seconds of delayed setup after Meta receives your SDP, which can result in audio clipping. Switch to SDES key exchange to avoid this — see Calling Troubleshooting → Audio Clipping.

SDP Overview

Session Description Protocol describes media parameters for WebRTC negotiation: codecs, ICE candidates, DTLS fingerprints, etc. Your session.sdp field on POST /calls must be RFC 8866 compliant.

Key requirements:

  • Single stream per SDP. Multiple streams not supported.
  • One audio track per stream.
  • CRLF (\r\n) line endings within the SDP string. Don't double-serialize — session.sdp is just a string field.
  • DTMF payload type 126 with 8000 clock rate (default if absent).
  • a=fingerprint line when using DTLS for SRTP key exchange. Without it, you'll get "No fingerprint found in SDP" — switch to SDES if you can't include a fingerprint.

For a business agent's browser to work in UIC, the WebRTC agent in the browser should generate an SDP answer (not offer). Pass that answer to POST /calls accept.

Meta cannot work with any SDP offer other than the one it generates and provides on the UIC connect webhook.

Media Relay Targeting (Latency)

Meta's targeting algorithm picks the Meta relay closest to the WhatsApp consumer. That relay's IP is the ICE candidate Meta sends in the SDP.

On your side, place media servers in the same region as the consumer to minimize latency. For international calls, this minimizes the public-internet routing length.

Optimize against the candidate IPs on Meta's SDPs, not against the source of signaling endpoints (which can be different).

Bandwidth Budget

Per call:

CodecBandwidth
OPUS~40 kbps codec + ~20 kbps overhead = ~60 kbps total
G.711 (PCMA/PCMU)64 kbps codec + 20 kbps overhead = ~84 kbps total

Multiply by concurrent calls. A 1 Mbps link supports roughly:

  • ~15 concurrent OPUS calls
  • ~12 concurrent G.711 calls

OPUS is variable-rate based on network conditions. A 1-minute OPUS call uses ~3.75 MB; G.711 uses ~4.9 MB.

Maximum concurrent calls per phone number: 1,000.

Webhook Delivery Semantics

  • No ordering guarantees for calling webhooks. Terminate can arrive before connect if the user hangs up immediately. Connect retries can interleave with terminate sends. Use the timestamp field to order events.
  • No exactly-once delivery. Be prepared for duplicates. Common causes: 20-second HTTP timeout from Meta's side (your endpoint thinks it succeeded; Meta retries), multiple apps subscribed to calls (one app fails, Meta retries the whole dispatch hitting the others again), Meta queue infrastructure recovery.
  • Retry policy is shorter than messaging webhooks (which retry up to 7 days). Meta hasn't published exact numbers — assume stale webhooks may still arrive and check timestamp before acting.
  • Multiple webhook endpoints (one app per URL) get all calling webhooks dispatched to all of them. No notion of primary/secondary — all are equal.
  • Different URLs for messaging vs calling is achievable by using two separate Meta apps (one subscribed to messages, one to calls) and overriding callback URLs per app. Or just use one app and one URL — distinguish by payload field (field: "calls" vs field: "messages").

IP Allowlisting

Meta's webhook servers come from a fluid set of IP ranges. As of mid-2024, this collapses to ~23 IPv4 prefixes (full list updates over time):

31.13.24.0/21      31.13.64.0/18      45.64.40.0/22
57.141.0.0/21      57.141.8.0/22      57.141.12.0/23
57.144.0.0/14      66.220.144.0/20    69.63.176.0/20
69.171.224.0/19    74.119.76.0/22     102.132.96.0/20
103.4.96.0/22      129.134.0.0/16     147.75.208.0/20
157.240.0.0/16     163.70.128.0/17    163.77.128.0/17
173.252.64.0/18    179.60.192.0/22    185.60.216.0/22
185.89.216.0/22    204.15.20.0/22

Generate the current list yourself:

whois -h whois.radb.net -- '-i origin AS32934' | grep '^route' | awk '{print $2}' | sort

Or use the geofeed CSV from Meta's webhooks documentation. Better: use mTLS for webhook authentication instead of IP allowlisting, since the IPs do change. Meta supports mTLS for webhooks (separate from SIP, which doesn't support mTLS).

For SIP-mode setups, the same Meta IP space applies — your SIP server's firewall must allow inbound TLS from these prefixes.

Related

  • Cloud API CallingVoice calling on WhatsApp Business Cloud API: VoIP via WebRTC or SIP, business-initiated and user-initiated calls, prerequisites, availability, and integration patterns.
  • Business-Initiated CallsPlace outbound voice calls to WhatsApp users. POST /calls with action: connect, SDP offer/answer flow, call status webhooks (RINGING/ACCEPTED/REJECTED), terminate webhook with duration, biz_opaque_callback_data tracking.
  • User-Initiated CallsReceive inbound voice calls from WhatsApp users. Call Connect webhook with SDP offer, pre-accept for faster setup, accept/reject/terminate actions, DTMF dial pad, companion-device support.
  • Calling TroubleshootingWhatsApp Calling errors and fixes: full error code table (138000-138023), SIP-specific status codes, media-flow timeouts, audio clipping causes and mitigations (SDES, pre-accept), quick triage guide.
Browse more docsStart Free Trial