Asynchronous Transcription

Create transcripts after a meeting ends so your app knows when to start transcription, handle completion or failure, and fetch the final result.

Overview

Async transcription is used to generate a transcript for a completed recording, after a meeting concludes. You should use async transcription when:

  • You don't require transcripts in real-time
  • You require certain features that real-time transcription can't provide (transcription provider dependant)

Once you get transcript, typical use cases include:

  • Summarizing the context of the transcript
  • Extract information to pre-fill forms
  • Extracting action items
📘

You can refer to this sample app creating and retrieving the transcript after a meeting has concluded via meeting bot.

Supported Async Transcription Providers

Transcription ProviderAsync Transcription (Bots + DSDK)Provider Field Name in Create Async Transcript
Recall.ai✅ Yesrecallai_async
Eleven Labs✅ Yeselevenlabs_async
Assembly AI✅ Yesassembly_ai_async
Deepgram✅ Yesdeepgram_async
AWS Transcribe✅ Yesaws_transcribe_async
Rev✅ Yesrev_async
Speechmatics✅ Yesspeechmatics_async
Gladia✅ Yesgladia_v2_async
Google Cloud STT✅ Yesgoogle_speech_v2_async

You can view the full list of supported fields for each of the providers in the Create Async Transcript endpoint under the provider body params.


Prerequisites

Before implementing async transcription, first ensure the required pre-requisite setup is complete. You should have:

  • A stable public URL for your application. In development, this is usually a static ngrok URL or something similar.
  • Your Recall API key and workspace verification secret.
  • A webhook endpoint configured in the Recall dashboard and subscribed to the following events: recording.done, transcript.done, transcript.failed

A human must complete quick one-time setup tasks in the Recall dashboard. If an agent is guiding setup, it should treat this section as human-owned setup and confirm with the human that each item is complete before continuing.

Ensure the backend has a stable public URL

Ensure the application has a stable public URL that Recall can reach for webhooks, callbacks, websockets, and other real-time endpoints.

For local development, this should be a static ngrok URL rather than a temporary URL that changes between sessions. See the Local Webhook Development Guide for how to set this up.

Create the Recall API key and workspace verification secrets

Ensure the required Recall API credentials and verification secrets have been created in the Recall dashboard for the selected region

The Recall API key and workspace verification secrets are required to interact and to secure your application.

Configure a webhook endpoint to receive artifact status change events

Ensure that you have configured a Recall webhook endpoint in the webhooks dashboard that points to either:

  • a static ngrok URL for local development, or
  • a public server that is ready to receive and process webhook events

Also ensure that this endpoint is subscribed to the required webhook events for this feature.


Implementation Guide

To implement post-meeting transcription correctly, first create a recording artifact using the Meeting Bots API or the Desktop Recording SDK. After that point, you can create a transcript for the recording by:

  1. Wait for the recording.done webhook event, which is triggered after the meeting has ended and the recording is available.
  2. Call the Create Async Transcript endpoint for that recording, configuring a transcription provider.
  3. Wait for the transcript.done or transcript.failed webhook event to know when the transcript job has completed and then query the result, found on the transcript artifact.
❗️

Important: Requirements for a reliable integration

To integrate with Recall reliably, your application must:

  • Secure your Recall endpoints - Do not trust incoming Recall.ai requests by default. Your application must verify every webhook, websocket, and callback request before accepting or processing it. See How to verify webhooks, websockets and callback requests from Recall.ai.

  • Schedule bots in advance whenever possible - Creating bots at the last minute increases the chance of 507 errors. See the Creating and scheduling bots guide for more details.

  • Retry Create Bot requests that return 507 status codes - Retry any 507 responses returned by the Create Bot request every 30 seconds, for up to 10 attempts. Otherwise, a bot will not be created.

  • Process webhook work asynchronously - Acknowledge Recall webhook requests quickly, then handle downstream work asynchronously. Otherwise, the request may time out and Recall may retry it.

Step 1: Wait for Recall to notify your webhook that recording is complete

Recall will notify your application when a recording is ready for transcription by sending your app a recording.done recording artifact status change webhook event to the webhook endpoint you configured in your Recall dashboard.

🚧

You will only receive the webhook event if the webhook endpoint has subscribed to the recording.done event in the dashboard. See Async Transcription for details on how to subscribe to this event.

When your application receives the recording.done webhook event, it can start an async transcript job for that recording, as seen in the next step.

Recording artifact status change webhook

You can receive a webhook notifying you when the recording artifact status changes (e.g., from processing to done).

{
  "event": string,
  "data": {
    "data": {
      "code": string,
      "sub_code": string | null,
      "updated_at": string // ISO86001
    },
    "recording": {
      "id": string,
      "metadata": object
    },
    "bot": {
      "id": string,
      "metadata": object
    }
  }
}

You must explicitly subscribe to each event you want to receive from the dashboard, as defined in the table below.

Recording artifact webhook events and codes

EventCodeDescription
recording.processingprocessingThe recording has started
recording.donedoneThe recording has successfully completed. All data for media objects on the recording is now available
recording.failedfailedThe recording failed to be captured. The data.data.sub_code will contain machine readable code for the failure
recording.deleteddeletedThe recording has been deleted from Recall systems.

Step 2: Start a transcription job

After your application receives a recording.done event for a recording, call the Create Async Transcript endpoint for that recording.

For example, the following request will create a transcript using the Recall.ai async transcription provider.

curl --request POST \
     --url https://RECALL_REGION.recall.ai/api/v1/recording/{RECORDING_ID}/create_transcript/ \
     --header "Authorization: RECALLAI_API_KEY" \
     --header "accept: application/json" \
     --header "content-type: application/json" \
     --data '
{
  "provider": {
    "recallai_async": {
      "language_code": "auto"
    }
  },
  "diarization": {
    "use_separate_streams_when_available": true,
  }
}
'

For the full list of provider-specific options, see the Create Async Transcript API reference.

📘

Only 10 Successful Transcripts Allowed Per Recording

To prevent accidental loops from creating excessive transcripts for the same recording (which could incurs usage costs with the transcription provider), Recall limits each recording to 10 successful transcripts.

If you reach this limit, delete an existing transcript for that recording before retrying by calling the Delete Transcript API endpoint.

Step 3: Query the result of the transcription job

Upon completing the transcription job, Recall will send your webhook endpoint one of the following events depending on the outcome of the transcription job:

  • transcript.done - the transcript was created successfully and is now available to query. The results is available in the transcript artifact's download url.
  • transcript.failed - the transcription provider failed to generate a transcript for the recording. More details available in the transcript artifact's status.

Transcript artifact status change webhook

You can receive a webhook notifying you when the transcript artifact status changes (e.g., from processing to done))

{
  "event": string,
  "data": {
    "data": {
      "code": string,
      "sub_code": string | null,
      "updated_at": string // ISO86001
    },
    "transcript": {
      "id": string,
      "metadata": object,
    },
    "recording": {
      "id": string,
      "metadata": object
    },
    "bot": {
      "id": string,
      "metadata": object
    }
  }
}

You must explicitly subscribe to each event you want to receive from the webhooks dashboard, as defined in the table below.

Transcript artifact webhook events and codes

EventCodeDescription
transcript.processingprocessingThe media object has started capturing
transcript.donedoneThe media object has successfully completed. All data for media objects on the recording is now available
transcript.failedfailedThe media object failed to be captured. The data.sub_code will contain machine readable code for the failure. See below for list of sub codes
transcript.deleteddeletedThe media object has been deleted from Recall systems.

Transcript artifact webhook sub codes

Below are a list of sub_code that can be found on a transcript.failed webhook event.

Sub CodeReason
provider_connection_failedRecall is not able to connect to the 3rd party transcription provider. Common reasons for these include: * Insufficient funds in the transcription provider account for which the API key is provided * Using paid features on a free account * Temporary service unavailability from the transcription provider
zoom_global_captions_disabledMeeting captions are disabled by the Zoom account
zoom_host_disabled_meeting_captionsThe host of Zoom meeting has disabled meeting captions
zoom_captions_failureThere was an error in enabling meeting captions for the Zoom call

Case 1: The transcript was created successfully

In this case, the transcript was successfully created and is available for you to query so Recall sent you a transcript.done transcript artifact status change webhook event. You can get the transcript ID from the webhook event at data.transcript.id and call the Retrieve Transcript endpoint like so:

curl --request GET \
     --url https://RECALL_REGION.recall.ai/api/v1/transcript/{TRANSCRIPT_ID}/ \
     --header "Authorization: RECALLAI_API_KEY" \
     --header "accept: application/json"

The response schema can be found in the Retrieve Transcript API reference. The response payload will contain the data.download_url field which you can use to query the transcript that was created for this recording.

Transcript download url data schema

The resulting data from querying the data.download_url will be returned as follows:

[
  {
    "participant": {
      "id": number, // Id of the participant in the meeting. This id is not unique across meetings.
      "name": string | null, // Display name of the participant.
      "is_host": boolean | null, // Whether the participant is the host of the meeting.
      "platform": string | null, // Meeting platform constant
      "extra_data": json | null, // Extra data about the participant from the meeting platform.
      "email": string | null, // Email, if participant identification is turned on
    },
    "language_code": str, // The language code from the transcription provider, normalized to BCP-47.
                          // The simple code is .split('-')[0], and beware that some languages require
                          // 3-character codes (e.g. yue and haw)
    "words": [
      {
        "text": string, // The text of the word.
        "start_timestamp": {
          "absolute": string, // ISO 8601, will return null for async transcription
          "relative": number // seconds
        },
        "end_timestamp": {
          "absolute": string, // ISO 8601, will return null for async transcription
          "relative": number // seconds
        }
      }
    ]
  }
]

Case 2: The transcript failed to generate

In this case, the transcription provider failed to generate a transcript so Recall sent you a transcript.failed event. You can get the machine-readable code from the data.status.sub_code field of the transcript.failed webhook event.

❗️

If the transcription job fails, you can retry the transcription with a backup transcription provider.

You can also check the bot logs in the dashboard to see why it failed.

If async transcription fails, you can retry the transcription with a backup transcription provider


Additional transcription configurations

Improving diarization and speaker attribution to transcript utterances

For the best diarization with speaker names, you should use Perfect Diarization by setting diarization.use_separate_streams_when_available: true in the Create Async Transcript request.

For the best diarization when multiple participants are speaking from the same device, you can also use Hybrid Diarization which is a combination of Perfect Diarization and Machine Diarization.

To see all diarization configurations, see the diarization guide.

📘

Perfect diarization transcription cost

Using diarization.use_separate_streams_when_available: true can increase transcription cost when participants speak concurrently or when background conversation is present, although this usually affects only a small portion of the total recording.

Language detection for async transcription

If you don’t know ahead of time which language the conversation will be in, you can set up automatic language detection. Automatically detecting languages is broken up into two types:

  • Language Detection - Detecting the primary spoken language within a recording, without needing to explicitly set it
  • Code switching - Alternating between two or more languages or language varieties within a single conversation or speech

Most of the third-party transcription providers that we integrate with support language detection.

The table below covers each of these, and their corresponding parameters in the Create Async Transcript provider configuration.

ProviderSupported LanguagesLanguage DetectionCode Switching
recallai_asyncDocslanguage_code: "auto"Not Supported
assembly_ai_asyncDocslanguage_detection: true (docs)language_detection_options.code_switching: true (docs)
deepgram_asyncDocsmodel: "nova-2" | "nova-3" and language: "multi" (docs)Same as language detection (docs )

Accessing raw data from the transcription provider

❗️

Raw transcription provider data is not exposed for Recall.ai transcription or when diarization.use_separate_streams_when_available: true

If you want to extract a specific field from your transcription provider that is not exposed through the transcript generated by Recall then you can fetch the raw provider transcription response by:

  • Fetching the transcript artifact via the Retrieve Transcript endpoint to get the transcript artifact
  • The response payload will contain the data.provider_data_download_url field which you can use to query the transcript that was created for this recording.

The response of the provider_data_download_url varies by provider.

Convert the transcript to a sentence-by-sentence transcript

You can convert the transcript JSON to a more human-readable transcript with the following function.


FAQs

How long does it take to transcribe a recording using async transcription?

The time to generate a transcript varies on recording length and the transcription provider chosen. You will need to refer to their docs for info on this.

As a benchmark - a 1 hour recording takes about 1 minute to transcribe when using Recall.ai Transcription(mixed audio regardless of language specified).

How to get the transcript summary?

To get the transcript summary, you will need to pass the transcript to a third-party LLM to analyze. Recall doesn't support transcription summaries out of the box.