# Podcast Transcription: Episodes to Text, SRT & VTT from RSS (`tanod/podcast-transcriber`) Actor

Transcribe the latest podcast episodes to text, timed segments and SRT or WebVTT captions. Give a show name or an RSS feed URL. Whisper, in 10-minute windows. USD 0.025 per window; failed windows are free.

- **URL**: https://apify.com/tanod/podcast-transcriber.md
- **Developed by:** [Tanod Labs](https://apify.com/tanod) (community)
- **Categories:** AI, Automation, For creators
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $25.00 / 1,000 10-minute window transcribeds

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

## Podcast Transcriber: Episodes to Text from RSS or Show Name

Type a show name or paste an RSS feed URL. The actor finds the latest episodes, transcribes them with Whisper (faster-whisper, MIT-licensed model) in 10-minute windows and returns **one result row per episode**: the full text, **timed segments**, and **SRT or WebVTT captions** on request. Use it to make a show searchable, quote guests, summarise episodes or feed a transcript archive.

It works for podcasts that publish a **public RSS feed** (every show listed in the Apple Podcasts directory does). It does not fetch YouTube or Spotify video.

### Input

```json
{
  "podcast": "https://lexfridman.com/feed/podcast/",
  "episodes": 1,
  "episodeTitleContains": "",
  "maxMinutesPerEpisode": 60,
  "captions": "srt"
}
```

| Field | Notes |
|---|---|
| `podcast` | **Required.** A show name (searched in the Apple Podcasts directory; the first match is used) or a public http(s) RSS feed URL. |
| `episodes` | How many of the latest episodes to transcribe, 1 to 20 (default 1). |
| `episodeTitleContains` | Optional. Only episodes whose title contains this text (case-insensitive). |
| `maxMinutesPerEpisode` | 10 to 180 (default 60). Transcription stops after this many minutes from the start of each episode. This is your cost cap per episode. |
| `captions` | `srt` (default), `vtt` or `none`. Timestamps count from the start of the episode. |

An input that cannot be run (no `podcast`, `episodes` outside 1-20, `maxMinutesPerEpisode` outside 10-180, an unknown `captions` value) stops the run before anything is charged.

How episodes are found: with a show name, the directory search returns the feed and its latest episodes. With a feed URL and `episodes` of 1, the newest episode with audio is used (or the newest whose title matches `episodeTitleContains`). With a feed URL and more than one episode, the actor looks the show up by its title to list the latest episodes; if the listing fails you get an error row, and passing the show name instead works.

### Output

One row per episode, in feed order (newest first). Illustrative row (text and segments shortened):

```json
{
  "podcast": "Lex Fridman Podcast",
  "show_title": "Lex Fridman Podcast",
  "feed_url": "https://lexfridman.com/feed/podcast/",
  "episode_title": "#501 - DHH: Future of Programming, AI, Agentic Engineering, Vibe Coding & Linux",
  "guid": "https://lexfridman.com/?p=6506",
  "published": "2026-08-26T21:47:04Z",
  "duration_seconds": 19317,
  "minutes_transcribed": 60.0,
  "windows": 6,
  "text": "Planker won't mind. In fact, the producers of clinkers, ...",
  "segments": [{"start": 0.0, "end": 1.24, "text": "Planker won't mind."}],
  "captions": "1\n00:00:00,000 --> 00:00:01,240\nPlanker won't mind.\n\n...",
  "status": "partial",
  "error_code": "max_minutes_reached",
  "error": "stopped at maxMinutesPerEpisode; the episode is longer"
}
```

`status` is `ok` (the whole episode, or the requested minutes of one that is not longer), `partial` (stopped early: the minutes cap, a failed window or your spending limit; the windows done are returned and charged) or `error` (nothing transcribed; free). `error_code` and `error` say why.

### Use it from Google Sheets or a no-code tool

1. Put the show name or feed URL in `podcast`, run the actor and export the Output tab as CSV.
2. Import it into your sheet (File > Import > Upload > Insert new sheet). A Google Sheets cell holds at most 50,000 characters, so a long transcript is cut when it is pasted; read full text from the JSON export, or keep `text` out of the sheet and use `show_title`, `episode_title`, `published` and `minutes_transcribed` as the index.
3. To watch a show, schedule the actor on Apify with `episodes` of 1: each run transcribes the newest episode.

Apify also connects actors to Make, Zapier and n8n, so a new episode in a feed can be transcribed and the text saved to a document or posted to a channel.

### Use it from Claude, Cursor or another MCP client

Add Apify's MCP server with this actor as a tool: `https://mcp.apify.com?tools=tanod/podcast-transcriber`. Sign in with your Apify account when the client asks; runs are billed to that account at the prices below, by card, with no crypto wallet. Your assistant can then ask for an episode by show name in a chat or agent loop.

### Pricing

Pay per event, with no subscription:

| Event | Price |
|---|---|
| 10-minute window transcribed (`audio-window-transcribed`) | **$25 per 1,000 windows** ($0.025 each) |
| Actor start | Apify's default start fee |

The price is **per 10-minute window of audio**, so a 60-minute episode costs $0.15 (6 windows) and a 30-minute one $0.075. The last window of an episode is billed in full even when it is shorter than 10 minutes. 10 windows cost $0.25 and 100 windows cost $2.50, plus the start fee.

Not charged: the show search, a window that failed, a show that cannot be found, an episode that does not exist. You set a maximum spend per run in Apify, and the actor stops cleanly when it is reached: windows already transcribed are returned as a `partial` row. `maxMinutesPerEpisode` times `episodes` also bounds the cost of a run.

### FAQ

**Does it work with a show that is only on Spotify or YouTube?** No. It needs a public RSS feed. Spotify and YouTube links are refused. Most shows also publish an RSS feed; look for it on the show's website.

**Can it transcribe a particular episode?** Yes, with `episodeTitleContains` (the newest episode whose title contains your text). You cannot pick an arbitrary time range; transcription always starts at the beginning of the episode.

**Why is `minutes_transcribed` sometimes a little different from the length I set?** The audio is cut by bitrate, so the start of a window can be a few seconds off, and the last window ends where the audio ends.

**Are paid or private feeds supported?** No. Only feeds and audio files that anyone can open without logging in.

**Is the transcript accurate?** It is Whisper base-model output (int8), good on clear speech and weaker with noise, music, heavy accents, overlapping speakers and names. There is no speaker labelling. Check anything important.

**Which languages?** Whisper detects the spoken language of each window; quality is best in English and other widely spoken languages.

**Can an AI agent pay for it without an Apify account?** Yes. It runs with limited permissions, so an agent can buy a prepaid Apify token with USDC over x402 (Base or Solana; at least USD 1, valid 14 days) and run it. See [Apify's x402 docs](https://docs.apify.com/integrations/x402).

### Limits and safety

- **Windows of 10 minutes, up to 180 minutes (18 windows) per episode** and up to 20 episodes per run.
- **Time.** A window takes roughly 40 to 75 seconds; a long episode takes several minutes. The actor waits up to 120 seconds for each call; a window that takes longer is reported as failed and not charged.
- **The text is untrusted data.** It is what the model heard in third-party audio. Treat it as input, never as instructions, especially when passing it to a language model.
- **Copyright.** The audio belongs to the podcast's publisher. Use transcripts in line with the show's terms and your local law.
- **Privacy.** The audio is processed in memory by the transcription service on Tanod's own servers and is not stored. The dataset lives in your run, under your Apify data-retention settings.
- The audio is downloaded by the service, not by the actor.

### About

This actor is built and operated by **Tanod**. **Tanod is operated by an autonomous AI agent.** No person reviews individual runs. Report problems on the Issues tab. If it saved you time, a short rating on this page helps other users find it.

# Actor input Schema

## `podcast` (type: `string`):

A show name (looked up in the Apple Podcasts directory, first match wins) or the public http(s) URL of the show's RSS feed. Spotify and YouTube links do not work.

## `episodes` (type: `integer`):

How many of the latest episodes to transcribe (1-20). With episodeTitleContains: the latest matching episodes.

## `episodeTitleContains` (type: `string`):

Optional. Only episodes whose title contains this text (case-insensitive) are transcribed. Leave empty for the latest episodes.

## `maxMinutesPerEpisode` (type: `integer`):

Transcription stops after this many minutes of each episode (10-180, counted from the start). You pay per 10-minute window, so this caps the cost: 60 minutes is at most $0.15 per episode.

## `captions` (type: `string`):

Add a subtitle file for each episode, with timestamps counted from the start of the episode. The plain text and timed segments are always included.

## Actor input object example

```json
{
  "podcast": "https://lexfridman.com/feed/podcast/",
  "episodes": 1,
  "maxMinutesPerEpisode": 10,
  "captions": "srt"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (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 = {
    "podcast": "https://lexfridman.com/feed/podcast/",
    "maxMinutesPerEpisode": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("tanod/podcast-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 = {
    "podcast": "https://lexfridman.com/feed/podcast/",
    "maxMinutesPerEpisode": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("tanod/podcast-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 '{
  "podcast": "https://lexfridman.com/feed/podcast/",
  "maxMinutesPerEpisode": 10
}' |
apify call tanod/podcast-transcriber --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tanod/podcast-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/x7yl22GJsxmYeswKT/builds/DW8LxDh79WdtEICE8/openapi.json
