0% found this document useful (0 votes)
68 views47 pages

Cloud API Calling GraphAPI Spec Beta V0.97

The document outlines the WhatsApp Cloud API Calling Graph API specifications, detailing how businesses can utilize VoIP communication alongside text messaging through the GraphAPI interface. It includes information on API endpoints for managing call settings, authorizations, and handling user-initiated calls, as well as planned features and potential errors. Additionally, it emphasizes the importance of call icon visibility and callback permissions for businesses using the API.

Uploaded by

chellamusha2708
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views47 pages

Cloud API Calling GraphAPI Spec Beta V0.97

The document outlines the WhatsApp Cloud API Calling Graph API specifications, detailing how businesses can utilize VoIP communication alongside text messaging through the GraphAPI interface. It includes information on API endpoints for managing call settings, authorizations, and handling user-initiated calls, as well as planned features and potential errors. Additionally, it emphasizes the importance of call icon visibility and callback permissions for businesses using the API.

Uploaded by

chellamusha2708
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

Meta Confidential! Do not share without approval!

WhatsApp Cloud API Calling Graph API Spec


Version: 0.97

Context
WhatsApp Business Calling aims to bring the VoIP communication channel in addition to text messaging between WhatsApp consumers and
Business on WhatsApp. The consumers would use the WhatsApp consumer app in a manner similar to the current Consumer to Consumer
Calling product. Businesses would however interface with WhatsApp via GraphAPI interface for the initial call signaling and connection.

Disclaimer
These APIs are for reference only. The shipped APIs can differ drastically from the ones in this doc.

Architecture Overview
Internet Internet

Meta Partner
Signaling Graph APIs, Signaling
Webhooks
Infra HTTPS
Infra

Enable reuse of
Partner VoIP
existing systems System

WhatsApp Business agents


Users
Meta RTC WebRTC
Partner RTC
Infra UDP Infra

Graph API Interface


The HTTP API endpoints described in this doc are denoted in relative format ex: POST /{phone-number-id}/calls. You’ll invoke such APIs
similar to our messaging APIs, example here. An example full URL for the APIs looks like https://graph.facebook.com/v20.0/{phone-number-
id}/calls.

Authorization
The Calling APIs utilize the same Authorization tokens as the rest of Cloud API and reuses existing permissions
whatsapp_business_messaging and whatsapp_business_management. More details can be found here.

New "calls" webhook field for Apps to Subscribe


A new Webhook field "calls" is exposed for Calling enabled apps to subscribe. After doing this one-time step from your App Dashboard, you
should also subscribe this app to individual WhatsApp Business Accounts (WABA) to receive the webhooks for phone numbers under it. This
per WABA subscription is the same as for other webhook subscription fields like ‘messages’.

Call Settings APIs


Use these APIs to view and manage calling related configuration for your business phone numbers. By default calling is not enabled on a
business phone number.

Update Phone Number Calling Settings


Description Update calling settings for a phone number

Endpoint POST /{phone-number-id}/settings

Request Body {
"calling": {
"status": "ENABLED",
"call_icon_visibility": "DEFAULT",
"callback_permission_status": "ENABLED"
}
}

Response {
"success": true
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
"fbtrace_id": "<Trace ID>"
}
}

App Permissions ● whatsapp_business_management


○ Advanced access is required to use the API on behalf of end business clients

Endpoint Params ● Phone-number-id: This is an ID for each phone number registered to whatsapp business
platform. More details here

Options Parameters nested under "calling" node:


● status: [ENABLED, DISABLED]
○ Indicates if calling feature is enabled for the number
● call_icon_visibility (optional): [DEFAULT, HIDE_IN_CHAT, DISABLE_ALL]
○ This controls the display of the call icon in WhatsApp consumer client apps. See details
on the behavior
○ Supported consumer client versions:
■ Android 2.24.10.x and above
■ iOS 2.24.10.x and above
● callback_permission_status (optional): [ENABLED, DISABLED]
○ Indicates if the callback permissions are enabled for this number, details here.
○ Enabling will allow WhatsApp to prompt users for sending an approved call permission
request following a (connected or missed) user initiated call
○ NOT_SET by default, behaves the same as DISABLED
○ Supported consumer client versions:
■ Android 2.25.3.X onwards
■ iOS: 2.25.3.X onwards
● [Planned Feature] ip_addresses (optional)
○ default: List of IP address blocks representing business voice call servers (max of 3,
IPv4 or IPv6). Cloud API will use this as default for the business to optimize call quality

Response Details ● success: is the operation successful


Details Call this API to enable/disable the calling feature and configure calling related settings.

Calling Status: When a business sets the calling status as enabled, WhatsApp clients will render the
call icon in business conversations and business chat profile. The call icon will be hidden when calling
status is set to disabled. Call icon updates in existing chats will be near real time when the business
phone number is in the user's contacts. Otherwise updates are real time for a limited number of users in
conversation with the business, and eventual (up to a few days) for the rest. See instructions to force
display of the call icon.

Calling Eligibility: To enable calling, the business must have a messaging limit of 1000 business-
initiated conversations in a rolling 24-hour period (or higher) on any of their phone numbers. See
instructions on how to check this.

The business numbers that were previously onboarded using Google form are automatically set to
calling status enabled. You don’t have to take any action for those numbers. We’ll soon deprecate
Google form in favor of this self service API

Call Icon Visibility: When calling status is enabled, you can further control the display of the call icon
via the "call_icon_visibility" parameter. The behavior for supported options is as follows:
● DEFAULT
○ Call icon is displayed is in all calling entry points (chat menu and business info)

● DISABLE_ALL
○ Deprecates HIDE_IN_CHAT.
○ Call icon is hidden in the chat menu and business info window accessed through the
chat.
○ All other entry points external to the chat are also disabled - consumers cannot make
unsolicited calls to the business. Note: This relies on the most recent WhatsApp client
version released on November 18, so it will take a few months before we reach 100%
client coverage of the feature.
○ When you choose DISABLE_ALL, you can still send interactive message or template
message with Call CTA button, which will continue to work

Callback Permissions: a business initiated call on WhatsApp Cloud API requires explicit permissions
from the user before a business can call the user. The account can be set to automatically trigger the
call permission UI in the user’s WhatsApp client on an unanswered user initiated call. The user may
change their selection at any time. More details here.
[Planned Change - ETA June 2025] Proactive callback permissions: We plan to update this feature
such that the WhatsApp client app will automatically send an approved call permission when a user
initiates a call to the business regardless of the outcome of the user initiated call. The user may change
this selection at any time. This change should be completely transparent from the API integration pov.
[Planned Feature] Support for providing your webrtc endpoint IP address blocks is coming in the near
future. Cloud API will only use these IPs to optimize server selection to improve call quality.

Possible Errors ● Permissions/Authorization errors


● Invalid status
More details on Cloud API Error codes here.

Get Phone Number Calling Settings


Description Fetch calling settings for a phone number

Endpoint GET /{phone-number-id}/settings

Response {
"calling": {
"status": "ENABLED",
"call_icon_visibility": "DEFAULT",
"callback_permission_status": "ENABLED"
},
<Other non-calling feature configuration...>
}
Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
"fbtrace_id": "<Trace ID>"
}
}

App Permissions ● whatsapp_business_management


● Advanced access is required to update use the API for end business clients

Endpoint Params ● Phone-number-id This is an ID for each phone number registered to whatsapp business
platform. More details here

Response Details ● calling: Calling related feature settings the business previously set
○ status: [ENABLED, DISABLED]
○ call_icon_visibility (optional): [DEFAULT, HIDE_IN_CHAT, DISABLE_ALL]
○ [Planned Feature - ETA Apr 2025] callback_permission_status: [ENABLED |
DISABLED | NOT_SET],
○ [Planned Feature] ip_addresses (optional)
■ default: List of IP address blocks representing business voice call servers (IPv4
or IPv6). Cloud API will use this as default for the business to optimize call quality

This API will also return other feature settings (ex. Local Storage) if configured

Details Businesses call this API to check their calling feature settings.
This API can return information for other Cloud API feature settings.

Possible Errors ● Permissions/Authorization errors


More details on Cloud API Error codes here.

Target Launch Beta

WhatsApp Manager Call Settings


[Planned Feature-November] You can also control your call settings via the WhatsApp Manager interface at https://business.facebook.com.

To access it:
1. Click on WhatsApp Accounts
2. Select your WhatsApp Account
3. Click on Phone Numbers
4. Click the gear icon next to the phone number you are using for calling
5. Click the "More" dropdown, then select "Calls"

[Planned Feature-Apr 2025] You can control your callback permissions settings via the WhatsApp Manager interface.
Consumer Initiated Calls
Pre-accepting an user initiated call
Description Respond to an user initiated call by pre-accepting the call. Pre-accept facilitates
faster call setup and avoids audio clipping problems

Endpoint POST /{phone-number-id}/calls

Request Body {
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"action": "pre_accept",
// connection is to be deprecated, use session instead
"connection" : {
"webrtc": {
"sdp" : "<<SDP INFO>>"
}
},
"session" : {
"sdp_type" : "answer",
"sdp" : "<<RFC 4566 SDP>>"
}
}
}

Response {
"messaging_product": "whatsapp",
"success" : true
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint Params ● Phone-number-id This is an ID for each phone number registered to


whatsapp business platform. More details here

Options ● call_id: Id of the call, from the webhook you previously received for this call
● action: [pre_accept, accept, reject, terminate]
● connection (Only required when Action = pre_accept or accept). The field
‘sdp’ is a json serialized string with following 2 keys†
○ sdp: SDP info of the device on the other end of the call. Example
structure in appendix.
○ type: "answer" - to indicate sdp answer
○ connection is to be deprecated, use session instead
● session: Indicates connection information/event pertaining to this call
session. It need two parameters
○ sdp: SDP info of the device on the other end of the call. Example
structure in appendix. Sdp must be compliant with RFC 4566.
○ sdp_type: "answer" - to indicate sdp answer

Response Details ● success: is the operation successful

Details Businesses call this API to initiate the call setup process by providing an SDP
answer. Pre-accepting is optional but highly recommended to optimize the call
setup process and allow media connection to be pre-established before call
acceptance, but with no media. Once the call is accepted, media starts flowing
immediately as the connection is already in place.

The webrtc connection would be established before call acceptance, so make


sure to flow the media only after you receive 200 OK for your accept call. If the
media flows too early, consumers will miss hearing the first few words. If media
flows too late, consumers will hear silence

Possible Errors ● Invalid call id


● Invalid phone-number-id
● Error related to your payment method
● Invalid Connection info eg sdp, ice etc
● Accept/Reject an already In Progress/Completed/Failed call
● Permissions/Authorization errors
More details on Cloud API Error codes here.

Accepting an user initiated call


Description Respond to an user initiated call by Accepting a previously pre-accepted call

Endpoint POST /{phone-number-id}/calls

Request Body {
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"action": "accept",
// connection is to be deprecated, use session instead
"connection" : {
"webrtc": {
"sdp" : "<<SDP INFO>>"
}
},
"session" : {
"sdp_type" : "answer",
"sdp" : "<<RFC 4566 SDP>>"
},
"biz_opaque_callback_data": "random data",
}
}

Response {
"messaging_product": "whatsapp",
"success" : true
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint Params ● Phone-number-id This is an ID for each phone number registered to


whatsapp business platform. More details here

Options ● call_id: Id of the call, from the webhook you previously received for this call
● action: [pre_accept, accept, reject, terminate]
● connection (Only required when Action = pre_accept or accept). The field
‘sdp’ is a json serialized string with following 2 keys
○ sdp: SDP info of the device on the other end of the call. Example
structure in appendix.
○ type: "answer" - to indicate sdp answer
○ connection is to be deprecated, use session instead
● session: Indicates connection information/event pertaining to this call
session. It need two parameters
○ sdp: SDP info of the device on the other end of the call. Example
structure in appendix. Sdp must be compliant with RFC 4566.
○ sdp_type: "answer" - to indicate sdp answer
● biz_opaque_callback_data [Optional]:
○ An arbitrary string, useful for tracking.
○ Any app subscribed to the calls webhook field on the WhatsApp
Business Account can get this string, as it is included in the “calls”
object within the subsequent Terminate Webhook payload.
○ Cloud API does not process this field, it just returns it as part of
Terminate Webhook
○ Maximum 512 characters.

Response Details ● success: is the operation successful

Details Businesses call this API to connect to a call by providing an agent's SDP.

The business has some amount of time to respond to the user initiated call (30 -
60s) incoming webhook with the pre-accept or accept API call. If the business
does not respond the call is terminated on consumer side with "Not Answered"
and a Terminate webhook is delivered to the business

Possible Errors ● Invalid call id


● Invalid phone-number-id
● Error related to your payment method
● Invalid Connection info eg sdp, ice etc
● Accept/Reject an already In Progress/Completed/Failed call
● Permissions/Authorization errors
● SDP answer provided in accept does not match the SDP answer provided in
the pre-accept API for the same call id
More details on Cloud API Error codes here.

Rejecting an user initiated call


Description Respond to an user initiated call by Rejecting the call

Endpoint POST /{phone-number-id}/calls

Request Body {
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"action": "reject"
}

Response {
"messaging_product": "whatsapp",
"success" : true
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint Params ● Phone-number-id This is an ID for each phone number registered to


whatsapp business platform. More details here

Options ● call_id: Id of the call, from the webhook you previously received for this call
● action: [accept, reject, terminate]

Response Details ● success: is the operation successful

Details Businesses call this API to reject a call.

Typically the business has some amount of time to respond to the user initiated
call (30 - 60s) incoming webhook with the reject API call. If the business does not
respond then the call will be terminated on consumer side with "Not Answered"
and a Terminate webhook is delivered to the business

Possible Errors ● Invalid call id


● Invalid phone-number-id
● Invalid Connection info eg sdp, ice etc
● Accept/Reject an already In Progress/Completed/Failed call
● Permissions/Authorization errors
More details on Cloud API Error codes here.

Hanging up an active call


Description End the call

Endpoint POST /{phone-number-id}/calls

Request Body {
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"action" : "terminate"
}

Response {
"messaging_product": "whatsapp",
"success" : true
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint Params ● Phone-number-id This is an ID for each phone number registered to


whatsapp business platform. More details here

Details Business must call this API to end a call. This must be done even if there is an
RTCP BYE packet in the media path. Doing so helps with more accurate pricing.
When a consumer terminates the call, you don’t have to invoke this API.
Terminate webhook will be sent following successful processing of this API.

Options ● call_id: Id of the call


● action: [accept, reject, terminate]

Response Details ● success: is the operation successful

Calling Webhooks
The structure of webhooks is similar to the structure of webhooks used for Messaging in Cloud API. Detailed documentation of the
webhooks can be found here.
A "calls" section in the "value" section of the webhook contains calls related fields.

Connect: Receive notification about an user initiated call ready for pickup
This webhook is sent in near real-time, when the business receives an user initiated call. Webhook also includes the info to
establish a connection via WebRTC.
- This webhook is sent to signal the business to establish the call WebRTC connection by utilizing the /calls action=connect
- This webhook contains the new SDP information to help with establishing WebRTC connection
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16315553601",
"phone_number_id": "phone-number-id",
},
"contacts": [{
"profile": {
"name": "callee name"
},
"wa_id": "16315553602"
}],
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"to": "16315553601",
"from": "16315553602",
"event": "connect",
"timestamp": "1671644824",
"direction": "[BUSINESS_INITIATED|USER_INITIATED]",
// connection to be deprecated, use session
"connection": {
"webrtc": {
"sdp": {..<<SDP data>>..}
}
},
"session": {
"sdp_type": "offer"
"sdp": "<<RFC 4566 SDP>>"
}
}
]
},
"field": "calls"
}
]
}
]
}

Field Name Description

id Unique ID created for a call

to Callee of the call

from Caller of the call

event The event this webhook notifies the listener about

timestamp Timestamp of the webhook event

connection Structure that contains information that is used for the voice connection for the call
Field connection is to be deprecated, use session instead

webrtc Information related to webrtc connect. At this time only WebRTC connections are
supported

sdp Session Description Protocol data for the device on the other end of the call. This
is a json serialized string with following 2 keys
● sdp: SDP info of the device on the other end of the call. Example structure
in appendix.
● type: "offer" - to indicate sdp offer

session Indicates connection information/event pertaining to this call session. It will have
the below two parameters

sdp Session Description Protocol data for the device on the other end of the call.
Example structure in appendix. Sdp must be compliant with RFC 4566

sdp_type Type of the sdp can be "offer" or "answer" depending on whether the call is
business initiated or consumer initiated respectively.

contacts Profile information of the callee. Contains their WhatsApp profile name and
WhatsApp ID.

Terminated: Receive notification about call termination


This webhook is sent when the call has been terminated for any reason by either the callee or the caller. The payload contains the
call id of the call that was terminated. This is generated either when Consumer hangs up OR when business calls GraphAPI /calls
action=terminate or /calls action=reject.
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16505553602",
"phone_number_id": "phone-number-id",
},
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"to": "16315553601",
"from": "16315553602",
"event": "terminate"
"direction": "[BUSINESS_INITIATED|USER_INITIATED]",
"biz_opaque_callback_data": "random data",
"timestamp": "1671644824",
"status" : [FAILED | COMPLETED],
"start_time" : "1671644824",
"end_time" : "1671644944",
"duration" : 120
}
],
"errors": [
{
"code": INT_CODE,
"message": "ERROR_TITLE",
"href": "ERROR_HREF",
"error_data": {
"details": "ERROR_DETAILS"
}
}
]
},
"field": "calls"
}
]
}
]
}

Field Name Description

id Unique ID created for a call

to Callee of the call

from Caller of the call

event The event this webhook notifies the listener about

direction Direction of the call with respect to the Business

timestamp Timestamp of the webhook event

status Final status of the call


- Completed: If the call completed, Call rejected by the Callee also counts as
completed
- Failed: If the call fails mid connection due to any reason

start_time [Optional] Start time of the call. Only present when the call was picked up by the
other party.

end_time [Optional] End time of the call. Only present when the call was picked up by the
other party.

duration [Optional] Duration of the call in seconds. Only present when the call was picked
up by the other party.

errors This field exists if status is failed and includes more details about the error

biz_opaque_callb [Optional] Will only be available if provided through New Call API Requests or
ack_data Accept Call Requests
Consumer to Business Call Sequence Diagram

Consumer to Business Call Flow


Prereq: Subscribe to the new calls webhook subscription field

1) Consumer Calls business from the whatsapp consumer app, the call results in the below webhook event being delivered to the business
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16315553601",
"phone_number_id": "phone-number-id",
},
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"to": "16315553601",
"from": "16315553602",
"event": "connect",
"timestamp": "1671644824",
"connection": {
"webrtc": {
"sdp": {..<<SDP offer data>>..}
}
},
"session": {
"sdp_type": "offer"
"sdp": "<<RFC 4566 SDP>>"
}
}
]
},
"field": "calls"
}
]
}
]
}

2) Business responds to the webhook by pre-accepting the call using the /calls api with the below Request body. This step is optional. See
audio clipping section for more context.
POST {phone-number-id}/calls
{
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"action": "pre_accept",
"connection" : {
"webrtc": {
"sdp" : "<<SDP answer data>>"
}
},
"session": {
"sdp_type": "answer"
"sdp": "<<RFC 4566 SDP>>"
}
}

3) Business gets the below response from Cloud API


{
"success" : true
}

4) Business waits for webrtc/ice connection and accepts the call using the /calls api with the below Request body
POST {phone-number-id}/calls
{
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"action": "accept",
"connection" : {
"webrtc": {
"sdp" : "<<SDP answer data>>"
}
},
"session": {
"sdp_type": "answer"
"sdp": "<<RFC 4566 SDP>>"
}
}

5) If the Business wants to terminates the call, they would call the /calls api with the below Request body
POST {phone-number-id}/calls
{
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"action" : "terminate"
}

6) The Business would receive the below response confirming the action
{
"success" : true
}

7) The Business would eventually receive the terminate webhook once the call has been disconnected across the stack or if the call was
disconnected by the whatsapp consumer
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16505553602",
"phone_number_id": "phone-number-id",
},
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"to": "16315553601",
"from": "16315553602",
"event": "terminate"
"direction": "[BUSINESS_INITIATED|USER_INITIATED]",
"timestamp": "1671644824",
"status" : [Failed | Completed],
"start_time" : "1671644824",
"end_time" : "1671644944",
"duration" : 120
}
]
},
"field": "calls"
}
]
}
]
Messages with Call CTA
Send interactive message with WhatsApp Call Button
Description Send an interactive message with WhatsApp Call Button

Endpoint POST /{phone-number-id}/messages

Request {
Body "messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "14085551234",
"type": "interactive",
"interactive" : {
"type" : "voice_call",
"body" : {
"text": "You can call us on WhatsApp now for faster service!"
},
"action": {
"name": "voice_call",
"parameters": {
"display_text": "Call on WhatsApp",
"ttl_minutes": 100,
}
}
}
}

Response See successful response in documentation

Error {
Response "error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint ● Phone-number-id This is an ID for each phone number registered to whatsapp


Params business platform. More details here
● interactive.type and interactive.body are required
● interactive.header is optional
● interactive.footer is not allowed
● interactive.action.parameters key is optional.
○ The default value of “display_text” is ‘Call Now’. Max allowed length is 20
chars
○ [new field]”ttl_minutes” (optional)
■ Is the time to live for the CTA button in minutes. After this time
expires, the button can’t be used to initiate a call to business.
■ Expected value is an Integer value between 1 and 43200 (30 days)
■ default value of “ttl_minutes” is (7 days) 10080

Details Business calls this API to send a message to consumers to raise awareness of the calling
support using an inline button embedded within the message. When a consumer clicks that
button, it initiates a WhatsApp call to the business number that sent this message. This
behavior is the same as a consumer clicking the phone/call icon in the chat title bar. There
is no support for the button to WhatsApp call a different phone number

Limitations ● Sending this message to users on older app versions will result in error webhook
with error code 131026

Options See public documentation for more details


Response See successful response in documentation
Details

Create Template with WhatsApp Call Button


The existing create template API is enhanced to support a new button type ‘VOICE_CALL’ which will trigger a WhatsApp call, when clicked by
a WhatsApp consumer. In general, this button can be used anywhere the existing phone number button is possible. So it is supported in
templates of any category.
You can also create/update templates in WhatsApp Manager GUI.
Description Create a new message template with WhatsApp Call Button

Endpoint POST /<WHATSAPP_BUSINESS_ACCOUNT_ID>/message_templates

Request {
Body "name": "<NAME>",
"category": "<CATEGORY>",
"language": "<LANGUAGE>",
"components": [
{
"type": "BODY",
"text": "You can call us on WhatsApp now for faster service!"
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "VOICE_CALL",
"text": "Call Now"
},
{
"type": "URL",
"text": "Contact Support",
"url": "https://www.luckyshrub.com/support"
}
]
}
]
}

Response See successful response in documentation

Error {
Response "error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint ● The only field supported for VOICE_CALL button type is "text" which indicates the
Params label of the button rendered on WhatsApp consumer client apps

Details Business calls this API to send a template message to consumer to raise awareness of the
calling support using an inline button embedded within the message
Options See public documentation for more details

Response See successful response in documentation


Details

Send template message with WhatsApp Call Button


At message send time, you can override the button expiry configured in the template definition
Description Send a template message with WhatsApp Call Button

Endpoint POST /{phone-number-id}/messages

Request {
Body "to": "14085551234",
"messaging_product": "whatsapp",
"type": "template",
"recipient_type": "individual",
"template": {
"name": "wa_voice_call",
"language": {
"code": "en"
},
"components": [
{
"type": "button",
"sub_type" : "voice_call",
"parameters": [
{
"type": "ttl_minutes",
"ttl_minutes": 100
}
]
}
]
}
}

Response See successful response in documentation

Error {
Response "error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint ● Phone-number-id This is an ID for each phone number registered to whatsapp


Params business platform. More details here
● components key is optional.
○ [new field] sub_type: "voice_call"
■ Inside "parameters"
● "type":"ttl_minutes"
● "ttl_minutes":<value in integer>
■ Is the time to live for the CTA button in minutes. After this time
expires, the button can’t be used to initiate a call to business.
■ Expected value is an Integer value between 1 and 43200 (30 days)
■ default value of “ttl_minutes” is (7 days) 10080

Details Business calls this API to send a message to consumers to raise awareness of the calling
support using an inline button embedded within the message. When a consumer clicks that
button, it initiates a WhatsApp call to the business number that sent this message. This
behavior is the same as a consumer clicking the phone/call icon in the chat title bar. There
is no support for the button to WhatsApp call a different phone number

Limitations ● Sending this message to users on older app versions will result in error webhook
with error code 131026

Options See public documentation for more details

Response See successful response in documentation


Details

Call deep links


Call deep links allow WhatsApp consumers to easily call a business. Businesses can embed a Call deep link on their websites/apps or send
deep links via chat.

As mentioned, deep links can currently be used in two ways:


1. Embed Call deep links on businesses’ websites, Apps, or QR Codes: By allowing businesses to advertise calls on their website
and using other communication channels, we can increase the visibility and accessibility of their services. Businesses are now able to
create and embed Call deep links directly on their website for easy accessibility for service/support and commerce/sales use cases (Ex:
“Call us to learn more about our real estate offerings”)

2. Businesses can send Call deep links on WhatsApp: With Call deep links, businesses now have more control over calls. Call deep
links allow businesses and agents to link to another number and prompt users to contact a different phone number with voice enabled.
The wa.me/call/<phone number> format is easy to replicate and copy and paste, and does not require having to set up a template in
Business Manager.

Calling Error Codes


Error codes related to Whatsapp Cloud API Business platform are detailed here. These are currently publicly available error codes for currently
supported use cases. The Calling specific error codes not included in the above documentation are detailed below.

Code Description Possible Solutions HTTP Status Code

138000 Calling APIs are not enabled for this phone WhatsApp CloudAPI Calling APIs are 401
Calling not enabled number currently only available to select WhatsApp Unauthorized
Business platform partners.
Reach out to the Whatsapp Business team
to find out more.
Code Description Possible Solutions HTTP Status Code

138001 Receiver is unable to receive calls Confirm with the recipient that they agree to 400
be contacted by you over WhatsApp and
Receiver Uncallable Reasons can include: are using the latest version of WhatsApp. Bad Request

● The recipient phone number is not a


WhatsApp phone number.
● Recipient has not accepted our new Terms of
Service and Privacy Policy.
● Recipient using an old WhatsApp version;
must use the following WhatsApp version or
greater:
● Recipient using an unsupported client. The
currently supported clients are Android, iOS,
SMB Android and SMB iOS

138002 Limit reached for maximum concurrent calls for the Try again later or reduce the frequency or 429
Concurrent Calls limit given number amount of API calls the app is making. Too many requests

138003 A call is already ongoing with the receiver Try again later when the current call ends. 400
Duplicate call Bad Request

138004 Error while connecting the call Try again later or investigate the connection 500
Connection error params provided to the API

138005 Limit reached for maximum calls that can be Try again later or reduce the frequency or 429
Call rate limit exceeded initiated by the business phone number amount of API calls the app is making. Too many requests

131009 Interactive Message type, 'voice_call' not Ensure the sender in one of the supported 400
supported. Supported types ['button', 'list’] countries. Bad Request

131044 An error webhook is sent on user initiated calls This is similar to the "Business eligibility 400
when there is no valid payment method attached payment issue" error in messaging. Bad Request

138006 No approved call permission from the recipient Ensure a call permission has been 401
No approved call accepted by the consumer Unauthorized
permission found

138007 Call was unable to connect due to a timeout Business did not apply the offer/answer 500
Connect Timeout error SDP from Cloud API in time.
Connect API was not invoked with the
answer SDP in time

138009 Limit reached for call permission request sends for When a business sends more than the limit 400
Call Permission the given business and consumer pair of call permission requests per time period,
Request Limit Hit Call Permission Requests are rate limited.
A connected call with a consumer will reset
the limits.

138010 Limit reached for business initiated calls per When business attempts more that the limit 400
Business Initiated Calls approved permission request, for the given of calls per approved call permission
Per Approved business and consumer pair request, we will rate limit the business
initiated calls.
Permission Limit Hit

138011 Unable to send a call permission request message Attempt was made to send a call 400
Unable to send Call permission request message without an Bad Request
permission request open customer service window

100 The GraphAPI call you are making has an invalid Exact error details will be listed in the 400
Invalid Parameter parameter. error_data section of the response payload. Bad Request

If its SDP Validation related error then the


exact issue will be included in the details.

138012 Limit reached for maximum business initiated calls Exact error details will be listed in the 400
Business Initiated Calls allowed in 24 hours. Currently 5 connected error_data section of the response payload.
Limit Hit business initiated calls are allowed within 24
hours. Details will include a timestamp when the
next call is allowed.

DTMF Support
The CloudAPI Calling supports DTMF tones. The intention is for the BSP applications to be able to support IVR based systems for the
participating businesses.
The consumers can press the buttons on the client app and the DTMF tones are injected into the WebRTC RTP stream established as a part of
the VoIP connection. Our WebRTC stream conforms to RFC 4733 for the transfer of DTMF Digits via RTP Payload. Specifically there is no
webhook for conveying DTMF digits.

Sending DTMF digits on consumer WhatsApp client


As a part of this workstream the WhatsApp client applications are enhanced to have a dialpad for calls with CloudAPI business phone numbers.
The consumers can press the buttons on the client app dialpad and send the DTMF tones.

NOTE: This dialpad only supports DTMF use cases. It is not shown for consumer to consumer calls and does not change any other calling
behaviors. For example the dialpad cannot be used to dial a number and initiate a call or message on WhatsApp.

Delivering DTMF digits on WebRTC connection


When a consumer presses a digit in the dialpad on the client, the equivalent DTMF is injected into the webrtc. Tones values are digits from 0 to
9, # and * (ref). The Duration is 500ms and InterToneGap is 100ms for all the tones.

DTMF Sequence Diagram

WhatsApp Consumer Cloud API BSP

WebRTC Connection established

Press key on Dialpad

Inject DTMF tone over WebRTC


Connection

Business Initiated Calls


Product Overview
This section specifically details the API interface for a Business initiated call to a WhatsApp consumer.

Obtaining call permission


To place a call to a user, a business must first receive permission from the user to place a call. A business can obtain permission to call from a
user in any of the following ways:
1. Sending a call permission request to the user
2. User providing a callback permission

When granted by the consumer, a call permission allows the business to call the user subject to following constraints (per business + consumer
pair) to protect WhatsApp users from unwanted calls

Description Limits
Time period the business has to call the user from 7 days
the time user approves the call permission
Permission Duration

Number of connected calls a business can make 5 connected calls per 24 hours for a possible total
to the user. of 35 calls across 7 days
Call limits Failed calls are not counted towards this limit.

Sending Call permission request to the user


A business may proactively request a call permission from a user by sending a call permission request message. The call permission request
message can be sent as a
● Free form interactive message or
● Template message

A consumer may approve, decline or not respond to a call permission request. A user may also change their response (i.e. decline a granted
permission request or grant a declined permission request) at any time before the call permission request expires.
The call permission request expires when any of the following occurs:
● When the consumer interacts with a subsequent new call permission request to the business
● 7 days after the permission was accepted or declined by the consumer
● 7 days after the permission was delivered if the consumer does not respond to the request

To ensure optimal user experience around business initiated calling, the following limits are enforced
1. Sending a call permission request message is subject to the following restrictions:
a. A business can send a maximum of 1 permission request in 24h and 2 permission requests in 7 days. This limit resets when a
connected call takes place between the business and consumer (call can be either user initiated or business initiated).
2. Unanswered business initiated calls i.e. calls either missed or rejected by the user, trigger following behaviour in the WhatsApp user
application
a. 2 consecutive unanswered calls (UX) result in system message to reconsider an approved permission
b. 4 consecutive unanswered calls (UX) result in an approved permission being automatically revoked. The user may again update
this if they so choose.

Call permission requests


Call Permission Request message can be sent to users in the following two ways:
1) Call Permission free form message: Allows business to send a call permission request in response to a user message subject to the
customer service window. A text body will be optional (but highly encouraged) in this case and header and footer sections will not be
supported. Body can be used to provide context on the call request. There is no need for an open conversation window, just a customer
service window is sufficient.
2) Call Permission template message: Allows businesses to start a conversation with a call request. Context (i.e. text body) will be required
in this case. The template will also support Header and Footer sections to further customize the permission request.
Client UI Experience: Permission request sent by the Business

Client UI Experience: System message to update permission on 2 consecutive unanswered calls

Client UI Experience: Automatically permission revoked after 4 consecutive unanswered calls


Client UI Experience: Call Permission Request Expiration behaviour

Call Permission Request Message expires 7 days after


the first time a user interacts with it and user can no
longer update it
Call permission request expires 7 days after the user
receives it if the user never interacts with it
Previously received call permission request is expired
immediately if the user never interacted with it and a
new call permission request is received
Previously received call permission request expires
immediately if the user allows it and then the user
interacts with the new call permission request.

In this case old call permission is overwritten by the user


selection.
User provided the callback permission
A user initiated call to a business is considered as a strong signal of a user’s willingness to converse with a business and hence results in a granted
call permission being sent to the business.

This feature is disabled by default and needs to be explicitly enabled for a business phone number via the call settings api. More details on
enabling/disabling this feature is in the Call Settings API section.

Client UI Experience: Callback permission on a call missed by the business


A call permission will be sent to the user if the user initiates a call and the business is unable to answer the call.
[Planned update Jun, 2025] Client UI Experience: Automatic call permission on user initiated call attempt
A call permission will be sent to the user if the user initiates a call regardless of call’s end state.

Business Initiated Calls Graph API Interface

Call Permission Request

API: Sending a free form Call Permission Request message


Description Sending a message to request call permission from the user

Endpoint POST /{phone-number-id}/messages

Request Body {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "<phone number> or <wa_id>",
"type": "interactive",
"interactive": {
"type": "call_permission_request",
"action": {
"name": "call_permission_request"
},
"body": {
"text": "We would like to call you to help
support your query on Order No: ON-12345."
}
}
}

Response {
"messaging_product": "whatsapp",
"contacts": [{
"input": "+1-408-555-1234",
"wa_id": "14085551234",
}]
"messages": [{
"id": "wamid.gBGGFlaCmZ9plHrf2Mh-o",
}]
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint Params ● Phone-number-id This is an ID for each phone number registered to


whatsapp business platform. More details here

Options
● to: Number to which the voice call is being made. Country codes are
required. More info about accepted formats here.
● type: This will be a new type of interactive message, more details on
interactive messages here
● interactive: For call permissions request messages only the type
param needs to be specified. See mocks above for how this will be
rendered on WhatsApp client device.
● body: optional param to provider users context for the call. Will be
available

Response Details ● As per the normal send message api response. Details here

Details Businesses will call this API to send a call request permission message to a
WhatsApp consumer account. This message will need an open conversation
with the consumer account. More details on opening conversations here.

Note: The message contents cannot be edited by the businesses for the call
permission request interactive message.

Possible Errors ● Invalid phone-number-id


● Permissions/Authorization errors
● Rate limit reached
● Sending this message to users on older app versions will result in error
webhook with error code 131026
● Calling not enabled
More details on Cloud API Error codes here.
Note: In addition, the usual message status webhooks will also be delivered for the call permission request message. Details on the message
status webhooks here.

API: Creating a new template with call permission request

Description Creating a call permission request message template

Endpoint POST/{whatsapp-business-account-id}/message_templates

Request Body {
"name": "sample_cpr_template",
"language": "en",
"category": "[MARKETING|UTILITY]",
"components": [
{
"type": "HEADER",
"text": "Support of Order No: {{1}}",
"example": {
"body_text": [
[
"ON-12345"
]
]
}
},
{
"type": "BODY",
"text": "We would like to call you to help support your
query on Order No: {{1}} for the item {{2}}.",
"example": {
"body_text": [
[
"ON-12345",
"Avocados"
]
]
}
},
{
"type": "FOOTER",
"text": "Talk to you soon!"
},
{
"type": "call_permission_request"
}
]
}

Response {
"id": "<ID>",
"status": "<STATUS>",
"category": "<CATEGORY>"
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
"error_subcode": <Error subcode>,
"is_transient": false,
"error_user_title": "<Error Title>",
"error_user_msg": "<Error Message>"
}
}

Endpoint Params ● whatsapp-business-account-id: This is an ID for the whatsapp business


account for this number. More details here

Response Details ● Id: Id of the template


● Status: Template status
● Category: The template category that you designated, or that we assigned.

Details Businesses may call this API to create a call permission request message template.
More details on how to create/manage templates can be found here. Media is not
supported for this template.

● components: For call permissions request template messages


● body: this component is mandatory for call_permission_request template
types and only supports text content
● header/footer components are optional
● category: only Marketing and Utility are supported
● type: “call_permission_request” identifies the template as a Call
Permission Request template
After creating the template, businesses can send a message to the user to open a
conversation with a call permission request. For more details on how to send
messages for a template check here.

Possible Errors ● Invalid whatsapp-business-account-id


● Permissions/Authorization errors
● Template structure/component validation alerts
More details on Cloud API Error codes for template messages here.

Endpoint Params ● whatsapp-business-account-id: This is the ID for the whatsapp business


account this template will be created for. More details here

API: Sending a call permission request template message


Description Sending a message to request call permission from the user

Endpoint POST /{phone-number-id}/messages

Request Body {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "{user number}",
"type": "template",
"template": {
"name": "sample_cpr_template",
"language": {
"policy": "deterministic",
"code": "en_US"
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "text",
"text": "ON-12345"
}
]
},
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "ON-12345"
},
{
"type": "text",
"text": "Avocados"
}
]
}
]
}
}

Response {
"messaging_product": "whatsapp",
"contacts": [{
"input": "+1-408-555-1234",
"wa_id": "+1-408-555-1234",
}]
"messages": [{
"id": "wamid.gBGGFlaCmZ9plHrf2Mh-o",
}]
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint Params ● Phone-number-id This is an ID for each phone number


registered to whatsapp business platform. More details here

Options
For more details on how to send template messages check the docs
here. Components can vary based on the params set on the template
creation.

Response Details ● As per the normal send message api response. Details here

Details Businesses will call this API to send a call request permission message
to a WhatsApp consumer account. This message will be charged as per
the assigned template category.
Note: The contents of the call permission component cannot be edited
by the businesses.

Possible Errors ● Invalid phone-number-id


● Permissions/Authorization errors
● Rate limit reached
● Sending this message to users on older app versions will result
in error webhook with error code 131026
● Calling not enabled
More details on Cloud API Error codes here.
Note: In addition, the usual message status webhooks will also be delivered for the call permission request message. Details on the message
status webhooks here.

Webhook: Receiving a Call Permission Approval Response


{
"object": "whatsapp_business_account",
"entry": [{
"id": "{phone-number-id}",
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": {phone-number},
"phone_number_id": {phone-number-id}
},
"contacts": [{
"profile": {
"name": "NAME"
},
"wa_id": {phone-number}
}],
"messages": [{
"from": {phone-number},
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": {TIMESTAMP},
"context": {
"from": "{phone-number}",
"id": "wamid.gBGGFlaCmZ9plHrf2Mh-o"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response": "accept",
"expiration_timestamp": {timestamp},
"response_source": "[user_action|automatic]"
}
}
],
},
"field": "messages"
}]
}]
}

Field Name Description

id Unique ID created for the message

from Message sender

timestamp Unix timestamp in seconds of the webhook event

interactive Structure that contains the details of the whatsapp consumer account’s response
for the call permissions request message.
response Consumer’s response to the call permission request message

expiration_time Time in seconds when this call permission expires if the consumer approved it

response_source Source of this permission, possible values for accepted call permissions are
● user_action: User approved or rejected the permission
● [From June] automatic: automatic approval due to user initiated call

context Context is included for a message when a user “replies to” or interacts with one of
your messages. The ID in the context section will be based on the use case.

When the user responds to a Call Permission Request message sent by the
business, the message id of the call permission request message sent by the
business is included in the context section of the webhook

from Business phone number

id Id of the call permission request message this response is for

Webhook: Receiving a Call Permission Rejection Response


{
"object": "whatsapp_business_account",
"entry": [{
"id": "{phone-number-id}",
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": {phone-number},
"phone_number_id": {phone-number-id}
},
"contacts": [{
"profile": {
"name": "NAME"
},
"wa_id": {c-phone-number}
}],
"messages": [{
"from": {c-phone-number},
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": {TIMESTAMP},
"context": {
"from": "{phone-number}",
"id": "wamid.gBGGFlaCmZ9plHrf2Mh-o"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response": "reject”
"response_source": "[user_action|automatic]"
}
}
],
},
"field": "messages"
}]
}]
}

Field Name Description

id Unique ID created for the message

from Message sender

timestamp Unix timestamp of the webhook event in seconds

interactive Structure that contains the details of the whatsapp consumer account’s response
for the call permissions request message.

response Consumer’s response to the call permission request message

response_source Source of this permission, possible values for rejected call permissions
● user_action: User approved or rejected the permission
● automatic: automatic rejection due to unanswered call limits

context Context is included for a message when a user “replies to” or interacts with one of
your messages. The ID in the context section will be based on the use case.

When the user responds to a Call Permission Request message sent by the
business, the message id of the call permission request message sent by the
business is included in the context section of the webhook

from Business phone number

id Id of the call permission request message sent to the consumer

Webhook: Receiving a Call Permission from the Callback flow


{
"object": "whatsapp_business_account",
"entry": [{
"id": "{phone-number-id}",
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": {phone-number},
"phone_number_id": {phone-number-id}
},
"contacts": [{
"profile": {
"name": "NAME"
},
"wa_id": {c-phone-number}
}],
"messages": [{
"from": {c-phone-number},
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": {TIMESTAMP},
"context": {
"from": "{phone-number}",
"id": "wacid.gBGGFlaCmZ9plHrf2Mh-o"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response":"accept",
"expiration_timestamp": {timestamp},
"response_source": "[user_action|automatic]"
}
}
],
},
"field": "messages"
}]
}]
}

Field Name Description

id Unique ID created for the message

from Message sender

timestamp Unix timestamp of the webhook event in seconds


interactive Structure that contains the details of the whatsapp consumer account’s response
for the call permissions request message.

response Consumer’s response to the call permission request message

expiration_time Time in seconds when this call permission expires if the consumer approved it

response_source Source of this permission, possible values for callback


● [Before June ] user_action: User approved or rejected the permission
● [After June] automatic: automatic approval due to user initiated call

context Context is included for a message when a user “replies to” or interacts with one of
your messages. The ID in the context section will be based on the use case.

When the user provides a permission after a missed consumer initiated call, the call
id of the user initiated call missed by the business is included in the context
section.
The business will receive the usual call webhooks for this call when the call
happens.

from Business phone number

id Id of the call permission request message sent to the consumer

Calling APIs

New Call API

Description Start a new call

Endpoint POST /{phone-number-id}/calls

Request Body {
"messaging_product": "whatsapp",
"to":"14085551234",
"action": "connect",
"session" : {
"sdp_type" : "offer",
"sdp" : "<<RFC 4566 SDP>>"
},
"biz_opaque_callback_data": "random data"
}

Response {
"messaging_product": "whatsapp",
"calls" : [{
"id" : "wacid.ABGGFjFVU2AfAgo6V",
}]
}

Error Response {
"error": {
"message": "<Error Message>",
"type": "<Exception Type>",
"code": <Exception Code>,
}
}

Endpoint Params ● Phone-number-id This is an ID for each phone number registered to whatsapp
business platform. More details here

Request Body
Params ● to: Number to which the voice call is being made. Country codes are required. More
info about accepted formats here.
● session: Indicates connection information/event pertaining to this call session. It need
two parameters
○ sdp: SDP info of the device on the other end of the call. Example structure in
appendix. Sdp must be compliant with RFC 4566.
○ sdp_type: "offer" - to indicate sdp offer
● biz_opaque_callback_data [Optional]:
○ An arbitrary string, useful for tracking.
○ Any app subscribed to the calls webhook field on the WhatsApp Business
Account can get this string. It is included within the subsequent webhook
payloads: “calls” object within Connect Webhook payload, “statuses” object
within Status Webhook payload and “calls” object within Terminate Webhook
payload
○ Cloud API does not process this field, it just returns it as part of webhooks
○ Maximum 512 characters.

Response Details ● id: Unique Id created to identify every business call

Details Businesses will call this API to start a call by providing a call receiver’s number and a webrtc
call offer.

Possible Errors ● Invalid phone-number-id


● Permissions/Authorization errors
● Request format validation errors eg connection info, sdp, ice etc
● SDP validation errors around

More details on Cloud API Error codes here.

Hanging up an active call


Note: There are no changes for this API and works the same as a business terminating a consumer initiated call

Calling Webhooks
The structure of webhooks is similar to the structure of the webhooks used for Messaging in Cloud API. Detailed documentation of
the webhooks can be found here.
A "calls" section in the "value" section of the webhook contains calls related fields.

Connect: Receive answer SDP from Cloud API to initiate media connection
This webhook is sent in response to a new call request received from the business.
- This webhook is sent to signal the business to establish the call WebRTC connection by invoking the API /calls
action=connect
- This webhook contains the answer SDP information to establish WebRTC connection
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16315553601",
"phone_number_id": "phone-number-id",
},
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V",
"to": "16315553601",
"from": "16315553602",
"event": "connect",
"timestamp": "1671644824",
"direction": "BUSINESS_INITIATED",
// connection is to be deprecated, use session
"connection": {
"webrtc": {
"sdp": {..<<SDP data>>..}
}
},
"session": {
"sdp_type": "answer"
"sdp": "<<RFC 4566 SDP>>"
},
"biz_opaque_callback_data": "random data",
}
]
},
"field": "calls"
}
]
}
]
}

Field Name Description

id Unique ID created for a call

to Callee of the call

from Caller of the call

event The event this webhook notifies the listener about

timestamp Timestamp of the webhook event

session Indicates connection information/event pertaining to this call session. It will have
the below two parameters

sdp Session Description Protocol data for the device on the other end of the call.
Example structure in appendix. Sdp must be compliant with RFC 4566

sdp_type Type of the sdp can be "offer" or "answer" depending on whether the call is
business initiated or consumer initiated respectively.

biz_opaque_callb [Optional] Will only be available if provided through New Call API Requests
ack_data

Call Status Webhooks: Receive notification on events for a business initiated call
This webhook is sent on certain events for a business initiated call. More specifically the status webhook will be sent on the following events.

1. Ringing: When the business initiated call begins Ringing on the WhatsApp consumer’s device
2. Accepted: When the WhatsApp consumer accepts the business initiated call
3. Rejected: When the business initiated call is Rejected by the WhatsApp consumer
The Webhook structure here is similar to the Status webhooks used for the Cloud API messages. More details on the current status
webhook structure here.
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16315553601",
"phone_number_id": "phone-number-id",
},
"statuses": [{
"id": "wacid.ABGGFjFVU2AfAgo6V",
"timestamp": "1671644824",
"type": "call"
"status": "[RINGING|ACCEPTED|REJECTED]",
"recipient_id": "16315553601",
"biz_opaque_callback_data": "random data",
]
},
"field": "calls"
}
]
}
]
}
Field Name Description

statuses This section contains information about the statuses.

id ID of the call this status is for

type The type this status webhook is for. Another possible value here is "message".

recipient_id The phone number for the WhatsApp consumer this call is to

timestamp Timestamp of the webhook event

status status of the call this webhook is communicating


- RINGING: Business initiated call is ringing the user
- ACCEPTED: Business initiated call is accepted by the user
- REJECTED: Business initiated call is rejected by the user

biz_opaque_callb [Optional] Will only be available if provided through New Call API Requests
ack_data

Terminate: Receive notification about call termination


This is same as terminate webhook for user initiated calls
Business to Consumer Call Sequence Diagram

Note: Accepted webhook will usually always arrive after the call has been established. It is primarily sent for call event auditing purposes.

Business to Consumer Call Flow


Prereqs:
● [One time effort] Subscribe to the messages and calls webhook fields
● [For every call] Ensure a conversation is opened with a consumer. More on how to open conversations here

1) Business sends a call permission request message to the consumer


POST {phone-number-id}/messages
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "<c-phone-number> or <wa_id>",
"type": "interactive",
"interactive": {
"type": "call_permission_request",
"action": {
"name": "call_permission_request"
}
}
}
2) Business receives a response with a message Id
{
"messaging_product": "whatsapp",
"contacts":[{
"input": "{c-phone-number}",
"wa_id": "{wa_id}"
}],
"messages":[{
"id": "wamid.HBgLMTQxMjYxMzYyNTMVAgAR"
}]
}

3) Message status webhooks are received as detailed here.

4) Consumer responds to the call permission request with an approval


{
"object": "whatsapp_business_account",
"entry": [{
"id": "{phone-number-id}",
"changes": [{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": {phone-number},
"phone_number_id": {phone-number-id}
},
"contacts": [{
"profile": {
"name": "NAME"
},
"wa_id": {c-phone-number}
}],
"messages": [{
"from": {c-phone-number},
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": {TIMESTAMP},
"context": {
"from": "{phone-number}",
"id": "wamid.HBgLMTQxMjYxMzYyNTMVAgAR"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response": APPROVE,
"expiration_time": {timestamp}
}
}],
},
"field": "messages"
}]
}]
}

5) Business initiates a new call with the /calls api with the below Request body
POST {phone-number-id}/calls
{
"messaging_product": "whatsapp",
"to":"{c-phone-number}",
"action":"connect",
"session" : {
"sdp_type" : "offer",
"sdp" : "<<RFC 4566 SDP>>"
}
}

6) Business gets the below response with a call-id from Cloud API. Response with error code 138006 indicates lack of a call
request permission for this number by the consumer account.
{
"messaging_product": "whatsapp",
"calls" : [
"id" : "wacid.ABGGFjFVU2AfAgo6V",
]
}

7) Business receives a webhook with the sdp answer from Cloud API
{
"entry":
[
{
"changes":
[
{
"field": "calls",
"value":
{
"calls":
[
{
"from": "{phone-number}",
"session": {
"sdp": "RFC 4566 SDP",
"sdp_type": "answer"
},
"connection": {
"webrtc": {
"sdp": {..<<SDP data>>..}
}
},
"id": "wacid.ABGGFjFVU2AfAgo6V",
"to": "{c-phone-number}",
"event": "connect",
"timestamp": "1716496634",
"direction": "BUSINESS_INITIATED"
}
],
"metadata":
{
"phone_number_id": "{phone-number-id}",
"display_phone_number": "{phone-number}"
},
"messaging_product": "whatsapp"
}
}
],
"id": "{phone-number-id}"
}
],
"object": "whatsapp_business_account"
}

8) Business receives appropriate status webhooks for the call


{
"entry":
[
{
"changes":
[
{
"field": "calls",
"value":
{
"statuses":
[
{
"id": "wacid.ABGGFjFVU2AfAgo6V",
"type": "call",
"status": "[RINGING|ACCEPTED|REJECTED]",
"timestamp": "1716496655",
"recipient_id": "{c-phone-number}"
}
],
"metadata":
{
"phone_number_id": "{phone-number-id}",
"display_phone_number": "{phone-number}"
},
"messaging_product": "whatsapp"
}
}
],
"id": "{phone-number-id}"
}
],
"object": "whatsapp_business_account"
}

9) The business may terminate the call by invoking the /calls api with the below Request body
POST {phone-number-id}/calls
{
"messaging_product": "whatsapp",
"call_id": "wacid.ABGGFjFVU2AfAgo6V",
"action" : "terminate"
}

10) The Business would receive the below response confirming the action
{
"success" : true
}

11) The Business would eventually receive the terminate webhook once the call has been disconnected or if the call was disconnected by
the whatsapp consumer
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "{phone-number-id}",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "{phone-number}",
"phone_number_id": "{phone-number-id}",
},
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"to": "{c-phone-number}",
"from": "{phone-number}",
"event": "terminate"
"direction"s: "BUSINESS_INITIATED",
"timestamp": "1671644824",
"status" : [Failed | Completed],
"start_time" : "1671644824",
"end_time" : "1671644944",
"duration" : 120
}
]
},
"field": "calls"
}
]
}
]
}

Sample SDP Offer Structure for a Business Initiated call


This is an example SDP Offer structure.

v=0
o=- 3626166318745852955 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-semantic: WMS d8b26053-4474-4eb7-b3c3-c93d6c8c9b2e
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 0 8 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:4g1c
a=ice-pwd:qY/Bb+jQzg5ICn6X4fhJQetk
a=ice-options:trickle
a=fingerprint:sha-256
35:47:24:24:9F:93:C4:3E:DB:37:7F:BB:ED:F8:20:B5:AD:AC:DC:35:C2:7D:67:EE:6C:35:54:DF:A6:00:5C:4A
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=sendrecv
a=msid:d8b26053-4474-4eb7-b3c3-c93d6c8c9b2e 5b4d3d96-ea9b-44a8-87e6-11a1ad21a3bc
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:63 red/48000/2
a=fmtp:63 111/111
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
a=ssrc:2220762577 cname:w/zwpg3jXNiTFTdZ
a=ssrc:2220762577 msid:d8b26053-4474-4eb7-b3c3-c93d6c8c9b2e 5b4d3d96-ea9b-44a8-87e6-11a1ad21a3bc

Sample SDP Answer Structure for a Business Initiated call


This is an example SDP Answer structure.

v=0
o=- 741807839102053725 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-semantic: WMS 798a9670-c0d6-47a8-925e-5f082ef4d8a0
a=ice-lite
m=audio 3482 UDP/TLS/RTP/SAVPF 111 9 0 8 110 126
c=IN IP4 31.13.65.130
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:2754936280 1 udp 2113937151 31.13.65.130 3482 typ host generation 0 network-cost 50
ufrag JHqAXFH4HcAY/8
a=candidate:1581496399 1 udp 2113939711 2a03:2880:f211:d1:face:b00c:0:699c 3482 typ host generation
0 network-cost 50 ufrag JHqAXFH4HcAY/8
a=ice-ufrag:JHqAXFH4HcAY/8
a=ice-pwd:dNNMmR8wUcGezvfBZOO0Qgcwl2m86GP/
a=ice-options:trickle
a=fingerprint:sha-256
9C:97:5C:4C:A9:BE:9E:2F:06:94:F5:BB:38:2C:A1:29:B5:69:B8:FA:94:10:56:1D:0B:5D:80:28:C1:FD:F0:F6
a=setup:active
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
a=ssrc:3407645770 cname:bg8KQDoIk2UJa6sf
a=ssrc:3407645770 msid:798a9670-c0d6-47a8-925e-5f082ef4d8a0 audio#nuxVMf9EAJX
a=ssrc:3407645770 mslabel:798a9670-c0d6-47a8-925e-5f082ef4d8a0
a=ssrc:3407645770 label:audio#nuxVMf9EAJX

Open Issues

Business opaque data


You can associate an arbitrary string to a specific call and receive the same string in the webhooks related to that call. This is supported via the
‘biz_opaque_callback_data’ field in New call API and Accept call API and the same is then available in all call related webhooks.

Test Business Phone Numbers


You can use Test Business Phone Numbers if you’re looking for a temporary phone number for testing your integration. For example, if you’ve
trouble procuring a number in our supported country list, you can use this feature to get a number in the US that can work with calling.

When developers add the WhatsApp product to their app for the first time, Meta automatically creates the following test resources (per Step 1:
Add The WhatsApp Product To Your App):
● Test WhatsApp Business Account (with the same name)
● Test Phone Number (1-555-xxx-xxx)

These resources are intended for testing only and allow a limited number of messages, calls and recipients.

To find and configure your test number go to the “App Dashboard”


1. Navigate to “Business Settings”
2. Navigate to “Accounts” → “Apps”
3. Select your calling-enabled app
4. Click “Open in App Dashboard “ on the top right
5. Navigate to “WhatsApp” → “API Setup”

Shortcut: https://developers.facebook.com/apps/<Enter your app ID>

If you don’t already have a test number, request one on this page (See ‘Get new test number’ in the From dropdown):

Follow the UI prompts to configure the allowed phone number recipients. For detailed instructions and restrictions see developer docs.
Webhook direction change [ETA: Sep, 2024]
As part of Graph API v21 release, the direction field in the webhooks will change from “INCOMING” to “USER_INITIATED” and “OUTGOING”
to “BUSINESS_INITIATED”.
Previous values (INCOMING/OUTGOING) will continue to be used in v20 and below until Jan 2 2025.

After Jan 2 2025, ALL API versions will use “USER_INITIATED” and “BUSINESS_INITIATED”.

Appendix
Sample Meta SDP Offer Structure
This is an example SDP Offer structure.

v=0
o=- 7602563789789945080 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS 6932bc1c-db1a-4abe-b437-0c4168be8a13
a=ice-lite
m=audio 40012 UDP/TLS/RTP/SAVPF 111 126
c=IN IP4 31.13.65.60
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:1972637320 1 udp 2113937151 31.13.65.60 40012 typ host generation 0 network-cost 50 ufrag 6k2qP1R6kBfI/2
a=candidate:1652262791 1 udp 2113939711 2a03:2880:f211:cf:face:b00c:0:6443 40012 typ host generation 0 network-cost 50 ufrag
6k2qP1R6kBfI/2
a=ice-ufrag:6k2qP1R6kBfI/2
a=ice-pwd:UApvJw3NcwFRDvIMKdM0vWCdlXah25E9
a=fingerprint:sha-256 1B:B6:6B:40:A5:0B:8C:75:0D:8C:CB:90:2F:99:74:1E:26:45:AE:AF:45:C1:51:60:8F:73:C9:2D:10:6D:8A:88
a=setup:actpass
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=ssrc:4208138518 cname:gAXq2V9TKltrnapv
a=ssrc:4208138518 msid:6932bc1c-db1a-4abe-b437-0c4168be8a13 audio#R5wfXFcdmT6
a=ssrc:4208138518 mslabel:6932bc1c-db1a-4abe-b437-0c4168be8a13
a=ssrc:4208138518 label:audio#R5wfXFcdmT6

Sample BSP SDP Answer Structure


This is an example SDP Answer structure.

v=0
o=- 2822644248144643933 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS eb909cf0-87f0-4358-a4c9-7861680d9431
m=audio 9 UDP/TLS/RTP/SAVPF 111 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:X1ho
a=ice-pwd:7fJSbV2N5qWiA5QiDKwK3vuh
a=fingerprint:sha-256 2E:35:9F:21:9E:63:72:E5:42:74:76:2D:B3:70:F7:CB:24:14:9B:14:52:71:05:48:DA:4D:67:31:09:58:2A:ED
a=setup:active
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=ssrc:330833028 cname:EDc1JutBl8rwHQc2
a=ssrc:330833028 msid:eb909cf0-87f0-4358-a4c9-7861680d9431 ea478c16-d9f7-493c-8cec-19bfac750a36

You might also like