WhatsApp Calling Webhook Events (UIC & BIC)
1. Common envelope
Every webhook has the same V3 wrapper. Only field and the contents of value change.
| Key | Meaning |
|---|---|
object | Always whatsapp_business_account |
gs_app_id | Gupshup app ID. Filter on it when several apps share one webhook URL |
entry[].id | WABA ID |
entry[].changes[].field | calls for every call event and call status. messages for the call-permission request statuses and reply |
value.messaging_product | Always whatsapp |
value.metadata | Business display_phone_number and phone_number_id |
value.contacts[] | The user: wa_id, user_id (BSUID, only when the app has BSUID enabled), profile.name when known |
value.calls[] | Call events: connect, terminate, call_recording_available, call_transcript_available |
value.statuses[] | Call progress for BIC only (type: "call", status: RINGING, ACCEPTED), or message statuses for the permission request |
calls[].id / statuses[].id | The call ID (wacid.…). The same for every event of one call |
timestamp | Unix seconds, as strings, for call events. Permission-request status enqueued uses milliseconds, as a number |
2. User-initiated call (UIC)
Sequence
User taps call in WhatsApp
│
├─► connect (direction USER_INITIATED, user's SDP offer) ~1 s after the user dials
│
│ Business → Gupshup /v1/event pre_accept (optional) → accept (+ recording / transcription)
│ Must happen while it rings (about 30 s)
│
├─► terminate (status COMPLETED, duration, start_time, end_time) at hang-up
│
├─► call_transcript_available ┐ 20–60 s after terminate,
└─► call_recording_available ┘ in either order
If the call is not accepted, only connect and terminate arrive. The terminate has status: COMPLETED, no duration / start_time / end_time, and comes 30–60 s after connect. No recording or transcript follows. UIC has no RINGING / ACCEPTED status webhooks.
2.1 connect (UIC)
connect (UIC)When: as soon as the user dials, while the call is ringing.
Use it to: get the call ID and the user's SDP offer, build your SDP answer, and accept with POST /partner/app/{appId}/v1/event.
Field (calls[0]) | Description |
|---|---|
id | Call ID. Send it as voice.id in pre_accept, accept, reject and terminate |
event | connect |
direction | USER_INITIATED |
from / from_user_id | The caller's number and BSUID |
to | The business number |
timestamp | When the call was offered |
session.sdp_type / session.sdp | The user's SDP offer (Meta format). Build your answer from it |
connection.webrtc.sdp | The same offer as a JSON string {"type":"offer","sdp":"…"} (Gupshup addition) |
value.contacts[0].profile.name | The caller's WhatsApp name |
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"connection": {
"webrtc": {
"sdp": "{\"type\":\"offer\",\"sdp\":\"v=0\\r\\no=- 1791965720257 2 IN IP4 127.0.0.1\\r\\ns=-\\r\\nt=0 0\\r\\na=group:BUNDLE audio\\r\\na=msid-semantic: WMS 4eab4c32-ceb5-4e64-8485-36601d274b04\\r\\na=ice-lite\\r\\nm=audio 3480 UDP/TLS/RTP/SAVPF 111 126\\r\\nc=IN IP4 57.144.43.49\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=candidate:2275956755 1 udp 2122260223 57.144.43.49 3480 typ host generation 0 network-cost 50\\r\\na=candidate:2684782176 1 udp 2122262783 2a03:2880:f312:131:face:b00c:0:699c 3480 typ host generation 0 network-cost 50\\r\\na=ice-ufrag:XLOGqZFMDClCrlmA\\r\\na=ice-pwd:m/1+pOzznd9n8T+QtBJdCw==\\r\\na=fingerprint:sha-256 B2:B4:F4:B8:E2:4D:5A:38:77:6C:18:F7:0D:FB:8C:42:D4:C2:1E:FA:3E:97:4E:58:4C:90:A0:3D:2C:2B:6F:85\\r\\na=setup:actpass\\r\\na=mid:audio\\r\\na=sendrecv\\r\\na=msid:4eab4c32-ceb5-4e64-8485-36601d274b04 WhatsAppTrack1\\r\\na=rtcp-mux\\r\\na=rtpmap:111 opus/48000/2\\r\\na=rtcp-fb:111 transport-cc\\r\\na=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1\\r\\na=rtpmap:126 telephone-event/8000\\r\\na=maxptime:20\\r\\na=ptime:20\\r\\na=ssrc:3190104950 cname:WhatsAppAudioStream1\\r\\n\"}"
}
},
"direction": "USER_INITIATED",
"event": "connect",
"from": "<USER_WA_ID>",
"from_user_id": "<USER_BSUID>",
"id": "wacid.IhggMDA2ODE3RDRCQTI4NjFDMDZFRkVCOEU0NjI3QjY4QUQcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"session": {
"sdp": "v=0\r\no=- 1791965720257 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio\r\na=msid-semantic: WMS 4eab4c32-ceb5-4e64-8485-36601d274b04\r\na=ice-lite\r\nm=audio 3480 UDP/TLS/RTP/SAVPF 111 126\r\nc=IN IP4 57.144.43.49\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=candidate:2275956755 1 udp 2122260223 57.144.43.49 3480 typ host generation 0 network-cost 50\r\na=candidate:2684782176 1 udp 2122262783 2a03:2880:f312:131:face:b00c:0:699c 3480 typ host generation 0 network-cost 50\r\na=ice-ufrag:XLOGqZFMDClCrlmA\r\na=ice-pwd:m/1+pOzznd9n8T+QtBJdCw==\r\na=fingerprint:sha-256 B2:B4:F4:B8:E2:4D:5A:38:77:6C:18:F7:0D:FB:8C:42:D4:C2:1E:FA:3E:97:4E:58:4C:90:A0:3D:2C:2B:6F:85\r\na=setup:actpass\r\na=mid:audio\r\na=sendrecv\r\na=msid:4eab4c32-ceb5-4e64-8485-36601d274b04 WhatsAppTrack1\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1\r\na=rtpmap:126 telephone-event/8000\r\na=maxptime:20\r\na=ptime:20\r\na=ssrc:3190104950 cname:WhatsAppAudioStream1\r\n",
"sdp_type": "offer"
},
"timestamp": "1791965720",
"to": "919355040978"
}
],
"contacts": [
{
"profile": {
"name": "<USER_NAME>"
},
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}2.2 terminate (UIC)
terminate (UIC)When: the call ends (hang-up by either side, terminate API, or not answered in time).
Field (calls[0]) | Description |
|---|---|
status | COMPLETED, seen for both answered and unanswered calls |
duration | Connected seconds. Missing if the call was never accepted |
start_time / end_time | Unix seconds for when the call was answered and when it ended. Missing if not accepted |
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"direction": "USER_INITIATED",
"duration": 21,
"end_time": "1791965786",
"event": "terminate",
"from": "<USER_WA_ID>",
"from_user_id": "<USER_BSUID>",
"id": "wacid.IhggMDA2ODE3RDRCQTI4NjFDMDZFRkVCOEU0NjI3QjY4QUQcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"start_time": "1791965765",
"status": "COMPLETED",
"timestamp": "1791965786",
"to": "919355040978"
}
],
"contacts": [
{
"profile": {
"name": "<USER_NAME>"
},
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}2.3 call_transcript_available (UIC)
call_transcript_available (UIC)See section 4 for the fields.
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"call_transcript": {
"document": {
"id": "2231824211080035",
"mime_type": "application/json",
"sha256": "6c0528660189bcc705ae2b4e400fc972e00a2bac5b78afef5954cff627e88784",
"url": "https://<gupshup-media-host>/wa/<APP_ID>/wa/media/2231824211080035?download=false"
}
},
"event": "call_transcript_available",
"from": "<USER_WA_ID>",
"from_user_id": "<USER_BSUID>",
"id": "wacid.IhggMDA2ODE3RDRCQTI4NjFDMDZFRkVCOEU0NjI3QjY4QUQcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"timestamp": "1791965807",
"to": "919355040978"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}2.4 call_recording_available (UIC)
call_recording_available (UIC)See section 4 for the fields.
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"call_recording": {
"audio": {
"id": "1607646396863177",
"mime_type": "audio/ogg; codecs=opus",
"sha256": "593145eb1a8ff9137cc3eaa0bf6b33c6c0e79a131d84aae2468420e837bfb443",
"url": "https://<gupshup-media-host>/wa/<APP_ID>/wa/media/1607646396863177?download=false"
},
"type": "audio"
},
"event": "call_recording_available",
"from": "<USER_WA_ID>",
"from_user_id": "<USER_BSUID>",
"id": "wacid.IhggMDA2ODE3RDRCQTI4NjFDMDZFRkVCOEU0NjI3QjY4QUQcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"timestamp": "1791965821",
"to": "919355040978"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3. Business-initiated call (BIC)
Sequence
(once per user and business number)
Business → Gupshup /v3/message call_permission_request
├─► messages.statuses enqueued → sent → delivered → read
└─► messages.messages interactive.call_permission_reply (response: accept)
Business → Gupshup /v1/voice connect (+ SDP offer, recording / transcription)
│ ← 200 {"callId":{"message":"wacid…"},"status":"success"}
│
├─► statuses RINGING (type call) ~1 s after connect
├─► connect (direction BUSINESS_INITIATED, user's SDP answer) when the user answers
├─► statuses ACCEPTED (type call) right after the answer
│
├─► terminate (status COMPLETED, duration, start_time, end_time) at hang-up
│
├─► call_recording_available ┐ 20–60 s after terminate,
└─► call_transcript_available ┘ in either order
If the user has not allowed calls, /v1/voice returns 400 No approved call permission from the recipient… and no webhooks follow.
3.1 Call-permission request statuses (field: messages)
field: messages)When: after POST /partner/app/{appId}/v3/message with interactive.type: call_permission_request. They follow the normal message status flow. enqueued carries Gupshup's message ID (id = gs_id). sent, delivered and read carry Meta's wamid.
enqueued
enqueued{
"entry": [
{
"changes": [
{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"statuses": [
{
"gs_id": "54749858-4392-4c32-b3f3-93a5d0e92483",
"id": "1e03c4df-e669-4909-948d-db29bcf4211a",
"recipient_id": "<USER_WA_ID>",
"status": "enqueued",
"timestamp": 1791966140946
}
]
}
}
]
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}sent
sent{
"entry": [
{
"changes": [
{
"field": "messages",
"value": {
"contacts": [
{
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
},
"statuses": [
{
"biz_opaque_callback_data": "1e03c4df-e669-4909-948d-db29bcf4211a||||||1",
"conversation": {
"expiration_timestamp": "1791966143",
"id": "ce881a45011a80d3860aa0a0ee909153",
"origin": {
"type": "service"
}
},
"gs_id": "54749858-4392-4c32-b3f3-93a5d0e92483",
"id": "1e03c4df-e669-4909-948d-db29bcf4211a",
"meta_msg_id": "wamid.HBgMOTE3NTA2MDgwNDgwFQIAERgSODA0MzBDQzMzNEQxRkYyOUI0AA==",
"pricing": {
"billable": false,
"category": "service",
"pricing_model": "PMP",
"type": "free_customer_service"
},
"recipient_id": "<USER_WA_ID>",
"recipient_user_id": "<USER_BSUID>",
"status": "sent",
"timestamp": "1791966143"
}
]
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}delivered
delivered{
"entry": [
{
"changes": [
{
"field": "messages",
"value": {
"contacts": [
{
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
},
"statuses": [
{
"biz_opaque_callback_data": "1e03c4df-e669-4909-948d-db29bcf4211a||||||1",
"conversation": {
"id": "ce881a45011a80d3860aa0a0ee909153",
"origin": {
"type": "service"
}
},
"gs_id": "54749858-4392-4c32-b3f3-93a5d0e92483",
"id": "1e03c4df-e669-4909-948d-db29bcf4211a",
"meta_msg_id": "wamid.HBgMOTE3NTA2MDgwNDgwFQIAERgSODA0MzBDQzMzNEQxRkYyOUI0AA==",
"pricing": {
"billable": false,
"category": "service",
"pricing_model": "PMP",
"type": "free_customer_service"
},
"recipient_id": "<USER_WA_ID>",
"recipient_user_id": "<USER_BSUID>",
"status": "delivered",
"timestamp": "1791966144"
}
]
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}read
read{
"entry": [
{
"changes": [
{
"field": "messages",
"value": {
"contacts": [
{
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
},
"statuses": [
{
"biz_opaque_callback_data": "1e03c4df-e669-4909-948d-db29bcf4211a||||||1",
"conversation": {
"id": "ce881a45011a80d3860aa0a0ee909153",
"origin": {
"type": "service"
}
},
"gs_id": "54749858-4392-4c32-b3f3-93a5d0e92483",
"id": "1e03c4df-e669-4909-948d-db29bcf4211a",
"meta_msg_id": "wamid.HBgMOTE3NTA2MDgwNDgwFQIAERgSODA0MzBDQzMzNEQxRkYyOUI0AA==",
"pricing": {
"billable": false,
"category": "service",
"pricing_model": "PMP",
"type": "free_customer_service"
},
"recipient_id": "<USER_WA_ID>",
"recipient_user_id": "<USER_BSUID>",
"status": "read",
"timestamp": "1791966144"
}
]
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3.2 Call-permission reply (field: messages)
field: messages)When: the user taps Allow or Decline on the request.
Use it to: know whether you may call. With is_permanent: true, permission doesn't need to be asked again.
Field (messages[0]) | Description |
|---|---|
type | interactive |
interactive.type | call_permission_reply |
interactive.call_permission_reply.response | accept or reject |
interactive.call_permission_reply.is_permanent | true means the permission doesn't expire |
interactive.call_permission_reply.response_source | user_action means the user tapped the button |
context.gs_id / context.id / context.meta_msg_id | Link the reply to the request you sent |
{
"entry": [
{
"changes": [
{
"field": "messages",
"value": {
"contacts": [
{
"profile": {
"name": "<USER_NAME>"
},
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messages": [
{
"context": {
"from": "919355040978",
"gs_id": "54749858-4392-4c32-b3f3-93a5d0e92483",
"id": "1e03c4df-e669-4909-948d-db29bcf4211a",
"meta_msg_id": "wamid.HBgMOTE3NTA2MDgwNDgwFQIAERgSODA0MzBDQzMzNEQxRkYyOUI0AA=="
},
"from": "<USER_WA_ID>",
"from_user_id": "<USER_BSUID>",
"id": "wamid.HBgMOTE3NTA2MDgwNDgwFQIAEhgUM0FEODA1MEJCOTc1MUZDODdENzIA",
"interactive": {
"call_permission_reply": {
"is_permanent": true,
"response": "accept",
"response_source": "user_action"
},
"type": "call_permission_reply"
},
"timestamp": "1791966148",
"type": "interactive"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3.3 Call status RINGING
RINGINGWhen: the user's phone starts ringing, about 1 s after /v1/voice returns.
Field (statuses[0]) | Description |
|---|---|
id | Call ID (the same as callId.message from /v1/voice) |
type | call |
status | RINGING |
recipient_id / recipient_user_id | The user's number and BSUID |
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"contacts": [
{
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
},
"statuses": [
{
"id": "wacid.IRggMjgyNjVFQTZENzZDNEI1MjMyQUU3RkFBNkZGOTJFMjkcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"recipient_id": "<USER_WA_ID>",
"recipient_user_id": "<USER_BSUID>",
"status": "RINGING",
"timestamp": "1791966667",
"type": "call"
}
]
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3.4 connect (BIC)
connect (BIC)When: the user answers.
Use it to: take the user's SDP answer and set it as the remote description on your WebRTC or media session, so audio flows.
Field (calls[0]) | Description |
|---|---|
id | The same call ID that /v1/voice returned |
direction | BUSINESS_INITIATED |
from / to / to_user_id | The business number, the user's number and the user's BSUID |
session.sdp_type / session.sdp | The user's SDP answer |
connection.webrtc.sdp | The same answer as a JSON string (Gupshup addition) |
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"connection": {
"webrtc": {
"sdp": "{\"type\":\"answer\",\"sdp\":\"v=0\\r\\no=- 1791966667060 2 IN IP4 127.0.0.1\\r\\ns=-\\r\\nt=0 0\\r\\na=group:BUNDLE 0\\r\\na=msid-semantic: WMS 253a303b-ead8-4279-a66a-92770df99897\\r\\na=ice-lite\\r\\nm=audio 3480 UDP/TLS/RTP/SAVPF 111 126\\r\\nc=IN IP4 57.144.43.49\\r\\na=rtcp:9 IN IP4 0.0.0.0\\r\\na=candidate:2275956755 1 udp 2122260223 57.144.43.49 3480 typ host generation 0 network-cost 50\\r\\na=candidate:2684782176 1 udp 2122262783 2a03:2880:f312:131:face:b00c:0:699c 3480 typ host generation 0 network-cost 50\\r\\na=ice-ufrag:zaTOQdmQQduZeu+t\\r\\na=ice-pwd:liJcPdzP5dzP3tLGcutqqw==\\r\\na=fingerprint:sha-256 48:DC:38:03:9D:BA:E6:7C:0F:BA:92:C2:24:9E:B4:3F:D9:B1:9D:C5:76:FB:3B:16:C1:24:74:69:DD:B3:6E:6D\\r\\na=setup:passive\\r\\na=mid:0\\r\\na=sendrecv\\r\\na=msid:253a303b-ead8-4279-a66a-92770df99897 WhatsAppTrack1\\r\\na=rtcp-mux\\r\\na=rtpmap:111 opus/48000/2\\r\\na=rtcp-fb:111 transport-cc\\r\\na=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1\\r\\na=rtpmap:126 telephone-event/8000\\r\\na=maxptime:20\\r\\na=ptime:20\\r\\na=ssrc:990711625 cname:WhatsAppAudioStream1\\r\\n\"}"
}
},
"direction": "BUSINESS_INITIATED",
"event": "connect",
"from": "919355040978",
"id": "wacid.IRggMjgyNjVFQTZENzZDNEI1MjMyQUU3RkFBNkZGOTJFMjkcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"session": {
"sdp": "v=0\r\no=- 1791966667060 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=msid-semantic: WMS 253a303b-ead8-4279-a66a-92770df99897\r\na=ice-lite\r\nm=audio 3480 UDP/TLS/RTP/SAVPF 111 126\r\nc=IN IP4 57.144.43.49\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=candidate:2275956755 1 udp 2122260223 57.144.43.49 3480 typ host generation 0 network-cost 50\r\na=candidate:2684782176 1 udp 2122262783 2a03:2880:f312:131:face:b00c:0:699c 3480 typ host generation 0 network-cost 50\r\na=ice-ufrag:zaTOQdmQQduZeu+t\r\na=ice-pwd:liJcPdzP5dzP3tLGcutqqw==\r\na=fingerprint:sha-256 48:DC:38:03:9D:BA:E6:7C:0F:BA:92:C2:24:9E:B4:3F:D9:B1:9D:C5:76:FB:3B:16:C1:24:74:69:DD:B3:6E:6D\r\na=setup:passive\r\na=mid:0\r\na=sendrecv\r\na=msid:253a303b-ead8-4279-a66a-92770df99897 WhatsAppTrack1\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1\r\na=rtpmap:126 telephone-event/8000\r\na=maxptime:20\r\na=ptime:20\r\na=ssrc:990711625 cname:WhatsAppAudioStream1\r\n",
"sdp_type": "answer"
},
"timestamp": "1791966667",
"to": "<USER_WA_ID>",
"to_user_id": "<USER_BSUID>"
}
],
"contacts": [
{
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3.5 Call status ACCEPTED
ACCEPTEDWhen: the call is connected, a few seconds after connect. Its timestamp equals the start_time in terminate.
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"contacts": [
{
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
},
"statuses": [
{
"id": "wacid.IRggMjgyNjVFQTZENzZDNEI1MjMyQUU3RkFBNkZGOTJFMjkcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"recipient_id": "<USER_WA_ID>",
"recipient_user_id": "<USER_BSUID>",
"status": "ACCEPTED",
"timestamp": "1791966671",
"type": "call"
}
]
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3.6 terminate (BIC)
terminate (BIC)When: the call ends. In BIC, from is the business and to is the user.
{
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"direction": "BUSINESS_INITIATED",
"duration": 35,
"end_time": "1791966706",
"event": "terminate",
"from": "919355040978",
"id": "wacid.IRggMjgyNjVFQTZENzZDNEI1MjMyQUU3RkFBNkZGOTJFMjkcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"start_time": "1791966671",
"status": "COMPLETED",
"timestamp": "1791966706",
"to": "<USER_WA_ID>",
"to_user_id": "<USER_BSUID>"
}
],
"contacts": [
{
"user_id": "<USER_BSUID>",
"wa_id": "<USER_WA_ID>"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3.7 call_recording_available (BIC)
call_recording_available (BIC){
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"call_recording": {
"audio": {
"id": "1248822537445861",
"mime_type": "audio/ogg; codecs=opus",
"sha256": "5ca2f4a80fd5c215e8c91a371adfdc0d15cfdc41e753b7840d25605b2c7c4393",
"url": "https://<gupshup-media-host>/wa/<APP_ID>/wa/media/1248822537445861?download=false"
},
"type": "audio"
},
"event": "call_recording_available",
"from": "<USER_WA_ID>",
"from_user_id": "<USER_BSUID>",
"id": "wacid.IRggMjgyNjVFQTZENzZDNEI1MjMyQUU3RkFBNkZGOTJFMjkcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"timestamp": "1791966729",
"to": "919355040978"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}3.8 call_transcript_available (BIC)
call_transcript_available (BIC){
"entry": [
{
"changes": [
{
"field": "calls",
"value": {
"calls": [
{
"call_transcript": {
"document": {
"id": "3278052889249622",
"mime_type": "application/json",
"sha256": "db3838f5f008e2557ed29be4276e3181ec9a828b779c49542c1d9b9e4e140b37",
"url": "https://<gupshup-media-host>/wa/<APP_ID>/wa/media/3278052889249622?download=false"
}
},
"event": "call_transcript_available",
"from": "<USER_WA_ID>",
"from_user_id": "<USER_BSUID>",
"id": "wacid.IRggMjgyNjVFQTZENzZDNEI1MjMyQUU3RkFBNkZGOTJFMjkcGAw5MTkzNTUwNDA5NzgVAgAVIAA=",
"timestamp": "1791966749",
"to": "919355040978"
}
],
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "919355040978",
"phone_number_id": "269033402967482"
}
}
}
],
"id": "293928007134319"
}
],
"gs_app_id": "<APP_ID>",
"object": "whatsapp_business_account"
}4. Recording and transcript fields (UIC and BIC)
They arrive only if recording / transcription were ENABLED in the accept (UIC) or connect (BIC) request, and the call was connected past the consent announcement. Both come 20–60 s after terminate, in either order, with the call's id.
In these two events, from is the user and to the business for both UIC and BIC. In a BIC terminate they're the other way round. They carry no direction.
Field (calls[0]) | Description |
|---|---|
event | call_recording_available or call_transcript_available. Meta's docs say call_transcription_available; the platform sends call_transcript_available |
call_recording.type | audio |
call_recording.audio / call_transcript.document | The media object |
.id | Media ID. Download with GET /partner/app/{appId}/media/{id} (app token) |
.url | Gupshup file-manager URL (not Meta's lookaside.fbsbx.com). Downloads without auth. Kept 7 days |
.sha256 | Hex SHA-256 of the file. Compare after downloading |
.mime_type | audio/ogg; codecs=opus (stereo, 48 kHz) or application/json |
Known issue : every transcript tested so far downloads empty: the URL returns 204 and the PP media API returns 200 with 0 bytes. Recordings download correctly.
6. Quick reference
| Event | field | Where | UIC | BIC | Key data |
|---|---|---|---|---|---|
| Permission request statuses | messages | statuses[] | — | ✅ | status: enqueued / sent / delivered / read |
call_permission_reply | messages | messages[].interactive | — | ✅ | response, is_permanent |
RINGING | calls | statuses[] (type: call) | — | ✅ | call ID |
connect | calls | calls[] | ✅ offer | ✅ answer | session.sdp, direction |
ACCEPTED | calls | statuses[] (type: call) | — | ✅ | call ID |
terminate | calls | calls[] | ✅ | ✅ | status, duration (missing if never answered) |
call_recording_available | calls | calls[] | ✅ | ✅ | audio.id, url, sha256 |
call_transcript_available | calls | calls[] | ✅ | ✅ | document.id, url, sha256 |
Updated about 3 hours ago
