Calling
Overview
Section titled “Overview”Whatomate provides WebRTC-based voice calling over WhatsApp. This page documents the HTTP/REST control-plane endpoints: browsing call logs and recordings, managing agent transfers, placing outgoing calls, and requesting call permission.
Permissions used on this page: call_logs:read, call_transfers:read, call_transfers:write, outgoing_calls:read, outgoing_calls:write.
Call Logs
Section titled “Call Logs”List Call Logs
Section titled “List Call Logs”Get call logs for the organization.
GET /api/call-logsQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status (ringing, answered, completed, missed, rejected, failed, transferring, initiating, accepted) |
account | string | Filter by WhatsApp account name |
contact_id | string | Filter by contact UUID |
direction | string | incoming or outgoing |
ivr_flow_id | string | Filter by IVR flow UUID |
phone | string | Partial match on the caller phone number |
start_date | string | Include calls created on or after this date |
end_date | string | Include calls created on or before this date |
page | integer | Page number (default 1) |
limit | integer | Results per page |
Response
Section titled “Response”{ "status": "success", "data": { "call_logs": [ { "id": "uuid", "organization_id": "uuid", "whatsapp_account": "Main", "contact_id": "uuid", "whatsapp_call_id": "wacid.HBg...", "caller_phone": "+15551234567", "direction": "incoming", "status": "completed", "duration": 92, "ivr_flow_id": "uuid", "agent_id": "uuid", "started_at": "2024-01-01T00:00:00Z", "answered_at": "2024-01-01T00:00:05Z", "ended_at": "2024-01-01T00:01:37Z", "disconnected_by": "agent", "recording_duration": 92, "contact": { "id": "uuid", "phone_number": "+15551234567" }, "agent": { "id": "uuid", "full_name": "Jane Agent" } } ], "total": 1, "page": 1, "limit": 20 }}Get Call Log
Section titled “Get Call Log”Get a single call log with its associated transfers.
GET /api/call-logs/{id}Response
Section titled “Response”{ "status": "success", "data": { "call_log": { "id": "uuid", "whatsapp_account": "Main", "caller_phone": "+15551234567", "direction": "incoming", "status": "completed", "duration": 92, "ivr_path": ["1", "3"], "agent_id": "uuid" }, "transfers": [ { "id": "uuid", "status": "completed", "team_id": "uuid", "agent_id": "uuid", "talk_duration": 80 } ] }}Get Call Recording
Section titled “Get Call Recording”Get a short-lived presigned URL for a call's audio recording. Requires S3 storage to be configured and the call to have a recording.
GET /api/call-logs/{id}/recordingResponse
Section titled “Response”{ "status": "success", "data": { "url": "https://s3.example.com/recordings/...?X-Amz-Expires=900", "duration": 92 }}Hold Call
Section titled “Hold Call”Put an active call on hold and play hold music to the caller. The {id} is the call log ID.
POST /api/call-logs/{id}/holdResponse
Section titled “Response”{ "status": "success", "data": { "status": "on_hold" }}Resume Call
Section titled “Resume Call”Take an active call off hold and restore the audio bridge.
POST /api/call-logs/{id}/resumeResponse
Section titled “Response”{ "status": "success", "data": { "status": "connected" }}Call Transfers
Section titled “Call Transfers”Call transfers move a live call from the IVR (or from another agent) to an agent or team. See IVR Flows for how transfers are triggered from a flow.
List Call Transfers
Section titled “List Call Transfers”GET /api/call-transfersQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status (waiting, connected, completed, abandoned, no_answer) |
page | integer | Page number (default 1) |
limit | integer | Results per page |
Response
Section titled “Response”{ "status": "success", "data": { "call_transfers": [ { "id": "uuid", "organization_id": "uuid", "call_log_id": "uuid", "whatsapp_call_id": "wacid.HBg...", "caller_phone": "+15551234567", "contact_id": "uuid", "whatsapp_account": "Main", "status": "waiting", "team_id": "uuid", "agent_id": null, "initiating_agent_id": null, "transferred_at": "2024-01-01T00:00:00Z", "hold_duration": 0, "talk_duration": 0 } ], "total": 1, "page": 1, "limit": 20 }}Get Call Transfer
Section titled “Get Call Transfer”GET /api/call-transfers/{id}Response
Section titled “Response”{ "status": "success", "data": { "id": "uuid", "call_log_id": "uuid", "caller_phone": "+15551234567", "status": "connected", "team_id": "uuid", "agent_id": "uuid", "connected_at": "2024-01-01T00:00:10Z", "talk_duration": 0 }}Connect Call Transfer
Section titled “Connect Call Transfer”An agent accepts a waiting transfer and completes the WebRTC handshake. The agent sends an SDP offer and receives the SDP answer. Concurrent accepts are rejected atomically.
POST /api/call-transfers/{id}/connectRequest Body
Section titled “Request Body”{ "sdp_offer": "v=0\r\no=- ... (WebRTC SDP offer)"}| Field | Type | Required | Description |
|---|---|---|---|
sdp_offer | string | Yes | The agent's WebRTC SDP offer |
Response
Section titled “Response”{ "status": "success", "data": { "sdp_answer": "v=0\r\no=- ... (WebRTC SDP answer)" }}Hangup Call Transfer
Section titled “Hangup Call Transfer”End a connected transfer.
POST /api/call-transfers/{id}/hangupResponse
Section titled “Response”{ "status": "success", "data": { "status": "completed" }}Initiate Agent Transfer
Section titled “Initiate Agent Transfer”A connected agent transfers their active call to another team (optionally targeting a specific agent within that team).
POST /api/call-transfers/initiateRequest Body
Section titled “Request Body”{ "call_log_id": "uuid", "team_id": "uuid", "agent_id": "uuid"}| Field | Type | Required | Description |
|---|---|---|---|
call_log_id | string | Yes | The active call's log UUID |
team_id | string | Yes | Target team UUID |
agent_id | string | No | Target a specific agent (must be a member of team_id) |
Response
Section titled “Response”{ "status": "success", "data": { "status": "transferring" }}Outgoing Calls & Permissions
Section titled “Outgoing Calls & Permissions”Initiate Outgoing Call
Section titled “Initiate Outgoing Call”Start a voice call from an agent to a WhatsApp contact. The agent provides an SDP offer and receives the SDP answer plus the new call log ID.
POST /api/calls/outgoingRequest Body
Section titled “Request Body”{ "contact_id": "uuid", "whatsapp_account": "Main", "sdp_offer": "v=0\r\no=- ... (WebRTC SDP offer)"}| Field | Type | Required | Description |
|---|---|---|---|
contact_id | string | Yes | Contact UUID to call |
whatsapp_account | string | Yes | WhatsApp account name to place the call from |
sdp_offer | string | Yes | The agent's WebRTC SDP offer |
Response
Section titled “Response”{ "status": "success", "data": { "call_log_id": "uuid", "sdp_answer": "v=0\r\no=- ... (WebRTC SDP answer)" }}Hangup Outgoing Call
Section titled “Hangup Outgoing Call”End an outgoing call. The {id} is the call log ID returned by the initiate call.
POST /api/calls/outgoing/{id}/hangupResponse
Section titled “Response”{ "status": "success", "data": { "status": "ok" }}Send Call Permission Request
Section titled “Send Call Permission Request”WhatsApp requires the consumer to grant call permission before a business can call them. This sends the permission-request message and records it.
POST /api/calls/permission-requestRequest Body
Section titled “Request Body”{ "contact_id": "uuid", "whatsapp_account": "Main"}| Field | Type | Required | Description |
|---|---|---|---|
contact_id | string | Yes | Contact UUID to request permission from |
whatsapp_account | string | Yes | WhatsApp account name |
Response
Section titled “Response”{ "status": "success", "data": { "permission_id": "uuid" }}Get Call Permission
Section titled “Get Call Permission”Check the live call-permission state for a contact directly via the WhatsApp API. The path parameter is the contact UUID.
GET /api/calls/permission/{contactId}?whatsapp_account=MainQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
whatsapp_account | string | Yes | WhatsApp account name |
Response
Section titled “Response”{ "status": "success", "data": { "status": "approved" }}Get ICE Servers
Section titled “Get ICE Servers”Return the configured ICE (STUN/TURN) servers the frontend should use when building WebRTC peer connections. TURN entries may carry short-lived, HMAC-derived credentials that are generated per request.
GET /api/calls/ice-serversResponse
Section titled “Response”{ "status": "success", "data": { "ice_servers": [ { "urls": ["stun:stun.example.com:3478"] }, { "urls": ["turn:turn.example.com:3478?transport=udp"], "username": "1735689600", "credential": "hmac-derived-credential" } ] }}