Skip to main content

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 forwards call events and proxies call actions. Your server or voice provider runs the agent and handles audio. An API key and webhook alone do not create a voice agent.
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:
The phone number ID is different from the display phone number, WABA ID, project ID, and Kapso configuration UUID. You can find it in Phone numbers in the dashboard, or list your numbers:
Load these variables with your application’s dotenv support. For a trusted shell-compatible .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

Then read Meta’s settings through the proxy:
Confirm 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 with kind: "meta", rather than a Kapso message-event subscription or project webhook. First check for an existing receiver:
If your application already processes messages from a 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.