API Comparison Table

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Block quote

Ordered list

  1. Item 1
  2. Item 2
  3. Item 3

Unordered list

Text link

Bold text

Emphasis

Superscript

Subscript

Pricing
Get started
Get started

Read more

Speech-To-Text

Add speech-to-text to a Pipecat voice agent

TL;DR: In a natural voice agent conversation, anything over 500ms end-to-end feels stilted. Transcription latency is the first line item in that budget, and it sets the ceiling for everything downstream. This guide walks through wiring Solaria-1 into a Pipecat pipeline, tuning VAD thresholds, and handling failure modes, so the STT layer is a decision you can revisit without a rewrite. Because each component is independently swappable, choosing your STT provider is an architectural constraint you control, not one the framework imposes.

Speech-To-Text

Add speech-to-text to a LiveKit voice agent

TL;DR: Voice agent latency comes from every layer, but the LLM accounts for the largest share of your total budget. Self-hosting open-source STT models burns GPU budget on cold-start delays and accuracy that degrades on accented speech. Integrating our Solaria-1 streaming API with LiveKit gives you partial transcripts in under 103ms and final transcripts at approximately 300ms, with true code-switching across 100+ languages. This guide delivers production-ready Python and Node.js code to connect LiveKit's audio egress to Gladia, configure silence detection, and drive natural turn-taking using live partials.

Speech-To-Text

Add speech-to-text to a Recall.ai meeting bot

TL;DR: Recall.ai handles the platform-level complexity of joining Zoom, Meet, and Teams calls while we handle transcription, diarization, and enrichment. This guide walks through the full integration: spawning a bot, routing recorded audio to our async API, enabling pyannoteAI Precision-2 diarization, and mapping speaker labels to participant names using timestamp overlap. Choose Solaria-3 for post-meeting accuracy on English and European business audio, Solaria-1 for real-time captions or broad language coverage. On Growth and Enterprise plans, your audio is never used to train our models.

Add speech-to-text to a Recall.ai meeting bot

Published on August 14, 2026
by Ani Ghazaryan
Add speech-to-text to a Recall.ai meeting bot

TL;DR: Recall.ai handles the platform-level complexity of joining Zoom, Meet, and Teams calls while we handle transcription, diarization, and enrichment. This guide walks through the full integration: spawning a bot, routing recorded audio to our async API, enabling pyannoteAI Precision-2 diarization, and mapping speaker labels to participant names using timestamp overlap. Choose Solaria-3 for post-meeting accuracy on English and European business audio, Solaria-1 for real-time captions or broad language coverage. On Growth and Enterprise plans, your audio is never used to train our models.

Keeping a custom recording bot running across Zoom, Google Meet, and Teams is an ongoing infrastructure problem. Platform changes, audio encoding differences, and bot admission policies create maintenance work that compounds with every new platform version. Recall.ai CEO Amanda Zhu puts a number on that burden.

'We estimate that it'd take a team of 3-5 engineers to maintain a solution like this in perpetuity.' - Amanda Zhu, Recall.ai CEO

Her full take on what modern meeting capture actually requires is worth reading before you decide to build this layer yourself. Using Recall.ai to handle that layer allows you to focus on the audio pipeline. This guide walks through each stage of that integration: architecture, webhook handling, speaker diarization mapping, language configuration, and failure recovery, with working Node.js code for each step.

Blueprint for the meeting bot integration

This integration is structured as four discrete stages:

  1. Video call platform: Raw audio originates in Zoom, Google Meet, or Microsoft Teams.
  2. Recall.ai bot layer: A cloud bot joins the call, records the audio, and exposes it as a downloadable MP3 or as a 16 kHz WebSocket stream for real-time scenarios.
  3. Gladia transcription layer: The audio URL (async) or live PCM stream (real-time) goes to our API, which returns a structured JSON transcript with word-level timestamps, speaker labels, and optional enrichment via the audio-to-LLM pipeline.
  4. Downstream systems: The structured transcript feeds your LLM for summarization, your CRM for deal hygiene, or your coaching platform for scoring.

Required credentials. Store these in your environment before writing any integration code:

  • Gladia API key for authentication (x-gladia-key header)
  • Recall.ai API key for bot spawning and metadata queries
  • Webhook base URL where we will POST completed transcripts
  • API endpoints for both async and real-time workflows
```bash
# .env
GLADIA_API_KEY=your_gladia_api_key
RECALL_API_KEY=your_recall_api_key
GLADIA_ASYNC_ENDPOINT=https://api.gladia.io/v2/pre-recorded  # docs.gladia.io/api-reference/v2/pre-recorded/init
GLADIA_LIVE_ENDPOINT=https://api.gladia.io/v2/live  # docs.gladia.io/api-reference/v2/live
RECALL_BOT_ENDPOINT=your_recall_bot_endpoint
WEBHOOK_BASE_URL=your_webhook_url
```

Use the x-gladia-key header to authenticate every request to our API. Recall.ai uses Authorization: Token $RECALL_API_KEY on their endpoints.

Getting accurate API context before you build

Before wiring up the SDK, run npx skills add gladiaio/skills to give your AI coding agent (Cursor, Claude Code, and similar tools) accurate context on our API and SDK surface. This eliminates hallucinated parameter names during implementation and is particularly useful when setting up the diarization config and webhook handling for the first time.

Set up Recall.ai to capture meeting audio

Recording bots typically return audio as a base64-encoded, mono-channel 16 kHz S16LE stream. Our async endpoint accepts WAV, MP3, M4A, FLAC, and AAC. Our real-time WebSocket expects PCM at 16 kHz mono, verify your bot's output format matches before skipping a conversion step.

Spawn the bot with recording config

The participant_events flag enables the active-speaker metadata needed later to match our generic speaker labels to participant names.

```javascript
async function spawnRecallBot(meetingUrl) {
  const res = await fetch(`${process.env.RECALL_BOT_ENDPOINT}`, {
    method: 'POST',
    headers: {
      'Authorization': `Token ${process.env.RECALL_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      meeting_url: meetingUrl,
      bot_name: 'Meeting-Intelligence-Bot',
      recording_config: {
        video_mixed_mp4: {},
        participant_events: {}
      }
    })
  });
  const bot = await res.json();
  return bot.id;
}
```

Once the meeting ends, our Recall.ai integration guide fires a webhook to your listener when the recording is ready. The payload contains a media_shortcuts.video_mixed.data.download_url field with the direct audio URL you'll forward to Gladia.

Audio format requirements

We accept WAV, MP3, M4A, FLAC, AAC, and direct URLs for files up to 1,000 MB and 135 minutes via the async transcription endpoint. For real-time streaming, send PCM at 16 kHz mono over WebSocket. The Recall.ai output matches both requirements without conversion.

Configure Gladia to process meeting audio

Select processing mode: async vs. real-time

The right model and mode depend on what you're building, so here are the specific usage recommendations:

  • Async (Solaria-3, recommended for post-meeting analysis): Solaria-3 is our most accurate model for real-world business audio across English, French, German, Spanish, and Italian, ranking #1 on Earnings22 and Switchboard against AssemblyAI, ElevenLabs, Deepgram, Mistral, and Speechmatics. It achieves 6.4% WER on Earnings22 financial calls (the only model under 7%) and 33.9% on Switchboard (the only model under 35%). Full-context processing improves accuracy on overlapping speech and domain-specific terminology. Choose this model for meeting summaries, CRM population, and post-call coaching.
  • Real-time (Solaria-1, required for live captions or agent assist): Solaria-1 covers 100+ supported languages, with true code-switching across all of them. Final transcript latency sits at approximately 300ms, with partials under 103ms.

For most meeting assistants, async is the correct default. Post-meeting summaries and action items are generated after the call ends anyway, and full-context processing runs at approximately 60 seconds per hour of audio on our infrastructure.

Configure per-speaker label assignment

Speaker diarization is powered by pyannoteAI's Precision-2 model and is only available in async workflows. Enable it in your transcription request body. For variable meeting sizes, omit a fixed number_of_speakers value and instead use the min_speakers and max_speakers bounds to guide the model. The speaker diarization documentation covers how these parameters interact as hints rather than hard constraints.

Set locale for meeting bot audio

If your user base primarily speaks English or a known set of European languages, pin the language to reduce model ambiguity and improve accuracy on domain-specific vocabulary. For global or multilingual teams where speakers switch languages mid-call, set language_config: { code_switching: true } and let Solaria-1 handle code-switching automatically. Custom vocabulary configuration is particularly useful for product names, internal abbreviations, or technical jargon that generic training data won't surface reliably.

Forwarding bot audio to Gladia for analysis

Processing batch audio with Gladia

Once Recall.ai fires its recording-ready webhook, extract the download URL and submit it directly to our API.

```javascript
async function submitToGladia(audioUrl, callbackUrl) {
  const response = await fetch(process.env.GLADIA_ASYNC_ENDPOINT, {
    method: 'POST',
    headers: {
      'x-gladia-key': process.env.GLADIA_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      audio_url: audioUrl,
      diarization: true,
      diarization_config: {
        min_speakers: 1,
        max_speakers: 12
      },
      callback: true,
      callback_config: { url: callbackUrl },
      language_config: { languages: ['en'] },
      model: 'solaria-3'
    })
  });

  const job = await response.json();
  return job.id;
}
```

Store the returned job.id in your database alongside the Recall.ai bot ID for later use in speaker-to-participant mapping.

Real-time meeting bot integration

For live caption or agent-assist scenarios, use Solaria-1 over WebSocket. Always start with a POST to /v2/live to create a session, then open exactly one WebSocket connection per session using the returned URL.

```javascript
const WebSocket = require('ws');

async function initLiveSession() {
  const sessionRes = await fetch(process.env.GLADIA_LIVE_ENDPOINT, {
    method: 'POST',
    headers: {
      'x-gladia-key': process.env.GLADIA_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      encoding: 'wav/pcm',
      sample_rate: 16000,
      bit_depth: 16,
      channels: 1,
      language_config: { languages: ['en'] },
    })
  });

  const session = await sessionRes.json();
  const ws = new WebSocket(session.url);

  ws.on('message', (msg) => {
    const data = JSON.parse(msg);
    if (data.type === 'transcript' && data.data.is_final) {
      console.log(`[FINAL] ${data.data.utterance.text}`);
    }
  });

  return { ws, sessionId: session.id };
}
```

When working with WebSocket audio streams, Gladia accepts audio either as raw binary frames or as base64-encoded chunks in JSON. Use binary if your environment supports it to avoid encoding overhead, or base64 if your WebSocket client requires text frames. Use aggressive timeouts and circuit breakers on the audio forwarding path: a cascading delay blocks downstream LLM processing if not isolated. Run transcript handling in a separate async worker to keep the send loop clear.

Receive and process transcripts via webhook

Defining the webhook listener endpoint

We fire a POST request to your callback_url when transcription completes. Set up a minimal Express endpoint to receive it and immediately ACK with a 200 response before doing any downstream processing.

```javascript
const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhook/gladia/complete', async (req, res) => {
  const { id } = req.body;
  res.status(200).json({ received: true });
  await processTranscription(id);
});
```

Transcript output structure

Our JSON output is structured around utterances, each with a speaker label, start/end timestamps in seconds, and a words[] array for word-level granularity.

```json
{
  "result": {
    "transcription": {
      "utterances": [
        {
          "speaker": 0,
          "text": "Let's move the deadline to Friday.",
          "start": 12.3,
          "end": 14.8,
          "words": [
            { "word": "Let's", "start": 12.3, "end": 12.6, "confidence": 0.99 }
          ]
        },
        {
          "speaker": 1,
          "text": "Agreed, I'll update the tracker.",
          "start": 15.1,
          "end": 17.0
        }
      ]
    }
  }
}
```

"speaker": 0, "speaker": 1, and so on are our generic labels from Precision-2. The next section maps them to participant names from Recall.ai.

Manage webhook downtime and failures

Use a message queue with exponential backoff rather than inline retries. BullMQ is a lightweight option for Node.js. Generate an idempotency key per transcription job before submission and store it alongside the gladia_job_id. If your listener restarts and receives a duplicate webhook, the idempotency key prevents double-processing.

Sync transcript speakers with meeting participants

The Retrieve Bot response (GET /bot/{id}/) includes recordings[0].media_shortcuts.participant_events.data.speaker_timeline_download_url, which maps timestamps to participant IDs you resolve against the participant list to get display names.

```javascript
async function getRecallSpeakerTimeline(botId) {
  const botRes = await fetch(
    `your_recall_api_endpoint/bot/${botId}/`,
    { headers: { Authorization: `Token ${process.env.RECALL_API_KEY}` } }
  );
  const bot = await botRes.json();
  const timelineUrl = bot.recordings[0].media_shortcuts.participant_events.data.speaker_timeline_download_url;
  return await (await fetch(timelineUrl)).json();
}
```

With the Recall.ai timeline and our utterances in hand, the mapping algorithm finds the active Recall.ai speaker at the midpoint of each utterance, then records that association the first time it appears for each speaker label.

```javascript
function mapSpeakersToParticipants(utterances, recallTimeline) {
  const mapping = {};

  for (const utterance of utterances) {
    if (mapping[utterance.speaker] !== undefined) continue;
    const midpoint = (utterance.start + utterance.end) / 2;
    const activeEvent = recallTimeline.find(
      ev => ev.start_timestamp.relative <= midpoint && ev.end_timestamp.relative > midpoint
    );
    if (activeEvent) {
      mapping[utterance.speaker] = activeEvent.participant.name;
    }
  }

  return mapping; // { 0: "Alice Johnson", 1: "Bob Smith" }
}

// Enrich transcript with participant names
async function enrichTranscript(gladiaTranscript, botId) {
  const utterances = gladiaTranscript.result.transcription.utterances;
  const recallTimeline = await getRecallSpeakerTimeline(botId);
  const mapping = mapSpeakersToParticipants(utterances, recallTimeline);

  return utterances.map(u => ({
    ...u,
    speaker_name: mapping[u.speaker] || u.speaker
  }));
}
```

Route the enriched transcript to your LLM for summarization, action item extraction, or CRM population via the structured audio-to-LLM pipeline.

Addressing latency and data privacy

Managing inference latency at scale

Our async infrastructure processes approximately 60 seconds per hour of audio, which means your meeting assistant can generate summaries almost immediately after the call ends. Aircall, which processes over 1M calls per week through our API, cut transcription time by 95%, reducing per-call processing from 30 minutes to 1.5 minutes. A fintech customer runs 800 concurrent sessions in production without pre-provisioning or capacity forecasting, and our public status page tracks uptime history.

Forecasting transcription costs

We charge per hour of audio duration, with all features including diarization, translation, named entity recognition (NER), and sentiment analysis bundled at the base rate on Starter and Growth plans. There are no per-feature add-on fees.

Volume (hours/month) Starter ($0.61/hr) Growth (as low as $0.20/hr) Monthly savings
500 $305 $100 $205
5,000 $3,050 $1,000 $2,050
20,000 $12,200 $4,000 $8,200

Growth pricing requires an upfront commitment. The figures above reflect the $0.20/hr floor rate, actual cost depends on your commitment tier. At the floor rate and 5,000 hours per month, it's 67% cheaper than Starter, with customer data never used for model training as the default behavior on that tier.

Handling meeting bot audio capture errors

Three failure modes require explicit handling:

  1. Silent audio segments: Short silent gaps at call start or end can produce empty utterances that break downstream parsing. Filter them before processing.
  2. Packet loss artifacts: If Recall.ai's WebSocket stream drops packets during a meeting, the resulting audio may contain gaps. Submit the final MP3 recording via the async path rather than the live stream to avoid this entirely for post-meeting workflows.
  3. Bot disconnect mid-call: Recall.ai fires its status-change webhook even on early disconnects. Always check recordings[0].media_shortcuts for a valid download URL before submitting to Gladia. If the URL is absent, trigger a re-join or escalate via your alerting system.

Data privacy on Growth and Enterprise plans

Our compliance hub details our SOC 2 Type II, ISO 27001, HIPAA, and GDPR posture. On Growth and Enterprise tiers, audio is never used to retrain our models, with no opt-out action required. This is a contractual default verifiable in our DPA. By default, audio can be processed in our EU or US region depending on your configuration. On the Starter plan, data can be used for training, so teams handling sensitive calls should upgrade before processing enterprise customer audio.

Integration and provider reference

Comparing infrastructure options

Deepgram launched a Voice Agent API that competes directly with meeting assistant builders, and AssemblyAI built LeMUR as an application layer on top of their STT API. We are a pure-play audio infrastructure provider with no application products that compete with your build.

Metric/Feature Gladia (Solaria-1 / Solaria-3) Deepgram (Nova-3) AssemblyAI (Universal-3.5 Pro)
Diarization engine pyannoteAI Precision-2 (async only) Proprietary (async/RT) Proprietary (async/RT)
Pricing model All-inclusive base rate on Starter/Growth Add-on fees for diarization/intelligence Add-on fees for speaker identification and other intelligence features
Data privacy default No training on paid plans, no opt-out required No training by default (opt-in improvement program only) Retraining unless explicitly opted out
Core focus Pure-play audio infrastructure Application-layer competitor (Voice Agent API) Application-layer competitor (LeMUR)

If you'd rather test on your own audio than take any vendor's benchmark at face value, our blind comparison tool removes the brand bias: upload up to 2 minutes of real meeting audio, receive side-by-side transcripts from two providers with names hidden, and pick the more accurate result before the reveal. For a more rigorous evaluation, run your audio against a reproducible benchmark methodology before committing.

Diarization accuracy for overlapped audio

Our diarization engine, powered by pyannoteAI's Precision-2, handles cross-talk and interruptions materially better than its predecessor, improving on speaker confusion, missed detection, and false alarm rates simultaneously. For meetings with frequent interruptions, set max_speakers to a realistic upper bound for your typical call size rather than leaving it unbounded.

Start with €50 in free credits and have your integration in production in less than a day.

FAQs

What is the latency for Gladia's async transcription?

Our async infrastructure processes approximately 60 seconds per hour of audio, so your meeting assistant can generate summaries almost immediately after the call ends. This applies to both short standup recordings and longer multi-hour sessions.

Does Gladia support real-time speaker diarization?

No, speaker diarization powered by pyannoteAI's Precision-2 is available in async workflows only. For real-time streams, speaker attribution should be handled in post-processing to maintain accuracy.

Is customer audio data used to train Gladia's models?

On Growth and Enterprise plans, customer data is never used for model training by default and no opt-out action is required. On the Starter plan, data may be used for training, so teams processing sensitive or enterprise customer audio should move to a paid tier before going to production.

How do I map our speaker labels to Recall.ai participant names?

Fetch Recall.ai's speaker_timeline_download_url from the participant_events endpoint, then use timestamp midpoint alignment to match each speaker number ("speaker": 0, "speaker": 1, and so on) to the active participant at that moment in the call.

Which model should I use for multilingual meeting bots?

Use Solaria-3 for async post-meeting workflows where your users speak English, French, German, Spanish, or Italian, especially in noisy or conversational audio conditions. Use Solaria-1 for real-time streaming, meetings involving languages outside that set, or any scenario where participants switch languages mid-call, as Solaria-1 handles code-switching natively.

What happens if the Recall.ai bot disconnects mid-meeting?

Check recordings[0].media_shortcuts for a valid download URL before submitting to Gladia. If the URL is absent, the recording is incomplete and you should trigger a retry or surface the failure in your alerting pipeline before attempting transcription.

Key terms glossary

Word Error Rate (WER): The standard metric for transcription accuracy, calculated by comparing the API output against a human-verified reference transcript. Lower is better, measured per language and audio condition rather than as a single universal figure.

Diarization Error Rate (DER): The metric used to evaluate speaker attribution accuracy, measuring how often the system assigns the wrong speaker label to a segment. It accounts for missed speakers, false alarms, and speaker confusion as separate error types.

Code-switching: The practice of alternating between two or more languages mid-conversation, which our Solaria-1 model detects automatically across all 100+ supported languages in both real-time and async modes.

pyannoteAI Precision-2: The diarization model powering our speaker attribution pipeline, improving on speaker confusion, missed detection, and false alarm rates compared to its predecessor and the open-source pyannote.audio baseline.

WebRTC: The open browser and application protocol used by Google Meet, Microsoft Teams, and other video platforms for audio capture. Recall.ai abstracts the platform-specific audio layer so you don't have to manage packet routing, NAT traversal, or codec negotiation directly.

Contact us

280
Your request has been registered
A problem occurred while submitting the form.

Read more