Skip to content

Calling

The Calling API enables real-time voice call functionality over WebRTC, IVR (Interactive Voice Response) setup, call transfers between teams and agents, and call history logs.


IVR flows represent the multi-level audio response menus configured for your WhatsApp accounts.

Retrieve all IVR flows for your organization.

Terminal window
GET /api/ivr-flows
ParameterTypeRequiredDescription
pageintegerNoPage number (default: 1)
limitintegerNoItems per page (default: 50)
accountstringNoFilter by WhatsApp account name
{
"status": "success",
"data": {
"ivr_flows": [
{
"id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e1c0",
"organization_id": "893c5d88-b4b6-4b2a-bf3b-9a8bb698a3e7",
"whatsapp_account": "Primary Line",
"name": "Main Support Menu",
"description": "Greeting menu with team routing options.",
"is_active": true,
"is_call_start": true,
"is_outgoing_end": false,
"menu": {
"nodes": [
{
"id": "node_1",
"type": "greeting",
"label": "Welcome Greeting",
"config": {
"greeting_text": "Thank you for calling support. Press 1 for Sales, 2 for Technical Support."
}
}
]
},
"welcome_audio_url": "https://example.com/audio/welcome.ogg",
"created_by_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_by_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
],
"total": 1,
"page": 1,
"limit": 50
}
}

Retrieve details for a single IVR flow.

Terminal window
GET /api/ivr-flows/{id}

Create a new IVR menu flow.

Terminal window
POST /api/ivr-flows
FieldTypeRequiredDescription
whatsapp_accountstringYesWhatsApp account name associated with the flow
namestringYesReadable flow name
descriptionstringNoFlow description
is_activebooleanNoEnable/disable the flow (default: true)
is_call_startbooleanNoMark as start flow for incoming calls on this account
is_outgoing_endbooleanNoMark as end flow for outgoing calls
menuobjectNoJSON flow graph configuration
welcome_audio_urlstringNoURL of fallback pre-recorded welcoming audio
{
"whatsapp_account": "Primary Line",
"name": "Main Support Menu",
"description": "Greeting menu with team routing options.",
"is_active": true,
"is_call_start": true,
"is_outgoing_end": false,
"menu": {
"nodes": [
{
"id": "node_1",
"type": "greeting",
"label": "Welcome",
"config": {
"greeting_text": "Welcome to our support line."
}
}
]
}
}

Update an existing IVR flow. Partial updates are supported.

Terminal window
PUT /api/ivr-flows/{id}

Soft-delete an IVR flow.

Terminal window
DELETE /api/ivr-flows/{id}

Upload a pre-recorded audio file to use for IVR menus (transcoded automatically to OGG/Opus format).

Terminal window
POST /api/ivr-flows/audio

Must be sent as multipart/form-data.

ParameterTypeRequiredDescription
filefileYesAudio file (supported types: MP3, OGG, WAV, AAC, M4A, FLAC. Max 5MB)
{
"status": "success",
"data": {
"filename": "f47ac10b-58cc-4372-a567-0e02b2c3d479.ogg",
"mime_type": "audio/mpeg",
"size": 1254320
}
}

Serve IVR audio files from storage.

Terminal window
GET /api/ivr-flows/audio/{filename}

Upload a pre-recorded audio file to use for organization-level hold music or ringback tones. Audio is automatically transcoded to OGG/Opus format.

Terminal window
POST /api/org/audio
ParameterTypeRequiredDescription
typestringYesThe audio destination/type. Must be either hold_music or ringback.

Must be sent as multipart/form-data.

ParameterTypeRequiredDescription
filefileYesAudio file (supported types: MP3, OGG, WAV, AAC, M4A, FLAC. Max 5MB)
{
"status": "success",
"data": {
"filename": "org_893c5d88-b4b6-4b2a-bf3b-9a8bb698a3e7_hold_music.ogg",
"type": "hold_music",
"mime_type": "audio/mpeg",
"size": 1254320
}
}

Tracks all incoming and outgoing calls.

Retrieve call logs for your organization. Agents only see their own call logs unless they have the call_logs:read permission.

Terminal window
GET /api/call-logs
ParameterTypeRequiredDescription
pageintegerNoPage number (default: 1)
limitintegerNoItems per page (default: 50)
statusstringNoFilter by status: ringing, answered, completed, missed, rejected, failed
accountstringNoFilter by WhatsApp account name
contact_idstringNoFilter by contact UUID
directionstringNoFilter by direction: incoming, outgoing
ivr_flow_idstringNoFilter by IVR flow UUID
phonestringNoFilter by caller phone number (partial match)
start_datestringNoStart date filter (YYYY-MM-DD)
end_datestringNoEnd date filter (YYYY-MM-DD)
{
"status": "success",
"data": {
"call_logs": [
{
"id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e1c0",
"organization_id": "893c5d88-b4b6-4b2a-bf3b-9a8bb698a3e7",
"whatsapp_account": "Primary Line",
"contact_id": "6df9892c-7eb1-4d32-9cb7-7f8a7e02e1c0",
"whatsapp_call_id": "meta-call-id-9988",
"caller_phone": "+1234567890",
"direction": "incoming",
"status": "completed",
"duration": 45,
"ivr_flow_id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e1c0",
"agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"started_at": "2024-01-01T10:00:00Z",
"answered_at": "2024-01-01T10:00:05Z",
"ended_at": "2024-01-01T10:00:50Z",
"disconnected_by": "client",
"recording_s3_key": "recordings/2024/01/01/e9b728cd.ogg",
"recording_duration": 45
}
],
"total": 1,
"page": 1,
"limit": 50
}
}

Retrieve details for a single call log, including any agent transfers associated with the call.

Terminal window
GET /api/call-logs/{id}
{
"status": "success",
"data": {
"call_log": {
"id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e1c0",
"whatsapp_account": "Primary Line",
"caller_phone": "+1234567890",
"direction": "incoming",
"status": "completed",
"duration": 45,
"recording_s3_key": "recordings/2024/01/01/e9b728cd.ogg"
},
"transfers": [
{
"id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e2ef",
"status": "completed",
"agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"connected_at": "2024-01-01T10:00:05Z",
"completed_at": "2024-01-01T10:00:50Z",
"hold_duration": 5,
"talk_duration": 40
}
]
}
}

Generate a temporary presigned URL for downloading or playing the call recording from S3 storage.

Terminal window
GET /api/call-logs/{id}/recording
{
"status": "success",
"data": {
"url": "https://cloudwa-recordings.s3.amazonaws.com/recordings/2024/01/01/e9b728cd.ogg?AWSAccessKeyId=...",
"duration": 45
}
}

Place an active call on hold. Plays the configured organizational hold music to the customer.

Terminal window
POST /api/call-logs/{id}/hold
{
"status": "success",
"data": {
"status": "on_hold"
}
}

Resume a call from hold and restore the audio bridge between the agent and customer.

Terminal window
POST /api/call-logs/{id}/resume
{
"status": "success",
"data": {
"status": "connected"
}
}

Manage call transfers from the IVR menu or between active agents and support teams.

Retrieve active and historical call transfers.

Terminal window
GET /api/call-transfers
ParameterTypeRequiredDescription
pageintegerNoPage number (default: 1)
limitintegerNoItems per page (default: 50)
statusstringNoFilter by transfer status: waiting, connected, completed, abandoned, no_answer
{
"status": "success",
"data": {
"call_transfers": [
{
"id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e2ef",
"organization_id": "893c5d88-b4b6-4b2a-bf3b-9a8bb698a3e7",
"call_log_id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e1c0",
"whatsapp_call_id": "meta-call-id-9988",
"caller_phone": "+1234567890",
"contact_id": "6df9892c-7eb1-4d32-9cb7-7f8a7e02e1c0",
"whatsapp_account": "Primary Line",
"status": "waiting",
"team_id": "5fa85f64-5717-4562-b3fc-2c963f66afa6",
"transferred_at": "2024-01-01T10:00:00Z"
}
],
"total": 1,
"page": 1,
"limit": 50
}
}

Retrieve details for a single call transfer by ID.

Terminal window
GET /api/call-transfers/{id}

Accept a pending call transfer. This requires a WebRTC SDP offer exchange to establish a peer-to-peer audio connection with the agent.

Terminal window
POST /api/call-transfers/{id}/connect
FieldTypeRequiredDescription
sdp_offerstringYesThe agent’s WebRTC SDP session offer
{
"sdp_offer": "v=0\r\no=- 8763487 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\n..."
}
{
"status": "success",
"data": {
"sdp_answer": "v=0\r\no=- 8763487 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\n..."
}
}

Disconnect a connected transfer session and hang up the call.

Terminal window
POST /api/call-transfers/{id}/hangup
{
"status": "success",
"data": {
"status": "completed"
}
}

Initiate a manual transfer of an active call to another team or to a specific team member.

Terminal window
POST /api/call-transfers/initiate
FieldTypeRequiredDescription
call_log_idstringYesUUID of the call to transfer
team_idstringYesUUID of the target team
agent_idstringNoUUID of the specific agent (must be a member of the target team)
{
"call_log_id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e1c0",
"team_id": "5fa85f64-5717-4562-b3fc-2c963f66afa6",
"agent_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
{
"status": "success",
"data": {
"status": "transferring"
}
}

Start voice calls directly to WhatsApp contacts.

Start an outgoing WebRTC voice call to a WhatsApp contact.

Terminal window
POST /api/calls/outgoing
FieldTypeRequiredDescription
contact_idstringYesUUID of the contact to call
whatsapp_accountstringYesAccount name to call from
sdp_offerstringYesWebRTC SDP offer from the agent’s browser
{
"contact_id": "6df9892c-7eb1-4d32-9cb7-7f8a7e02e1c0",
"whatsapp_account": "Primary Line",
"sdp_offer": "v=0\r\no=- 8763487 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\n..."
}
{
"status": "success",
"data": {
"call_log_id": "e9b728cd-7eb1-4d32-9cb7-7f8a7e02e1c0",
"sdp_answer": "v=0\r\no=- 8763487 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\n..."
}
}

End an outgoing call.

Terminal window
POST /api/calls/outgoing/{id}/hangup
{
"status": "success",
"data": {
"status": "ok"
}
}

Send a template call permission request message to a WhatsApp contact (required by Meta before starting outgoing calls to contacts).

Terminal window
POST /api/calls/permission-request
FieldTypeRequiredDescription
contact_idstringYesUUID of the contact
whatsapp_accountstringYesAccount name to send the request from
{
"contact_id": "6df9892c-7eb1-4d32-9cb7-7f8a7e02e1c0",
"whatsapp_account": "Primary Line"
}
{
"status": "success",
"data": {
"permission_id": "a9b728cd-7eb1-4d32-9cb7-7f8a7e02e987"
}
}

Check the current call permission status for a contact.

Terminal window
GET /api/calls/permission/{contactId}
ParameterTypeRequiredDescription
whatsapp_accountstringYesWhatsApp account name
{
"status": "success",
"data": {
"status": "accepted"
}
}
  • pending: Request sent, awaiting user response.
  • accepted: User accepted, calling is allowed.
  • declined: User declined, calling is blocked.
  • expired: Request expired.

Retrieve STUN/TURN server configurations configured on the backend for frontend WebRTC connection setup.

Terminal window
GET /api/calls/ice-servers
{
"status": "success",
"data": {
"ice_servers": [
{
"urls": [
"stun:stun.l.google.com:19302"
]
},
{
"urls": [
"turn:turn.example.com:3478"
],
"username": "webrtc-user",
"credential": "secure-turn-password-123"
}
]
}
}