# Audio Transcription - Audio to Text, Speech to Text, SRT (`kaz_kakyo/audio-transcriber`) Actor

Transcribe audio/video file URLs to text via API/MCP/schedule. Whisper alternative: speech to text and video to text for meeting recordings, interviews, podcasts. Convert audio to text from MP3/MP4/WAV or public Google Drive/Dropbox file links. SRT subtitles, speaker diarization, English summaries.

- **URL**: https://apify.com/kaz_kakyo/audio-transcriber.md
- **Developed by:** [Heim](https://apify.com/kaz_kakyo) (community)
- **Categories:** AI, Videos, Automation
- **Features:** Limited permissions
- **Stats:** 363 total users, 86 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 audio minute (zero setup)s

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Audio Transcriber — Fast, Accurate Speech-to-Text

**URL in → transcript out.** Pass direct audio/video file URLs; get one JSON dataset row per file. **Google Drive / Dropbox share links, Apple Podcasts episode links, Loom share links, and progressive Vimeo links are resolved to the media file automatically.** No separate speech-to-text account required. API callers still need an Apify API token. Built for **MCP agents, API clients, and scheduled pipelines** (that is how almost all usage runs today).

| | |
|---|---|
| **Actor id** | `kaz_kakyo/audio-transcriber` |
| **Minimal input** | `{ "audioUrls": ["https://dpgr.am/spacewalk.wav"] }` |
| **Cost** | **$0.010/min** zero-setup · **$0.004/min** BYOK · $0.00005 base start event (scales with memory) |
| **Output** | Dataset rows with `type: "transcript"` or `type: "error"` |

### Call it (MCP / API / schedule)

#### MCP (agents)

```json
{
  "actor": "kaz_kakyo/audio-transcriber",
  "input": {
    "audioUrls": ["https://dpgr.am/spacewalk.wav"]
  }
}
```

Optional extras agents usually want:

```json
{
  "audioUrls": ["https://dpgr.am/spacewalk.wav"],
  "diarize": true,
  "summarize": true,
  "includeSrt": true
}
```

After the run, read the default dataset. Every row has a `type` discriminator — filter on `"transcript"`; treat `"error"` as per-file failure. Bad/unsupported URLs become error rows and the run still **SUCCEEDS** (including all-failed batches) so agent mistakes do not look like platform outages. Missing provider credentials, upstream auth/credit errors, or a failure to save output after charging can fail the run.

#### API / `apify-client`

Install `apify-client` and set `APIFY_TOKEN` in your environment. This public 26-second sample should return one transcript, billed as one minute: **$0.010** for transcription, plus the memory-scaled start event, with optional chapters off. Runs default to 4096 MiB; 2048 MiB also works for zero-setup files up to 1 GiB. It has one speaker; use your own permitted interview to try multiple-speaker labels.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('kaz_kakyo/audio-transcriber').call(
  { audioUrls: ['https://dpgr.am/spacewalk.wav'], diarize: true },
  { maxTotalChargeUsd: 1.0, memory: 4096 }, // hard budget for this run
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const transcripts = items.filter((i) => i.type === 'transcript');
const errors = items.filter((i) => i.type !== 'transcript');
console.log({ runId: run.id, transcripts, errors });
```

Same shape via REST: `POST /v2/acts/kaz_kakyo~audio-transcriber/runs` with your token, then poll or attach a webhook.

#### Process new recordings repeatedly

Use a saved Task for fixed options, and pass **new media URLs** from your CMS, RSS feed or file uploader. A new run can transcribe and bill the same URL again; scheduling a fixed list does not provide cross-run deduplication.

1. Record a stable source ID and the Apify run ID in a durable ledger before retrying uncertain work.
2. Set `maxTotalChargeUsd` on every run. This caps each run, not monthly spending or all retries combined.
3. Read every dataset row. Save transcripts and route error/skip rows to a review destination. Also handle FAILED/TIMED-OUT runs.
4. If a request times out, inspect the existing run and dataset before starting another paid run.

Long runs checkpoint completed URLs for migration/resume within the same run. This is not an across-run ledger.

[Podcast transcription guide and n8n starter](https://github.com/jx-yan/n8n-transcription-workflows/blob/master/podcast-transcription-guide.md) — runnable API example, cost calculations, and explicit replay/restart limits.

### For actor developers — use this as your transcription backend

Building an actor that touches audio or video (podcast tools, meeting pipelines, media
scrapers)? Call this actor from yours instead of integrating a speech-to-text vendor:
no key to manage, no audio handling, and **your user's account pays the per-minute
event directly** — you never proxy the cost.

```js
import { Actor } from 'apify';

const run = await Actor.call(
  'kaz_kakyo/audio-transcriber',
  { audioUrls: mediaUrls, diarize: true },
  { maxTotalChargeUsd: 2.0 },
);
const { items } = await Actor.apifyClient.dataset(run.defaultDatasetId).listItems();
const transcripts = items.filter((i) => i.type === 'transcript');
```

**Contract stability promise:** the input fields and the `type: "transcript" | "error"`
output shape documented on this page are a frozen public contract — fields are only
ever added, never renamed or removed, so a nested integration does not break on our
releases. Batch-safe by design: your users' bad URLs come back as `error` rows, never
as a failed run inside your actor.

### Output contract

One dataset item per input URL (plus skipped/invalid rows). Success shape:

```json
{
  "type": "transcript",
  "url": "https://dpgr.am/spacewalk.wav",
  "transcript": "Full smart-formatted text…",
  "durationSeconds": 204.3,
  "minutesBilled": 4,
  "model": "nova-3",
  "language": "en",
  "confidence": 0.97,
  "summary": "…",
  "speakerTranscript": "Speaker 0: …\nSpeaker 1: …",
  "srt": "1\n00:00:00,000 --> …",
  "utterances": [{ "start": 0.0, "end": 3.2, "speaker": 0, "text": "…" }],
  "words": [{ "word": "Hello", "start": 0.0, "end": 0.4, "confidence": 0.99, "speaker": 0 }]
}
```

| Field | When present |
|---|---|
| `transcript`, `durationSeconds`, `minutesBilled`, `language`, `confidence`, `model` | always on success |
| `summary` | `summarize: true` (English audio) |
| `speakerTranscript` | `diarize: true` |
| `srt` | `includeSrt: true` |
| `utterances` / `words` | respective toggles |
| `resolvedUrl` | input was a share/episode link — the direct media URL actually transcribed (`url` stays your input) |
| `wordsUrl` / `utterancesUrl` / `srtUrl` | rare — oversized payloads spilled to the key-value store |

Failure / skip row (never charged):

```json
{ "type": "error", "url": "https://…", "error": "…" }
```

Download the dataset as JSON, CSV, Excel, or HTML from Console or the dataset API.

### Why this one

- **Two pricing options.** Managed transcription is $0.01/min; BYOK is $0.004/min actor fee plus your own provider bill. Both add the start event.
- **Nova-3 by default** — or `nova-2` / `whisper-large`. Diarization, SRT, summaries, keyterm boosting.
- **Guarded local checks.** Zero-setup runs download and decode media before provider processing. BYOK sends the URL to the provider.
- **Batch-safe for agents.** Bad links become `type: "error"` rows; URL/decode mistakes do not fail the run — inspect run failures separately from per-file errors.

### Related actors

- [YouTube Transcripts](https://apify.com/kaz_kakyo/youtube-transcripts): captions and SRT from YouTube videos and channels, no audio upload needed.
- [Media URL Transcriber](https://apify.com/kaz_kakyo/media-url-transcriber): Vimeo, Loom and podcast RSS URLs to text.

### Pricing

| Event | Price | When |
|---|---|---|
| Audio minute (zero-setup) | **$0.010** | No key — transcription included |
| Audio minute (BYOK) | **$0.004** | `deepgramApiKey` set — you pay your provider at cost |
| Actor start | $0.00005 base | Once per run; units scale with memory above 1 GB |

Minutes round **up per file**. With optional chapters off, 90 seconds costs **$0.020** in managed minute charges; a 60-minute recording costs **$0.600** managed, or **$0.240 actor minute fees plus your own provider bill** with BYOK. Add the memory-scaled start charge. Splitting a recording into files can increase rounded minutes.

**Free Apify plan:** zero-setup transcription needs a paid Apify plan. On a free plan, each file returns an uncharged `free-plan` error row and the run still succeeds; set `deepgramApiKey` to transcribe at the BYOK rate.

Optional chapter generation adds $0.01 per generated chapter set plus your own LLM usage. Start-event pricing can scale with run memory; check the Pricing tab for your settings. BYOK savings depend on your provider plan.

### Input rules agents must follow

- **`audioUrls` (required)** — direct `https` links to files (`mp3`, `wav`, `m4a`, `flac`, `ogg`, `opus`, `mp4`, `mov`, `webm`, `mkv`; ≤2 GiB at the default 4096 MiB memory, ≤1 GiB at 2048 MiB). Google Drive / Dropbox share links, Apple Podcasts **episode** links (the URL with `?i=…`), Loom share/embed links, and progressive Vimeo links are resolved to the file automatically. **Not** YouTube / TikTok / Spotify / SoundCloud page URLs — those cannot be resolved here. For YouTube captions use [kaz_kakyo/youtube-transcripts](https://apify.com/kaz_kakyo/youtube-transcripts); for HLS/captioned Vimeo or podcast RSS feeds use [kaz_kakyo/media-url-transcriber](https://apify.com/kaz_kakyo/media-url-transcriber).
- **`deepgramApiKey`** — optional; encrypted; sent only to the transcription provider.
- **`model`** — `nova-3` (default), `nova-2`, `whisper-large`.
- **`language`** / **`detectLanguage`** — BCP-47 or auto-detect; `multi` + nova-3 for code-switching.
- **Toggles** — `diarize`, `smartFormat`, `paragraphs`, `summarize`, `includeSrt`, `includeUtterances`, `includeWords` (see Input tab).
- **`keyterms`** — nova-3 only; boost product names / jargon / speaker names.

Limits: 500 files/run, ~10 min upstream processing per file, at most 4 concurrent provider jobs (2 for Whisper). Zero-setup files are checked before paid processing: the full decoded audio must fit the run budget, six hours, and the decoded-audio limit (1 GiB at 2048 MiB memory, about 4.6 hours of stereo or the full six hours of mono; 2 GiB at 4096 MiB or more). Oversized files are rejected rather than partially transcribed. Silent audio that decodes is still billed by duration.

Zero-setup processing also needs enough disk for each complete input and its decoded audio. Apify allocates disk at twice run memory, and 1 GiB is kept for the runtime. Below 4096 MiB each active file reserves 2 GiB (downloads and decoded audio up to 1 GiB each), so 2048 MiB admits one file at a time. At 4096 MiB or more each file reserves 4 GiB (up to 2 GiB each): 4096 MiB admits one file, 8192 MiB three and 16384 MiB four (subject to the model cap). A file over the 2048 MiB limits returns an uncharged `insufficient-resources` error that names 4096 MiB, and stays eligible when the run is resurrected with more memory. Allocations that cannot cover one file (below 2048 MiB) return the same uncharged error before downloading or decoding. Waiting jobs recheck the monetary budget. BYOK URL processing retains its existing path.

**Default memory:** runs default to 4096 MiB, the fastest setting for long files: a 53-minute podcast took about 22 s at 4096 MiB and 36–66 s at 2048 MiB, at similar compute cost. If you set memory yourself (API `memory`, a saved task or a schedule), 2048 MiB also works for zero-setup files up to 1 GiB (larger files return an uncharged `insufficient-resources` error naming 4096 MiB), and 8192 MiB or more processes several files in parallel. Below 2048 MiB zero-setup files return the uncharged `insufficient-resources` error. BYOK runs work with less memory. At 4096 MiB the start event counts as four units ($0.0002 per run).

See the **Input** tab for the full schema. See the **API** tab for run/dataset endpoints.

### FAQ

**Do I need my own speech-to-text account?** No. Bring a key only for the $0.004/min rate.

**What languages?** Nova-3: 30+. `whisper-large`: 90+ for rarer languages.

**Is my audio stored?** Zero-setup runs temporarily download and decode media on the worker to check its duration and budget, then delete those temporary files. Source audio is not published to the dataset or key-value store. BYOK runs send the media URL to the speech-to-text service. Transcript JSON and oversized transcript fields are retained in your run outputs.

**Why did my URL fail?** It was not a direct, publicly reachable (or signed) media file, and not a resolvable share link (Drive/Dropbox/Apple Podcasts episode). Resolve other page URLs with a downloader first, then call this actor. The run still succeeds with `type: "error"` rows — check the dataset, not the run status. (Drive note: files past ~100 MB hit Drive's virus-scan page — host very large files elsewhere or use a signed URL.)

**How do I keep costs predictable on a schedule?** Set `maxTotalChargeUsd` on the run/task. Prefer BYOK once volume is steady.

***

*If this saved you time, a Store review on the [actor page](https://apify.com/kaz_kakyo/audio-transcriber) helps our team. Hit a problem? [Open an issue](https://apify.com/kaz_kakyo/audio-transcriber/issues).*

### Telemetry

When telemetry is configured, the actor sends usage and charge-summary events to the developer: a pseudonymous caller hash, paying-plan flag, run ID, origin, timestamps and event counts, plus how many inputs were YouTube or TikTok page links (counts only), and a per-run workflow summary: counts of input link types (direct file, Google Drive, Dropbox, Apple Podcasts, web-page link, invalid), transcript lengths in broad buckets (under 5 min, 5–30, 30–120, over 120), batch size bucket, which on/off options were used, whether the language was English or another language, and the memory tier. No media URLs, hostnames, file names, input content or transcripts are included.

# Actor input Schema

## `audioUrls` (type: `array`):

Required. Direct https links to media files (mp3, wav, m4a, flac, ogg, opus, mp4, mov, webm, mkv — up to 2 GiB each at the default 4096 MiB memory, 1 GiB at 2048 MiB). Zero-setup files must also fit six hours, the decoded-audio limit (1 GiB at 2048 MiB, 2 GiB at 4096 MiB+), and the run budget; a file over the 2048 MiB limits returns an uncharged resource error asking for 4096 MiB. Oversized files are rejected without a partial transcript. Google Drive/Dropbox share links, Apple Podcasts episode links (?i=…), Loom share/embed links, and progressive Vimeo video links resolve automatically. One dataset row per URL; max 500 per run. Do NOT pass YouTube/Spotify/SoundCloud page URLs. Bad URLs become type:error rows; the run still succeeds.

## `deepgramApiKey` (type: `string`):

Optional. Leave empty for zero-setup at $0.010/min (paid Apify plans only). Or bring your own speech-to-text API key and pay $0.004/min here plus your provider's wholesale ~$0.0043/min directly; this also works on the free Apify plan. Best for scheduled/API volume. Stored encrypted; sent only to the transcription provider.

## `model` (type: `string`):

Speech model. Default `nova-3` (fast, accurate, multilingual). `nova-2` = previous generation; `whisper-large` = rarer languages (runs at lower concurrency).

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

Optional BCP-47 code (e.g. `en`, `es`, `zh`, `de`). Leave empty for English, or set `detectLanguage`. Use `multi` with nova-3 for code-switched audio.

## `detectLanguage` (type: `boolean`):

Default: false. When true, detect the dominant language per file and transcribe in it. Overrides `language`.

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

Default: false. When true, adds `speakerTranscript` (`Speaker 0: …`) and speaker labels on SRT/utterances/words. Typical for meetings and interviews.

## `smartFormat` (type: `boolean`):

Default: true. Punctuation plus formatted dates, numbers, currency, phones, and emails in `transcript`.

## `paragraphs` (type: `boolean`):

Default: true. Split `transcript` into readable paragraphs instead of one wall of text.

## `summarize` (type: `boolean`):

Default: false. When true, adds `summary` (short abstract). English audio only — ignored for explicit non-English `language`.

## `includeSrt` (type: `boolean`):

Default: false. When true, adds `srt` (ready-to-save `.srt` string; speaker tags when `diarize` is on).

## `includeUtterances` (type: `boolean`):

Default: false. When true, adds `utterances[]`: `{ start, end, speaker, text }` per spoken segment. Useful for programmatic indexing.

## `includeWords` (type: `boolean`):

Default: false. When true, adds `words[]` with per-word timing and confidence. Large output on long audio — prefer utterances for most pipelines.

## `keyterms` (type: `array`):

Optional. Product names, jargon, or speaker names to boost recognition (nova-3 keyterm prompting). Ignored on other models.

## `generateChapters` (type: `boolean`):

Default: false. When true and `llmApiKey` is set, each transcript row additionally gets `chapters[]` (`{ startSeconds, title }`) and `showNotes` (markdown episode summary), generated by your own LLM provider — $0.010 per file, charged only when chapters are delivered. An LLM failure never fails the run or the file: the transcript is delivered unchanged with a `chaptersError` note.

## `llmApiKey` (type: `string`):

Optional. Your own API key for an OpenAI-compatible LLM provider — required when `generateChapters` is on. Stored encrypted; sent only to the host in `llmBaseUrl`; never logged and never included in output rows. You pay your LLM provider's token cost directly.

## `llmBaseUrl` (type: `string`):

Default: `https://api.openai.com/v1`. Base URL of any OpenAI-compatible chat-completions API. Your `llmApiKey` is sent only to this host.

## `llmModel` (type: `string`):

Default: `gpt-5-mini`. Model name passed to the OpenAI-compatible endpoint when generating chapters + show notes.

## Actor input object example

```json
{
  "audioUrls": [
    "https://dpgr.am/spacewalk.wav"
  ],
  "model": "nova-3",
  "detectLanguage": false,
  "diarize": false,
  "smartFormat": true,
  "paragraphs": true,
  "summarize": false,
  "includeSrt": false,
  "includeUtterances": false,
  "includeWords": false,
  "generateChapters": false,
  "llmBaseUrl": "https://api.openai.com/v1",
  "llmModel": "gpt-5-mini"
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "audioUrls": [
        "https://dpgr.am/spacewalk.wav"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kaz_kakyo/audio-transcriber").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 = { "audioUrls": ["https://dpgr.am/spacewalk.wav"] }

# Run the Actor and wait for it to finish
run = client.actor("kaz_kakyo/audio-transcriber").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 '{
  "audioUrls": [
    "https://dpgr.am/spacewalk.wav"
  ]
}' |
apify call kaz_kakyo/audio-transcriber --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kaz_kakyo/audio-transcriber"
        }
    }
}
```

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/9WKjU5fxRBHDl4PKu/builds/0ZHrgnJ6Nqk0rhaMK/openapi.json
