Call Recording & Transcription

Record and transcribe WhatsApp Cloud API calls: per-call recording and transcription objects, spoken consent announcements and languages, call_recording_available and call_transcription_available webhooks, transcript JSON format, 7-day retention.

What Recording and Transcription Are

The Calling API can record and transcribe the audio of business-initiated and user-initiated calls made through Cloud API. Both are opt-in per call: you decide when you place or accept each call.

Recording and transcription are independent features. Each has its own request object (recording, transcription) and its own webhook event (call_recording_available, call_transcription_available). Enabling recording does not produce a transcript, and enabling transcription does not produce an audio file. You can enable either, both, or neither.

When a call is opted in, both participants hear a short, legally required announcement before recording or transcription starts. After the call ends you receive a webhook with a media ID for the finished audio file or JSON transcript.

Dualhook Boundary

Dualhook documents call recording and transcription but does not offer them. There is no calling screen in the dashboard, and the Runtime API has no /calls route, so you can't place or accept a call, or attach a recording or transcription object, through Dualhook. Use your own Meta app with access to the number, and download the files with that app's token.

The Calling API, and with it recording and transcription, is not available on Coexistence numbers, which most Dualhook connections are. Voice and video calls on those numbers stay in the WhatsApp Business app.

The call_recording_available and call_transcription_available events arrive on the calls webhook field. Dualhook's Meta app does not subscribe to calls, so it does not ingest, store, or forward these webhooks, and a Dualhook connection does not deliver them, even with Webhook Override active. Subscribe your own Meta app to calls to receive them. Dualhook never holds recordings or transcripts.

Prerequisites

  • Calling API enabled on the business phone number (see Calling Configuration).
  • Your app subscribed to the calls webhook field.
  • For business-initiated calls, an open conversation or a call permission from the WhatsApp user.

Enable on a Business-Initiated Call

Add a recording object, a transcription object, or both to the connect request:

POST /<PHONE_NUMBER_ID>/calls
{
  "messaging_product": "whatsapp",
  "to": "14085551234",
  "recipient": "US.13491208655302741918",
  "action": "connect",
  "session": {
    "sdp_type": "offer",
    "sdp": "<<RFC 8866 SDP>>"
  },
  "recording": {
    "status": "ENABLED",
    "purpose": "quality assurance",
    "announcement_language": "en_US"
  }
}

recipient lets you identify the user by BSUID instead of, or in addition to, the phone number in to.

Enable on a User-Initiated Call

Add the same object to the accept request:

{
  "messaging_product": "whatsapp",
  "call_id": "wacid.ABGGFjFVU2AfAgo6V",
  "action": "accept",
  "session": {
    "sdp_type": "answer",
    "sdp": "<<RFC 8866 SDP>>"
  },
  "transcription": {
    "status": "ENABLED",
    "purpose": "quality assurance",
    "announcement_language": "en_US"
  }
}

To accept a call without recording or transcribing it, omit the object or send it with "status": "DISABLED".

Request Object Reference

recording and transcription take the same fields:

FieldRequiredNotes
statusYesENABLED to opt the call in, DISABLED to opt out explicitly.
purposeWhen status is ENABLEDSpoken to both participants as part of the announcement. Max 250 characters. Write it in the language of announcement_language.
announcement_languageWhen status is ENABLEDLocale code for the spoken announcement, e.g. en_US or es. See Announcement Languages.

Before any audio is recorded or transcribed, the Calling API mixes a spoken announcement into both the business and the user audio streams, built from your purpose and announcement_language:

  • Recording: "The audio of this call will be recorded for the following purpose: <purpose>."
  • Transcription: "The audio of this call will be transcribed for the following purpose: <purpose>."

Recording or transcription starts only after the announcement finishes. A participant who doesn't consent can end the call before or during the announcement. A request with status: ENABLED and no purpose is rejected.

Announcement Languages

These announcement_language values have a localized announcement:

Languageannouncement_languageRecordingTranscription
Englishen (also en_US, en_AU, en_CA, en_GB, en_IN, en_NZ)YesYes
DutchnlYesAccepted, plays the English announcement
FrenchfrYesYes
GermandeYesYes
HindihiYesYes
ItalianitYesYes
KannadaknYesYes
Portuguese (Brazil)ptYesYes
Spanish (Latin America)esYesYes
Spanish (Spain)es_ESYesAccepted, plays the English announcement
TeluguteYesYes
VietnameseviYesYes

announcement_language only sets the announcement. It does not set the transcript language, which Meta detects from the audio (see Transcript Language).

Recording and Transcription on the Same Call

Send both objects to get both an audio recording and a transcript. Participants then hear one combined announcement: "The audio of this call will be recorded and transcribed for the following purpose: <purpose>." It is localized in the same languages as the recording announcement.

When both objects are present, the purpose and announcement_language from recording are used and the values in transcription are ignored. You still receive one webhook per feature.

Recording-Available Webhook

After the call ends and post-processing finishes (typically under a minute), Meta sends call_recording_available on the calls field:

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "<WABA_ID>",
    "changes": [{
      "field": "calls",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": {
          "phone_number_id": "<BUSINESS_PHONE_NUMBER_ID>",
          "display_phone_number": "<BUSINESS_DISPLAY_PHONE_NUMBER>"
        },
        "calls": [{
          "id": "wacid.HBgLMTQxMjYxMzYyNTMVAgASGCBGO...",
          "from": "<USER_PHONE_NUMBER>",
          "from_user_id": "<BSUID>",
          "from_parent_user_id": "<PARENT_BSUID>",
          "timestamp": "1728932177",
          "event": "call_recording_available",
          "call_recording": {
            "type": "audio",
            "audio": {
              "id": "1002764438271669",
              "sha256": "Y9vvGyeo3n76ptkXu3CwDBsnzbRFqpjHskQdMGSVqas=",
              "mime_type": "audio/ogg; codecs=opus",
              "url": "https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=133..."
            }
          }
        }]
      }
    }]
  }]
}
FieldNotes
call_recording.typeAlways audio for now.
audio.idMedia ID. Use the Media API to get a fresh download URL.
audio.sha256Base64 SHA-256 of the file, to verify the download.
audio.mime_typee.g. audio/ogg; codecs=opus.
audio.urlShort-lived download URL (see Download and Retention).

from_user_id and from_parent_user_id identify the user by BSUID. from may be omitted when the user has adopted a username.

Transcription-Available Webhook

call_transcription_available has the same envelope, with a call_transcript object instead of call_recording:

{
  "id": "wacid.HBgLMTQxMjYxMzYyNTMVAgASGCBGO...",
  "from": "<USER_PHONE_NUMBER>",
  "from_user_id": "<BSUID>",
  "from_parent_user_id": "<PARENT_BSUID>",
  "timestamp": "1728932177",
  "event": "call_transcription_available",
  "call_transcript": {
    "document": {
      "id": "1002764438271669",
      "sha256": "Y9vvGyeo3n76ptkXu3CwDBsnzbRFqpjHskQdMGSVqas=",
      "mime_type": "application/json",
      "url": "https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=133..."
    }
  }
}

document.id, sha256, and url work like the recording fields. document.mime_type is always application/json.

Transcript Language

You don't set a transcription language. Meta detects the spoken language from the audio and reports it as an ISO 639 code (e.g. en) in transcript.language, independent of announcement_language.

Supported languages change as Meta's speech models improve. Currently: Afrikaans, Albanian, Arabic, Azerbaijani, Bengali, Bulgarian, Burmese, Cebuano, Chinese, Croatian, Czech, Danish, Dutch, English, Finnish, French, German, Greek, Guarani, Gujarati, Hebrew, Hindi, Hungarian, Indonesian, Italian, Japanese, Javanese, Kannada, Korean, Macedonian, Malay, Malayalam, Marathi, Norwegian, Persian, Polish, Portuguese, Punjabi, Romanian, Russian, Serbian, Sinhala, Slovak, Slovenian, Spanish, Swahili, Swedish, Tagalog (Filipino), Tamil, Telugu, Thai, Turkish, Urdu, and Vietnamese.

For a call in an unsupported language you still get the webhook, but the transcript may be empty.

Transcript Document Format

The downloaded transcript is a JSON document with two top-level objects:

{
  "metadata": {
    "processed_at": "2026-06-18T20:16:47Z",
    "audio": { "duration": 21.76, "sample_rate": 16000, "channels": 2, "audio_format": "stereo" }
  },
  "transcript": {
    "text": "[Business] Hello, how about you? [Customer] Hey, I'm good. How are you?",
    "language": "en",
    "duration": 21.76,
    "confidence": 0.83,
    "segments": [
      {
        "id": 1,
        "speaker": "Business",
        "channel": 0,
        "start": 1.16,
        "end": 2.44,
        "text": "Hello, how about you?",
        "confidence": 0.85,
        "words": [
          { "word": "Hello,", "start": 1.16, "end": 1.64, "confidence": 0.89, "lang": "en" }
        ]
      }
    ]
  }
}
FieldNotes
metadata.processed_atISO 8601 UTC time post-processing finished.
metadata.audioduration (seconds), sample_rate (Hz), channels (2 for a two-party call), audio_format (e.g. stereo).
transcript.textWhole conversation as one string, each segment prefixed with [Business] or [Customer].
transcript.languageDetected language, ISO 639.
transcript.durationTranscribed audio length in seconds.
transcript.confidenceOverall score, 0 to 1.
segments[].speaker / channelBusiness on channel 0, Customer (the WhatsApp user) on channel 1. Attribution holds when people talk over each other.
segments[].start / endSeconds from the start of the call audio.
segments[].words[]word, start, end, confidence, and lang (ISO 639) per word.

Download and Retention

Recordings and transcripts use the same download flow as media messages:

  • The url in the webhook is valid for 5 minutes. Download it with an authenticated GET using your access token.
  • After that, fetch a fresh URL from the Media API with audio.id or document.id.

Files stay available for 7 days after the webhook is delivered. Then the media ID expires and Meta deletes the file. Copy anything you need to keep to your own storage within that window.

Errors

Request errors specific to these features (the same for recording and transcription):

ScenarioCause
Missing purposestatus is ENABLED but purpose is omitted or empty.
Purpose too longpurpose exceeds 250 characters.
Invalid announcement_languageNot a supported locale code.
Invalid statusNot ENABLED or DISABLED.

See Calling Troubleshooting for general calling errors.

Pricing and Known Issues

Recording and transcription are currently free. Meta plans to price each one separately later and says it will publish rates with advance notice first; there is no launch date. See Calling Pricing.

Known issue (as of Meta's Aug 31, 2026 update): when the WhatsApp user changes networks during a call, the recording and transcript can be cut short. Meta is rolling out a fix.

Related

  • Business-Initiated CallsPlace outbound voice calls to WhatsApp users. POST /calls with action: connect, SDP offer/answer flow, call status webhooks (RINGING/ACCEPTED/REJECTED), terminate webhook with duration, biz_opaque_callback_data tracking.
  • User-Initiated CallsReceive inbound voice calls from WhatsApp users. Call Connect webhook with SDP offer, pre-accept for faster setup, accept/reject/terminate actions, DTMF dial pad, companion-device support.
  • Calling API ReferenceConsolidated WhatsApp Calling reference: every endpoint, every webhook, WebRTC and ICE guidelines, DTLS certificate recommendations, SDP requirements, bandwidth budget, IP allowlisting.
  • Calling PricingHow Meta bills WhatsApp Calling: free user-initiated calls, per-pulse business-initiated billing, volume tiers, customer service window interaction, call permission request charges, billing prerequisites.
Browse more docsStart Free Trial