# Podcast & Audio Transcription with Speaker Labels (SRT, VTT) (`iiclabs/podcast-audio-transcription-speakers`) Actor

Transcribe audio and video links or whole podcast RSS feeds: transcripts with speaker labels and timestamps, plus SRT and VTT subtitles. Only-new mode transcribes just new episodes on a schedule. Pay per audio minute.

- **URL**: https://apify.com/iiclabs/podcast-audio-transcription-speakers.md
- **Developed by:** [IIC Labs](https://apify.com/iiclabs) (community)
- **Categories:** AI, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.50 / 1,000 audio minutes

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?

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

## Podcast & Audio Transcription with Speaker Labels (SRT, VTT)

**Transcribe podcasts, interviews, meetings and videos with speaker labels and timestamps, and get ready-to-use SRT and VTT subtitles.** Give it audio or video links, or a podcast's RSS feed, and it returns who said what, when, for every recording. On a schedule with *Only new episodes*, it transcribes each new episode of a show and nothing twice.

Speaker labels, word-level timing and both subtitle formats are **included in one per-minute price**, not sold as extras.

### What you get

For each recording:

- **the transcript as text**, one paragraph per speaker turn (`Speaker 1: ...`, `Speaker 2: ...`);
- **segments** with start and end times in seconds, the text and the speaker, ready for search, quotes, chapters or AI pipelines;
- **SRT and VTT subtitle files** in the run's key-value store (speaker names included);
- the episode's title, link and publication date when it came from a feed.

### Input

| Field | What it does |
|---|---|
| **Audio or video links** | Direct links to MP3, M4A, WAV, MP4, WEBM, OGG or FLAC files, up to 1 GB each. |
| **Podcast RSS feeds** | The newest episodes of each feed are transcribed. |
| **Episodes per feed** | How many of the newest episodes (default 3). |
| **Only new episodes** | Transcribe, and pay for, only episodes published since your last run. The first run transcribes the newest ones and remembers the older episodes in the feed as already there. Perfect for a daily or weekly schedule. |
| **State name** | Separate memory per schedule. |
| **Language** | Two-letter code (en, de, es, fr, ...), or empty to detect it. |
| **Speaker labels** | On by default. |
| **Maximum minutes per recording** | Longer recordings are transcribed up to this length (default 240). |

```json
{
  "feeds": ["https://feeds.example.com/podcast.xml"],
  "maxEpisodesPerFeed": 5,
  "onlyNew": true,
  "language": "en"
}
```

### Output

One dataset item per recording:

```json
{
  "url": "https://cdn.example.com/episodes/42.mp3",
  "episodeTitle": "Episode 42: Searching twenty years of contracts",
  "publishedAt": "2026-10-14T08:00:00.000Z",
  "status": "ok",
  "durationSeconds": 2735,
  "language": "eng",
  "speakers": 2,
  "text": "Speaker 1: Welcome back to the show. ...\n\nSpeaker 2: Thanks for having me. ...",
  "segments": [
    { "start": 0.6, "end": 6.9, "text": "Welcome back to the show.", "speaker": "Speaker 1" }
  ],
  "files": {
    "txt": "https://api.apify.com/v2/key-value-stores/<store-id>/records/001-transcript.txt",
    "srt": "https://api.apify.com/v2/key-value-stores/<store-id>/records/001-transcript.srt",
    "vtt": "https://api.apify.com/v2/key-value-stores/<store-id>/records/001-transcript.vtt"
  },
  "error": null
}
```

### Pricing

Pay per event: **one audio minute** for each started minute transcribed, plus Apify's small start fee per run. Speaker labels, timestamps, SRT and VTT are included. Recordings that fail (broken links, files that aren't audio) are not charged.

**Apify's free plan** transcribes up to 10 minutes per run (longer recordings: the first 10 minutes), enough to try it; paid Apify plans have no such limit. The *Maximum cost per run* you set is respected: a recording that would go past it is transcribed up to the limit and marked `trimmed`, and the rest are skipped. With *Only new episodes*, an episode cut short by the cost limit is transcribed again in full on the next run.

### Good to know

- Recordings longer than 2 hours 20 minutes are transcribed in parts of that length; speaker numbering can restart in each part.
- With *Only new episodes*, set *Episodes per feed* to at least the number of episodes published between your runs; any left over are picked up by the next run.
- A recording without speech (silence, music only) returns an empty transcript with a note and is charged by its length, like any processed audio.
- Transcription quality depends on the audio: clear speech gives the best results; heavy music, crosstalk and strong noise give weaker text and speaker labels.
- Only transcribe recordings you have the right to use. The audio is sent to a third-party speech-to-text service (ElevenLabs Scribe v2, reached through OpenRouter) to be transcribed; we keep no copy of your files or transcripts, and the results stay in your own Apify storage. Check that this is acceptable for confidential recordings.

### FAQ

**Which languages?** Dozens, detected automatically; setting the language helps for short clips.

**Can I use it in Make, Zapier or n8n?** Yes, through Apify's integrations or the Apify API.

**Support:** support+transcription@iiclabs.com. Include the run ID if something looks wrong. If it saved you time, a rating on this page helps others find it.

# Actor input Schema

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

Direct links to audio or video files (MP3, M4A, WAV, MP4, WEBM, OGG, FLAC), up to 1 GB each.

## `feeds` (type: `array`):

Podcast feed URLs; the newest episodes are transcribed.

## `maxEpisodesPerFeed` (type: `integer`):

How many of the newest episodes to transcribe from each feed.

## `onlyNew` (type: `boolean`):

Transcribe (and pay for) only episodes published since the last run with the same state name. The first run transcribes the newest episodes and remembers the older ones in the feed as already there. Ideal for a daily or weekly schedule.

## `stateName` (type: `string`):

Separate memory for different schedules. Only used with "Only new episodes".

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

Two-letter language code (en, de, es, fr, ...) if you know it; leave empty to detect it.

## `speakerLabels` (type: `boolean`):

Label who is speaking (Speaker 1, Speaker 2, ...).

## `maxMinutesPerFile` (type: `integer`):

Longer recordings are transcribed up to this length (you pay per minute transcribed).

## Actor input object example

```json
{
  "audioUrls": [
    "https://iiclabs.com/samples/interview-sample.mp3"
  ],
  "feeds": [
    "https://feeds.example.com/podcast.xml"
  ],
  "maxEpisodesPerFeed": 3,
  "onlyNew": false,
  "stateName": "default",
  "speakerLabels": true,
  "maxMinutesPerFile": 240
}
```

# Actor output Schema

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

One item per recording: text, segments with speakers and timestamps, and links to the files.

## `summary` (type: `string`):

Recordings transcribed, failed and skipped, and minutes charged.

# 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://iiclabs.com/samples/interview-sample.mp3"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("iiclabs/podcast-audio-transcription-speakers").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://iiclabs.com/samples/interview-sample.mp3"] }

# Run the Actor and wait for it to finish
run = client.actor("iiclabs/podcast-audio-transcription-speakers").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://iiclabs.com/samples/interview-sample.mp3"
  ]
}' |
apify call iiclabs/podcast-audio-transcription-speakers --silent --output-dataset

```

## MCP server setup

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

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/vtAbGSkaLocIFeOdN/builds/Wdj7EhtwmRTKCK505/openapi.json
