Getting Started
Contact us to enable the Calling API feature
The Calling API is restricted to whitelisted accounts. Contact us to request access.
Configure/Update business phone number calling settings
Use this endpoint Configure Call Settings API to update call settings configuration for an individual business phone number.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings'\
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"calling": {
"status": "ENABLED",
"iconVisibility": "DEFAULT"
}
}'
Use this endpoint Get Call Settings API to check the configuration of your Calling API feature settings. This endpoint can return information for other Cloud API feature settings.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings'\
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}'
Calling Eligibility
To qualify for Calling API features, your business must have a messaging limit of at least 1000 business-initiated conversations in a rolling 24-hour period.
Settings calling webhooks
You need to subscribe to the following webhook events:
- whatsapp-calling-connect-webhook
- whatsapp-calling-status-update-webhook
- whatsapp-calling-terminate-webhook
User-initiated calling flow
Sequence Diagram

Part 1: A WhatsApp user calls your business from their client app
When a WhatsApp user calls your business, a Call Connect webhook will be triggered with an SDP Offer, see User-initiated Calling Connect Webhook
Webhook sample
{
"id": "evt_6757b723a5a42d369ef48480",
"type": "whatsapp.call.connect",
"apiVersion": "v2",
"createTime": "2024-12-10T03:36:03.749Z",
"callingConnect": {
"id": "6757b723960b25543b9ecc66",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABIYIEF",
"phoneId": "461269257068831",
"from": "+6281361905133",
"to": "+6283138205150",
"direction": "USER_INITIATED",
"dialTime": 1733826430000,
"sdpType": "offer",
"sdp": "<<RFC 4566 OFFER SDP>>"
}
}
Part 2: Your business pre-accepts the call (Recommended)
In essence, when you pre-accept an inbound call, you are allowing the calling media connection to be established before attempting to send call media through the connection.
Pre-accepting calls is recommended because it facilitates faster connection times and avoids audio clipping issues.
To pre-accept, make a request to the Pre-accept an inbound call endpoint.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/calls/preAccept' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"phoneId": "461269257068832",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTEKKSESFF32343242SE",
"sdpType": "answer",
"sdp": "<<RFC 4566 ANSWER SDP>>"
}'
Note
A business uses the SDP offer from a webhook to create an SDP answer via WebRTC, then calls the pre-answer interface.
Part 3: Your business accepts the call after the WebRTC connection is made
Once the WebRTC connection is made on your end, you can accept the call.
Once you accept the call, wait until you receive a 200 OK back from the endpoint. Media will begin flowing immediately since the connection was established prior to call connect.
You can now call the Accept an inbound call endpoint to accept the call.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/calls/accept' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"phoneId": "461269257068832",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTEKKSESFF32343242SE",
"sdpType": "answer",
"sdp": "<<RFC 4566 ANSWER SDP>>"
}'
Use this endpoint to reject a call.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/calls/reject' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"phoneId": "461269257068832",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTE"
}'
Part 4: Your business or the WhatsApp user terminates the call
Both the business or the WhatsApp user can terminate the call at any time.
You call the Terminate a WhatsApp call endpoint with the following request body to terminate the call.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/calls/terminate' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"phoneId": "461269257068832",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTE"
}'
A webhook notification whatsapp-calling-terminate-webhook is sent whenever a call ends, for any reason. This includes when the WhatsApp user hangs up, or when the business sends a terminate or reject request to the endpoint.
Webhook sample
{
"id": "evt_6757b889a5a42d369ef48481",
"type": "whatsapp.call.terminate",
"apiVersion": "v2",
"createTime": "2024-12-10T03:42:01.822Z",
"callingTerminate": {
"id": "6757b889960b25543b9ecc67",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTE",
"phoneId": "461269257068832",
"from": "+6281361905133",
"to": "+6283138205150",
"direction": "USER_INITIATED",
"startTime": 1733734738000,
"endTime": 1733734771000,
"duration": 33,
"status": "COMPLETED"
}
}
Note
There is about 30 to 60 seconds after the User-initiated Calling Connect Webhook is sent for the business to accept the phone call. If the business does not respond, the call is terminated on the WhatsApp user side with a "Not Answered" notification and a whatsapp-calling-terminate-webhook is delivered back to you.
Since the WebRTC connection is established before calling the Accept an inbound WhatsApp call, make sure to flow the call media only after you receive a 200 OK response back.
If call media flows too early, the caller will miss the first few words of the call. If call media flows too late, callers will hear silence.
Business-initiated calling flow
Part 1: Obtain permission to call the WhatsApp user
Obtaining call permissions from the WhatsApp user can be done in one of the following ways:
Send a call permission request message
You can request call permissions by sending the WhatsApp user a permission request, either as a free form message during an open customer service window, or by using a template message that contains the request.
- send a free form call permission request
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/messages/sendDirectly' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-H 'Content-Type: application/json' \
-d '{
"from": "{{BUSINESS-PHONE-NUMBER}}",
"to": "{{CUSTOMER-PHONE-NUMBER}}",
"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-12853."
}
}
}'
- send a template call permission request
Code sample(create message template)
curl 'https://api.ycloud.com/v2/whatsapp/templates' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"wabaId": "{{WABA-ID}}",
"name": "call_permission_request_template",
"language": "en_US",
"category": "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"
}
]
}'
Code sample(send message template)
curl 'https://api.ycloud.com/v2/whatsapp/messages/sendDirectly' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"from": "{{BUSINESS-PHONE-NUMBER}}",
"to": "{{CUSTOMER-PHONE-NUMBER}}",
"type": "template",
"template": {
"name": "call_permission_request_template",
"language": {
"code": "en_US",
"policy": "deterministic"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "John Smith"
},
{
"type": "text",
"text": "order #1522"
}
]
}
]
}
}'
Enable callback_permission_status in call settings
When callback_permission_status is enabled, the user automatically provides call permission to your business when they place a call to you.
WhatsApp user grants permanent permissions
The user can also grant permanent permissions to the business at any time through their business profile.
User calling permission request webhook
This webhook is sent back after requesting user calling permissions. Lastly, the user can grant permanent calling permission to the business, which is represented in the is_permanent parameter below.
Webhook sample
{
"id": "evt_6772458a2b4b206adc55f094",
"type": "whatsapp.inbound_message.received",
"apiVersion": "v2",
"createTime": "2024-12-30T07:02:34.899Z",
"whatsappInboundMessage": {
"id": "6772458abeea6edef0d4f4a6",
"wamid": "wamid.HBgNNjI4MTM2MTkwNTEzMxUCABEYEkM0Q",
"wabaId": "188234691048809",
"from": "+6281361905133",
"customerProfile": {
"name": "Erin.liu"
},
"to": "+6283138205150",
"sendTime": "2024-12-30T06:33:33.000Z",
"type": "interactive",
"interactive": {
"type": "call_permission_reply",
"call_permission_reply":{
"response":"[accept|reject]",
"is_permanent":false,
"expiration_timestamp": "{timestamp}",
"response_source": "[user_action|automatic]"
}
},
"context": {
"from": "6283138205150",
"id": "wamid.HBgNNjI4MTM2MTkwNTEzMxUCABEYEkM0Q"
}
}
}
Part 2: Your business initiates a new call to the WhatsApp user
Now that you have user permission, you can initiate a new call to the WhatsApp user in question.
You can now call the Initiate an outbound WhatsApp call endpoint with the following request body to initiate a new call.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/calls/connect' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"from": "+62831382000",
"to": "+6281369051330",
"sdpType": "offer",
"sdp": "<<RFC 4566 OFFER SDP>>"
}'
Note
Response with error code 138006 indicates a lack of a call request permission for this business number from the WhatsApp user.
Part 3: You establish the call connection using webhook signaling
After successful initiation of a new call, you will receive Business-initiated Calling Connect Webhook response that contains an SDP Answer. Critically, the webhook contains information required to establish a call connection via WebRTC.
Webhook sample
{
"id": "evt_676e5a0d7a9cb742d02d7645",
"type": "whatsapp.call.connect",
"apiVersion": "v2",
"createTime": "2024-12-27T07:41:01.554Z",
"callingConnect": {
"id": "676e5a0d94c533526d3c5ad5",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE",
"phoneId": "461269257068832",
"from": "+6283138205150",
"to": "+6283138205150",
"direction": "BUSINESS_INITIATED",
"sdpType": "answer",
"sdp": "<<RFC 4566 ANSWER SDP>>",
"dialTime": 1735283452000
}
}
Once you receive the Call Connect webhook, you can apply the SDP Answer recieved in the webhook to your WebRTC stack in order to initiate the media connection.
A webhook is dispatched upon the ringing event on the WhatsApp user's client device.
Webhook sample
{
"id": "evt_676e5ab57a9cb742d02d7646",
"type": "whatsapp.call.status.updated",
"apiVersion": "v2",
"createTime": "2024-12-27T07:41:28.422Z",
"callingStatusUpdated": {
"wabaId": "188234691048809",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE",
"status": "RINGING",
"recipientPhone": "+6281361905133"
}
}
A webhook is dispatched upon the call acceptance event by the WhatsApp user.
Webhook sample
{
"id": "evt_67724ad42b4b206adc55f099",
"type": "whatsapp.call.status.updated",
"apiVersion": "v2",
"createTime": "2024-12-27T07:42:00.577Z",
"callingStatusUpdated": {
"wabaId": "188234691048809",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE",
"status": "ACCEPTED",
"recipientPhone": "+6281361905133"
}
}
A webhook is dispatched upon the call rejection event by the WhatsApp user, triggering the call terminate webhook.
Webhook sample
{
"id": "evt_6757b889a5a42d369ef48481",
"type": "whatsapp.call.terminate",
"apiVersion": "v2",
"createTime": "2024-12-10T03:42:01.822Z",
"callingTerminate": {
"id": "6757b889960b25543b9ecc67",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTE",
"phoneId": "461269257068832",
"from": "+6281361905133",
"to": "+6283138205150",
"direction": "USER_INITIATED",
"startTime": 1733734738000,
"endTime": 1733734771000,
"duration": 33,
"status": "COMPLETED"
}
}
Part 4: Your business or the WhatsApp user terminates the call
Both you or the WhatsApp user can terminate the call at any time.
You call the Terminate a WhatsApp call endpoint with the following request body to terminate the call.
Code sample
curl 'https://api.ycloud.com/v2/whatsapp/calls/terminate' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {{YOUR-API-KEY}}' \
-d '{
"phoneId": "461269257068832",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTE"
}'
When either the business or the WhatsApp user terminates the call, you receive a whatsapp-calling-terminate-webhook
Webhook sample
{
"id": "evt_6757b889a5a42d369ef48481",
"type": "whatsapp.call.terminate",
"apiVersion": "v2",
"createTime": "2024-12-10T03:42:01.822Z",
"callingTerminate": {
"id": "6757b889960b25543b9ecc67",
"wacid": "wacid.HBgNNjI4MTM2MTkwNTE",
"phoneId": "461269257068832",
"from": "+6281361905133",
"to": "+6283138205150",
"direction": "USER_INITIATED",
"startTime": 1733734738000,
"endTime": 1733734771000,
"duration": 33,
"status": "COMPLETED"
}
}