Skip to main content
Meta can record and transcribe WhatsApp calls on request. Kapso saves the metadata from Meta’s completion events and fetches the audio or transcript from Meta when you ask for it. Kapso does not turn capture on for you, keep its own copy, or run extra speech-to-text. Complete Calling setup and get a normal call working first.
Kapso’s recording and transcript support is rolling out. If a call detail response has no artifacts field, it isn’t available for your project yet.

Turn on capture for a call

Recording and transcription are separate, per-call opt-ins. Add either object, or both, to the request that starts the call:
  • Inbound: the accept request. Do not add them to pre_accept.
  • Outbound: the connect request, next to the usual to/recipient and SDP offer.
Send it to the same POST https://api.kapso.ai/meta/whatsapp/{version}/{phone_number_id}/calls endpoint you already use. Kapso passes both objects to Meta unchanged. Before capture starts, Meta plays an announcement to both participants, for example: “El audio de esta llamada se grabará con el siguiente propósito: control de calidad.” Either participant can hang up instead. With both objects enabled, Meta plays one combined announcement and uses the recording object’s purpose and announcement_language.
  • Recording alone gives you audio and no transcript. Transcription alone gives you a transcript and no audio.
  • announcement_language only controls the announcement. Meta detects the spoken language for the transcript; an unsupported spoken language can produce an empty transcript.
  • Meta’s prerequisites still apply: Calling enabled on the number and your app subscribed to the calls webhook field. Meta currently documents a known issue where a caller changing networks can cut a recording or transcript short.
Keep your normal call flow: start the agent after accept succeeds or, for outbound calls, after ACCEPTED and media are ready. The announcement plays at the start of the call; plan your greeting around it.

Completion events

After the call ends and Meta finishes processing, Meta sends one event per enabled feature on the calls field. Kapso forwards them through your signed kind: "meta" webhook like any other Calling event.
These events arrive after terminate, can share a delivery with other events, and can carry only a business-scoped user ID instead of a phone number. In your receiver:
  • Verify the raw-body signature and iterate over every entry, change, and call, as for other Calling events.
  • Route them as metadata, not as call lifecycle. A completion event must not start a media session, restart an agent, or reopen a finished call.
  • Accept them even after you have cleaned up the call’s session.
You don’t need to download from the webhook url. It expires after five minutes and needs Meta credentials. Use Kapso’s endpoints below instead. Logs → Meta Logs shows the completion webhooks, including media IDs and checksums. It does not show the audio or the transcript text.

In the dashboard

Open WhatsApp → More → Calls and click a call. The Call Details panel shows:
  • Recording: click Load recording to play it in the browser, or Download recording.
  • Transcript: readable text with speaker labels and timestamps, plus Download transcript (JSON).
Each available artifact shows its estimated expiry. “No recording received” or “No transcript received” means Kapso hasn’t received a completion event for that call; it does not mean capture was off or still processing. Use Refresh to check again. These sections only cover Meta’s native recordings and transcripts. Recordings from your own voice runtime don’t appear here.

Fetch through the API

Use your project API key on the developer API host:
{id} is Kapso’s call UUID, not Meta’s wacid... call ID. Look up the UUID from the Meta call ID with List calls:
Use data[0].id. An empty data array means Kapso has no saved call with that ID for this number. The call list does not include artifacts. The TypeScript SDK has no artifact helper. Use fetch:

Call detail

data.artifacts has a recording and a transcription entry:
Meta keeps recordings and transcripts for seven days. Kapso estimates expires_at from the earlier of the event timestamp and the first time Kapso received it, plus seven days. Repeated events don’t extend it. Meta can remove the media earlier. fetch_path is relative to https://app.kapso.ai. Each fetch asks Meta for a fresh media URL with the number’s credentials, so don’t store or reuse webhook URLs.

Recording

Returns the whole audio file with Meta’s MIME type, up to 32 MiB. Without download=true it is served inline. Range requests are not supported; load the file once and seek locally.

Transcript

Without download=true, you get a readable preview:
  • duration, start, and end are seconds. Channel 0 is your business and 1 is the customer; speaker is Meta’s label.
  • Optional segment fields are omitted when Meta doesn’t send them. language and duration are null when missing.
  • The preview returns up to 500 segments and 100,000 characters, without word-level detail. truncated: true means it was shortened.
  • state: "empty" means Meta returned a valid, empty transcript. Kapso does not retranscribe.
  • Render text as plain text.
?download=true returns Meta’s original transcript JSON, including metadata and word-level detail, up to 2 MiB.

Errors

A call outside your project returns 404 with {"error": "Call not found"}. A missing or invalid API key returns 401 with {"error": "Invalid or missing API key"}. Artifact responses are Cache-Control: private, no-store.

Keep a copy

Kapso does not archive recordings or transcripts. To keep them past Meta’s retention, download them while they are available and store them yourself. If your voice runtime records or transcribes calls itself, for example with Pipecat’s audio buffer or ElevenLabs Agents’ post-call data, that runs separately from Meta’s native capture. Those files stay with your runtime and don’t appear in Kapso’s call details.

Pricing

Meta currently doesn’t charge for native recording or transcription, on top of normal call rates. Meta plans separate pricing for both; it hasn’t published rates or a date. See Calling pricing.