What you need
- A dedicated WhatsApp Cloud API number connected to your Kapso project.
- A Kapso API key from that project and the number’s Meta phone number ID.
- A public HTTPS endpoint for call webhooks.
- A media server that handles WebRTC audio and creates real SDP offers and answers.
Kapso’s messaging sandbox is not a Calling test number. Coexistence numbers continue to use calls in the WhatsApp Business App; calls through Kapso require a dedicated Cloud API number. Meta decides Calling eligibility and country availability. Check Meta’s current prerequisites before choosing a number.
1. Configure your application
Keep these values in your application’s.env, excluded from Git:
.env, run set -a, source .env, then set +a before using the shell examples below. Provider keys for speech recognition, reasoning, or speech synthesis belong on your server too.
2. Enable Calling
calling.status is ENABLED. A Meta eligibility rejection must be resolved before testing an agent; changing the voice model or webhook will not enable an ineligible number.
3. Register a Meta webhook
Calling events retain Meta’s payload structure, scoped to the connected number. Use a phone-number webhook withkind: "meta", rather than a Kapso message-event subscription or project webhook.
First check for an existing receiver:
kind: "kapso" webhook, adding a Meta receiver also exposes Meta messages changes. Choose one path for normal message processing to avoid duplicate replies; keep Calling permission replies on the Meta receiver.
Only one Meta webhook is allowed per number, including inactive ones. If one exists, reuse its receiver or deliberately update it; replacing it changes where other Meta events go too. In the dashboard, check whether a voice agent is already assigned to the number. Choose which component answers its calls before testing; do not let the assigned agent and your receiver both answer.
If there is no Meta webhook, create one. Use jq to safely encode your URL and secret:
secret_key is required and is separate from your Kapso API key. Save the returned webhook ID. Repeat the webhook-list request above and confirm the URL and active: true before calling.
4. Connect audio
HTTPS carries events and SDP. Audio needs its own reachable WebRTC path. For a local test, a public HTTPS tunnel such as Tailscale Funnel can deliver webhooks, but it does not by itself make UDP media reachable. Configure a TURN relay if your server’s network requires one. See receiving calls and connecting a voice agent. ICE selects a network path for the media connection. A STUN server helps discover a reachable address; a TURN server relays audio when a direct connection cannot be established. These are separate from your webhook URL. Once your receiver and agent are running, call the connected number from WhatsApp. You can also send a voice call button that the user taps to call your business.Other Meta Calling capabilities
Meta also documents SIP, voicemail, call recording, transcription, and partner call routing. These require separate configuration and validation; the WebRTC guides here do not establish that those features work in your deployment. Messaging handoff does not transfer a live call.Troubleshooting
Receive calls
Verify events, answer a call, and end the session.
Connect a voice agent
Connect Pipecat, Pipecat Cloud, or ElevenLabs Agents to the Calling API.
Make outbound calls
Check permission, dial, and apply the caller’s SDP answer.
TypeScript SDK
Use the call action, permission, and log helpers.

