messaging.voip. To speak and
listen on a call from server code, use CallsClient from @polymorfa/sdk/calls.
For browser calling, see the Calls guide.
Place a call
session is the Number that places the call. participant names who acts on
the call for your server, as server:agent-7. It defaults to default. Set
video: true for a video call.
Pass an idempotency key so the SDK can retry the request without placing a
second call.
Check before you call
check runs the same checks as place without placing a call. refusal is
calls_disabled, call_recipient_opted_out, call_destination_blocked,
call_permission_required, or call_limit_reached. place runs the checks
again, so a call can still fail if something changed in between.
Answer, decline, and end calls
Incoming calls arrive ascall.received webhooks. A call rings until someone
answers or declines it. Nothing answers automatically.
acceptanswers a ringing call. Later accepts by other participants join it, unless the first participant setexclusive: true. Then they fail with409 call_claimed.rejectdeclines a ringing call. It fails with409 call_not_ringingotherwise.endends the call for everyone.leave(callId, { connectionId })closes one of your connections and leaves the call running.addParticipant(callId, { to })invites another WhatsApp user.
Ask for call permission
WhatsApp requires a person’s permission before an Official API Number calls them. Read the current state, then ask with a message:call_permission_request_limited. Changes
arrive as call.permission_changed webhooks. Linked-device Numbers do not use
call permission.
Change call settings for a Number
callsEnabled: falseturns calling off for the Number. New calls fail withcalls_disabledand incoming calls are declined. Calls in progress continue.conferenceMode(defaulttrue) lets every participant you connect hear each other. Withfalse, each hears only the WhatsApp caller.inboundRoute: "sip_trunk"withsipTrunkIdsends incoming calls to a SIP trunk.clients(the default) rings your apps and browsers.
expectedRevision fails with 409 state_conflict.
Speak on a call from server code
CallsClient follows one Number’s calls and gives you each call’s audio, for
example to run a voice agent:
call.audio carries signed 16-bit mono PCM at call.audio.sampleRate. Write
your own audio with call.audio.write(). The client reconnects after a dropped
connection. Call disconnect() to stop following the Number.
Connect a SIP trunk
A SIP trunk connects your PBX to a project’s calls. Read the address to configure in your PBX:update(trunkId, { enabled: false, expectedRevision }).
rotateCredentials(trunkId) issues a new inbound password. A team client passes
the project ID as the first argument to list and create. See
SIP trunks.
Block countries and keep a do-not-call list
The team’s call policy blocks calls to country calling codes. It needs a team key:update replaces the whole list. Codes are 1 to 4 digits without +; 1876
blocks Jamaica without blocking the rest of +1. While any code is blocked,
calls to people whose phone number is unknown are refused too.
The do-not-call list blocks calls to specific people:
call_recipient_opted_out. Matching uses
the identifier you stored: a phone number entry does not block a call addressed
by user ID. import({ entries }) adds up to 5,000 entries at once.
For call history and statistics, see Call records.