# Speech to Text (`lergassy/speech-to-text`) Actor

Transcribe audio and video files to text with timecodes, in 90+ languages. Whisper large v3 with nothing to set up, optional translation to English, SRT and WebVTT subtitles, and chunks for RAG. Export data, run via API, schedule runs, or integrate with AI workflows.

- **URL**: https://apify.com/lergassy/speech-to-text.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Videos, AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $21.00 / 1,000 minute transcribeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Turn **audio and video into text** with timecodes, in 90+ languages. Feed it MP3, M4A, WAV, FLAC, OGG, MP4, MOV or WEBM — anything with sound — and get back a clean transcript, timed passages, ready-made SRT or WebVTT subtitles, and retrieval chunks that keep the moment each passage was spoken. No API key to set up, no model to choose, no file preparation on your side.

### What is Speech to Text?

Speech to Text is a **transcription API** built on Whisper large v3. It downloads your media, strips the audio out of video, prepares it for recognition, splits files of any length into parts, transcribes them and stitches the timings back together — so a three-hour recording is one input and one row of output.

The recognition key is built in. There is nothing to sign up for, and nothing to paste. If you already pay for a Groq key, supply it and the per-minute price drops by 60%.

| What you give it | What you get back |
| --- | --- |
| An MP3 or WAV link | Transcript with timed passages |
| A video file | The same — the video track is discarded |
| A three-hour podcast | One transcript, timings continuous across parts |
| A recording in any language | Text in that language, or translated to English |
| `chunkForRag: true` | Chunks with timecodes, ready to embed |

### What data can Speech to Text extract?

| Field | Type | Example |
| --- | --- | --- |
| `source` | string | `https://example.com/episode-12.mp3` |
| `fileName` | string | `episode-12.mp3` |
| `durationSeconds` / `durationMinutes` | number | `461.05` / `7.68` |
| `language` | string | `English` |
| `model` | string | `fast` or `accurate` |
| `translatedToEnglish` | boolean | `false` |
| `transcript` | string | `It is a truth universally acknowledged…` |
| `wordCount` / `charCount` | integer | `1665` / `9218` |
| `segmentCount` | integer | `101` |
| `speakerCount` | integer | `3` (only when speaker labels are on) |
| `speakers` | array | `["Speaker 1", "Speaker 2", "Speaker 3"]` |
| `segments` | array | `[{"start": 0, "duration": 4.56, "text": "It is a truth universally acknowledged…", "speaker": "Speaker 1"}]` |
| `chunks` | array | `[{"index": 0, "start": 0, "startTimecode": "00:00:00", "text": "…", "charCount": 1180}]` |
| `subtitles` | string | A complete SRT or WebVTT file |
| `status` / `errorCode` / `errorMessage` | string | `ok`, or why a file failed |
| `transcribedAt` | string | `2026-09-05T11:42:07+00:00` |

### How much does transcription cost?

| Event | Price | When it is charged |
| --- | --- | --- |
| Minute transcribed | $0.03 | Per started minute, using the built-in key |
| Minute with your own key | $0.012 | Per started minute when you supply a Groq key |
| Add-on: Speaker labels | $0.012 | Per started minute, only when **Speaker labels** is on |
| File processed | $0.002 | Per file downloaded and prepared |

Minutes are counted per started minute with the last second free, so a recording that a
container format reports as 10:00.01 is charged as ten minutes, not eleven.

**Files that fail are never charged.** A dead link, a file above the size limit, a video with no audio track or a recording with no speech in it comes back as an `error` row at no cost.

| Job | Cost |
| --- | --- |
| A 45-minute podcast episode | $1.35 |
| The same episode with speaker labels | $1.89 |
| 10 hours of interviews | $18.02 |
| 100 one-minute voice notes | $3.20 |
| A 45-minute episode with your own Groq key | $0.54 |

Comparable transcription Actors charge $10 to $48 per 1,000 minutes; this one is $30, or $12 with your own key. The Apify Free plan includes $5 of monthly usage, which is about **160 minutes** of audio before you pay anything.

### How to transcribe an audio file

1. Click **Try for free** and sign in to Apify.
2. Paste media links into **Audio or video URLs**, or use **Upload a file**.
3. Leave quality on **Fast** unless the recording is noisy or heavily accented.
4. Optionally set the spoken language, or leave it empty to detect it automatically.
5. Press **Start**, then read the **Output** tab or export as JSON, CSV or Excel.

### ⬇️ Input

![Speech to Text input: audio and video URLs, recognition quality, language, subtitles and RAG chunks](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/speech-to-text/speech-to-text-input-form.png)

```json
{
  "urls": ["https://example.com/episode-12.mp3"],
  "quality": "fast",
  "language": "en",
  "includeSegments": true,
  "chunkForRag": false,
  "subtitleFormat": "srt"
}
```

#### Quality

**Fast** uses Whisper large v3 turbo and handles clean speech at about 5% word error. **Accurate** uses the full Whisper large v3 — around 3% on the same audio, better on accents, background noise and technical vocabulary. Both cost the same here; the difference is time.

#### Language and translation

Leave `language` empty and the language is detected from the audio. Set a two-letter code when you already know it — that is faster and avoids mistakes on short clips. `translateToEnglish` returns English text whatever the speaker used.

#### Vocabulary hint

`vocabularyHint` takes names, product terms or spellings that appear in the recording. It nudges the engine toward the right proper nouns, which is the usual source of embarrassing transcripts.

#### Speaker labels

Switch on **🗣️ Speaker labels ($)** and every segment says who is talking. The transcript is
laid out as a conversation, one paragraph per turn, and SRT and WebVTT subtitles carry the
name in front of each line:

```
Speaker 1: So how did the migration actually go?
Speaker 2: Better than we expected. We moved the last service on Friday.
```

Leave **Number of speakers** empty and the Actor works out how many voices are in the
recording. Set it when you already know — two people in an interview, four in a panel —
and the result is steadier, especially on noisy audio.

Speakers are found from the audio itself, inside the Actor, with no second service and no
extra key. Voices that talk over each other are given to whoever holds most of the segment,
so a heated cross-talk moment can be labelled with one name instead of two.

#### Long files

There is no length limit. Files are converted to compact mono audio and, when still too large for one request, split into parts and reassembled — timings stay continuous across the joins, so a segment at 02:41:15 really is at 02:41:15.

#### Bring your own key

Supply a Groq API key in **Your own Groq API key** and the price per minute drops from $0.03 to $0.012. You then pay Groq directly for the recognition, which at their rates is a fraction of a cent per minute.

### ⬆️ Output

![Speech to Text output: one row per file with duration, language, word count and timed passages](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/speech-to-text/speech-to-text-output-table.png)

```json
{
  "source": "https://example.com/episode-12.mp3",
  "fileName": "episode-12.mp3",
  "durationMinutes": 7.68,
  "language": "English",
  "model": "fast",
  "transcript": "It is a truth universally acknowledged, that a single man in possession of a good fortune…",
  "wordCount": 1665,
  "segmentCount": 101,
  "segments": [
    { "start": 0, "duration": 4.56, "text": "It is a truth universally acknowledged, that a single man in possession of a good fortune," }
  ],
  "status": "ok",
  "transcribedAt": "2026-09-05T11:42:07+00:00"
}
```

#### Error rows

| `errorCode` | Meaning |
| --- | --- |
| `network-error` / `http-error` / `not-found` | The file could not be downloaded |
| `too-large` | The file is above the size limit you set |
| `unreadable-media` | The file has no audio track, or is not media at all |
| `no-speech` | Nothing was recognised — silence, or music with no words |
| `invalid-api-key` | The Groq key you supplied was rejected |
| `rate-limited` | The recognition service throttled the run after retries |
| `budget-reached` | The run hit its maximum total charge; raise it and run the rest again |

### Use cases

#### Podcasts and interviews

Turn episodes into searchable text, show notes and quotes. Timed segments make it easy to find the moment a topic came up.

#### Meetings and calls

Transcribe recordings for minutes and follow-ups. Add participant names as a vocabulary hint so they are spelled right.

#### Subtitles

Get an SRT or WebVTT file back and attach it to the video, or translate it first.

#### Voice notes and support calls

Feed short recordings in bulk and run analysis over the text — one row per file, one prompt for all of them.

#### Feeding audio into a RAG pipeline

Chunks carry the timecode where they start, so an answer built on hours of recordings can cite the exact moment instead of the whole file.

### Integrations

- **API**: `POST https://api.apify.com/v2/acts/lergassy~speech-to-text/runs`
- **Python**: `ApifyClient(token).actor('lergassy/speech-to-text').call(run_input={'urls': [...]})`
- **JavaScript**: `await client.actor('lergassy/speech-to-text').call({ urls: [...] })`
- **n8n, Make, Zapier, Google Sheets, Airtable**: run the Actor and map the dataset onward.
- **MCP**: available through the Apify MCP server as a callable tool.
- **Webhooks**: fire a webhook when a run finishes.

### 🤖 For AI agents and LLM apps

```json
{ "urls": ["https://example.com/call.mp3"], "chunkForRag": true }
```

- One row per file; `status` is `ok` or `error`, so a failed file needs no log parsing.
- `transcript` is the field to summarise; `chunks` is the field to embed.
- Every chunk carries `startTimecode`, so an answer can cite the moment it came from.
- `language` reports what was actually detected, which is worth checking before acting on the text.
- Failed files are never charged, so agent retries stay cheap.

### ❓ FAQ

#### Do I need an API key?

No. Recognition works out of the box. Supplying your own Groq key is optional and lowers the per-minute price.

#### How long can a file be?

There is no fixed limit. Long recordings are split and stitched back together automatically; a three-hour file is a normal input.

#### Which languages are supported?

Whisper covers 90+ languages, including English, Russian, Spanish, German, French, Portuguese, Indonesian, Arabic, Hindi, Chinese, Japanese and Korean. Detection is automatic unless you set the language yourself.

#### Can it separate speakers?

Yes. Switch on **Speaker labels** and each segment carries `Speaker 1`, `Speaker 2` and so
on, the transcript reads as a conversation and subtitles show the name on every line. It
costs $0.012 per minute on top of the transcription. Tell the Actor how many people are in
the recording if you know — it makes the result steadier.

#### Does speaker labelling name the people?

No. It tells the voices apart and numbers them in the order they first speak; it cannot know
that Speaker 2 is Maria. Renaming them afterwards is a find-and-replace on the transcript.

#### What about videos?

Any video ffmpeg can read works — the audio track is extracted and the video is discarded, so you are not charged for pixels.

#### What is the difference from YouTube Transcript Scraper?

[YouTube Transcript Scraper](https://apify.com/lergassy/youtube-transcript-scraper) reads captions that already exist on YouTube, which is far cheaper. This Actor listens to the audio, so it works on any file and on videos that have no captions at all.

#### Can I use it with the Apify API or an MCP server?

Yes to both, like any Apify Actor.

### Your feedback

Missing a language, a format or a field? Open an issue on the **Issues** tab — issues are answered quickly.

### You might also like

| Actor | What it does |
| --- | --- |
| [YouTube Transcript Scraper](https://apify.com/lergassy/youtube-transcript-scraper) | Existing YouTube captions with timecodes and chapters |
| [Document Text Extractor](https://apify.com/lergassy/document-text-extractor) | PDF, Word, Excel and PowerPoint to Markdown and RAG chunks |
| [OCR Text Extractor](https://apify.com/lergassy/ocr-text-extractor) | Images and scanned PDFs to text with confidence scores |
| [Trustpilot Reviews API](https://apify.com/lergassy/trustpilot-reviews-api) | Trustpilot reviews, ratings and company replies |

# Actor input Schema

## `urls` (type: `array`):

Direct links to media files: MP3, M4A, WAV, FLAC, OGG, MP4, MOV, WEBM and anything else ffmpeg can read. Video files are stripped to their audio track automatically.

## `file` (type: `string`):

Upload one audio or video file from your computer instead of giving a URL.

## `quality` (type: `string`):

Fast is the everyday choice. Accurate makes fewer mistakes on accents, noise and technical vocabulary, and costs more.

## `language` (type: `string`):

Two-letter code of the language spoken, for example <code>en</code>, <code>ru</code>, <code>id</code>. Leave empty to detect it automatically.

## `translateToEnglish` (type: `boolean`):

Return an English transcript no matter what language is spoken.

## `diarize` (type: `boolean`):

Mark who is speaking in each part of the recording. Every segment gets a speaker ("Speaker 1", "Speaker 2", …), the transcript is laid out as a conversation, and subtitles carry the names. Charged per minute on top of the transcription, and slow: the speaker model runs on the machine, so expect several minutes of processing per hour of audio, while a plain transcript is near-instant.

## `speakerCount` (type: `integer`):

How many people talk in the recording. Leave empty and the Actor works it out on its own; set it when you already know, for example two people in an interview.

## `vocabularyHint` (type: `string`):

Names, jargon or spellings that appear in the audio, comma separated. Helps the engine get proper nouns right.

## `includeSegments` (type: `boolean`):

Return every recognised passage with its start time and duration, alongside the full transcript.

## `chunkForRag` (type: `boolean`):

Split the transcript into retrieval chunks that keep the timecode where each one starts.

## `chunkSize` (type: `integer`):

Target size of one chunk. Chunks break on sentence ends, so real sizes vary.

## `chunkOverlapSeconds` (type: `integer`):

How many seconds of the previous chunk to repeat at the start of the next one.

## `subtitleFormat` (type: `string`):

Also return a ready-made subtitle file as text.

## `apiKey` (type: `string`):

Optional. Supply your own key and the per-minute price drops sharply; you then pay Groq directly for the recognition. Leave empty to use the built-in key with nothing to set up.

## `maxConcurrency` (type: `integer`):

How many files to transcribe at the same time.

## `maxFileSizeMb` (type: `integer`):

Files larger than this are skipped with an error row instead of being downloaded.

## `timeoutPerFileSecs` (type: `integer`):

How long one file may take to download and recognise before it is given up on.

## Actor input object example

```json
{
  "urls": [
    "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/audio-samples/sample-5min.m4a"
  ],
  "quality": "fast",
  "translateToEnglish": false,
  "diarize": false,
  "includeSegments": true,
  "chunkForRag": false,
  "chunkSize": 1200,
  "chunkOverlapSeconds": 0,
  "subtitleFormat": "none",
  "maxConcurrency": 3,
  "maxFileSizeMb": 500,
  "timeoutPerFileSecs": 600
}
```

# Actor output Schema

## `transcripts` (type: `string`):

Dataset with one row per audio or video file.

## `transcriptsInConsole` (type: `string`):

Browse the transcripts in the Apify Console.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/audio-samples/sample-5min.m4a"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/speech-to-text").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": ["https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/audio-samples/sample-5min.m4a"] }

# Run the Actor and wait for it to finish
run = client.actor("lergassy/speech-to-text").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/audio-samples/sample-5min.m4a"
  ]
}' |
apify call lergassy/speech-to-text --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/speech-to-text"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/oQtGP7GIlVnSqwe32/builds/mfZ6eS8BxFpy92czz/openapi.json
