# Podcast Transcriber for RSS & Apple Podcasts (`northloop-labs/podcast-transcriber`) Actor

Transcribe podcast episodes from an RSS feed, Apple Podcasts link or audio URL: full text, timestamped segments, SRT subtitles, language and episode metadata. Whisper runs inside the Actor, no API key. Failed or silent episodes are free.

- **URL**: https://apify.com/northloop-labs/podcast-transcriber.md
- **Developed by:** [Northloop Labs](https://apify.com/northloop-labs) (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 $6.00 / 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.

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 for RSS & Apple Podcasts

Turn podcast episodes into text. Paste a show's **RSS feed**, an **Apple Podcasts** show or episode link, or a **direct audio URL**, and get back for every episode:

- the **full transcript** text
- **timestamped segments** (start and end in seconds)
- ready-to-use **SRT subtitles** (and WebVTT if you want them)
- the **detected language**
- **episode metadata**: show, title, publish date, duration, episode and season number, description, audio URL, and chapters when the feed has them

Speech recognition (OpenAI's open-source Whisper model, via faster-whisper) runs **inside the Actor**. No API key, no account anywhere else, and your audio is never sent to a third-party service.

### What you can use it for

- **Podcast search and SEO:** publish transcripts next to your episodes so search engines and listeners can find what was said.
- **Show notes and clips:** jump to the exact second something was said using the segments or SRT.
- **Media monitoring:** schedule a daily run on a list of shows and get only the new episodes as text.
- **AI pipelines:** feed clean transcripts with metadata into your LLM, RAG index or analytics.
- **Accessibility:** subtitles and text versions for listeners who are deaf or hard of hearing.

### How to transcribe a podcast from RSS or Apple Podcasts

1. Paste one or more feeds, Apple Podcasts links or audio URLs into **Podcast feeds, Apple Podcasts links or audio URLs**.
2. Choose how many of the **latest episodes per show** you want, and optionally a date range or a title filter.
3. Set your **cost cap** (max audio minutes per run), then click **Start**.

Spotify links are not supported because Spotify doesn't publish the audio file. Most shows on Spotify are also on Apple Podcasts or have a public RSS feed, so use that link instead.

### Input

| Field | Description |
|---|---|
| `urls` | RSS feeds, Apple Podcasts show links (`…/id123456789`), Apple Podcasts episode links (`…/id123456789?i=1000…`) or direct audio URLs (`.mp3`, `.m4a`, `.wav`, `.ogg`…) |
| `maxEpisodes` | Newest matching episodes to take per show (default 3) |
| `publishedAfter` / `publishedBefore` | Date range (YYYY-MM-DD). Episodes without a date in the feed are kept |
| `titleContains` | Only episodes whose title contains this text |
| `maxTotalMinutes` | **Hard cap** on audio minutes transcribed and charged in the run (default 180) |
| `maxMinutesPerEpisode` | Transcribe only the first N minutes of each episode (0 = whole episode) |
| `transcribePartialEpisodes` | If the next episode doesn't fit in the minutes left: skip it for free (default) or cut it short |
| `language` | `auto` (default) or a language code such as `en`, `es`, `de` |
| `includeSegments`, `includeSrt`, `includeVtt` | Which timestamped outputs to include |
| `skipAlreadyTranscribed` | For schedules: skip episodes you already transcribed in an earlier run, free of charge |

#### Input example

```json
{
  "urls": [
    "https://feeds.npr.org/510289/podcast.xml",
    "https://podcasts.apple.com/us/podcast/the-daily/id1200361736",
    "https://example.com/audio/episode-42.mp3"
  ],
  "maxEpisodes": 5,
  "publishedAfter": "2026-10-01",
  "maxTotalMinutes": 300,
  "language": "en"
}
```

Run it with an empty input to try it on a 1:40 public-domain recording of the Gettysburg Address from LibriVox.

#### Output example

```json
{
  "status": "ok",
  "showTitle": "Planet Money",
  "showAuthor": "NPR",
  "episodeTitle": "Anatomy of a movie market",
  "publishedAt": "2026-10-16T21:30:00Z",
  "episodeNumber": null,
  "durationSeconds": 1623.4,
  "audioUrl": "https://…/episode.mp3",
  "feedUrl": "https://feeds.npr.org/510289/podcast.xml",
  "language": "en",
  "languageProbability": 0.998,
  "transcribedSeconds": 1623.4,
  "truncated": false,
  "billedMinutes": 28,
  "wordCount": 4410,
  "text": "This is Planet Money from NPR. …",
  "segments": [
    { "start": 0.0, "end": 4.2, "text": "This is Planet Money from NPR." }
  ],
  "srt": "1\n00:00:00,000 --> 00:00:04,200\nThis is Planet Money from NPR.\n\n…",
  "chapters": null,
  "publisherTranscripts": null,
  "model": "whisper-base"
}
```

Episodes that couldn't be transcribed still get a row, with a `status` (`error`, `no-speech`, `skipped-budget`, `skipped-timeout`, `already-transcribed`, `no-episodes`) and an `error` message explaining why, and `billedMinutes: 0`. A `RUN_SUMMARY` record in the key-value store lists every input with its status.

### How much does it cost?

Pay per event, no platform usage costs on top:

- **$0.006 per audio minute** transcribed ($0.36 per hour of audio), counted per started minute of each episode
- **$0.005** per run start (one event per GB of memory; the default 2 GB = $0.01)

A 30-minute episode costs $0.18. A weekly 30-minute show, four episodes a month, is about $0.75 a month including run starts.

**You only pay for transcripts you get.** Episodes that fail to download or decode, contain no speech, are skipped by your filters or caps, or were already transcribed are **never charged**. Charging happens only after an episode's transcript is ready.

**Strict cost caps:** the run never charges more audio minutes than `maxTotalMinutes`, and it stops cleanly at the "Maximum cost per run" you set in Apify. An episode that doesn't fit in what's left is skipped (free) instead of being charged past your limit.

### Transcription speed and accuracy (Whisper)

- The Actor uses Whisper **base** (int8 on CPU). At the default 2 GB of memory it transcribes about 4–6 minutes of audio per minute of run time, so a 60-minute episode takes about 10–15 minutes. The default run timeout (1 hour) fits about 4 hours of audio; raise it for bigger runs. Episodes that wouldn't finish before the timeout are skipped for free.
- More memory gives more CPU and is faster, but the start fee is per GB and the per-minute price stays the same.
- Accuracy is very good for clear speech in English and other major languages. It's weaker on heavy accents, crosstalk, noisy recordings, rare names and less common languages. It doesn't label speakers.
- Silence and music-only parts are skipped by voice detection, but you're billed for the audio length processed, as with every per-minute transcriber.

### Use with AI agents, MCP, Make, Zapier, n8n and the API

#### AI agents and the Apify MCP server

Your AI agent can run this Actor as a tool through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp). In Claude, Cursor, VS Code or any other MCP client, add this server URL to load only this Actor:

```text
https://mcp.apify.com?tools=northloop-labs/podcast-transcriber
```

You sign in to Apify on first connection. Agents that use the default server can also find the Actor with `search-actors` and run it with `call-actor`. Pass `maxTotalChargeUsd` in `callOptions` to cap what one run may cost. The Actor uses pay-per-event pricing, so it also works with Apify's agentic payments.

Example prompt: *"Transcribe the latest episode of Planet Money and summarize the main points."* MCP calls wait at most 45 seconds, so the agent gets the run ID first and reads the transcript with `get-dataset-items` once the run finishes.

#### Make, Zapier and n8n

Apify has official integrations for [Make](https://docs.apify.com/platform/integrations/make), [Zapier](https://docs.apify.com/platform/integrations/zapier) and [n8n](https://docs.apify.com/platform/integrations/n8n). Use "Run Actor", pick `northloop-labs/podcast-transcriber`, paste your input as JSON, and send the dataset items on to Google Sheets, Slack, a CRM or email. Inside Apify you can also connect Google Sheets or Slack, or add a [webhook](https://docs.apify.com/platform/integrations/webhooks) that fires when a run finishes.

#### API

Start a run, then read its dataset when it finishes. Transcription can take longer than the 5 minutes a synchronous API call waits, so start runs asynchronously and use a webhook, or the client libraries, which wait for you:

```bash
curl -X POST "https://api.apify.com/v2/acts/northloop-labs~podcast-transcriber/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://feeds.npr.org/510289/podcast.xml"], "maxEpisodes": 1, "maxTotalMinutes": 60}'
```

Or with the Python client (`pip install apify-client`). The JavaScript client works the same way:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("northloop-labs/podcast-transcriber").call(run_input={"urls": ["https://feeds.npr.org/510289/podcast.xml"], "maxEpisodes": 1, "maxTotalMinutes": 60})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### Data & privacy

- The Actor downloads only the audio files and feeds you point it to, from their public URLs. It does not log in anywhere and never uses Spotify or any private feed.
- Transcription runs **inside the Actor**. The audio is not sent to any third-party service, and the downloaded file is deleted as soon as it's decoded.
- Results are written **only to your run's default dataset** and key-value store in your own Apify account. If you turn on `skipAlreadyTranscribed`, a named key-value store `podcast-transcriber-history` in your account keeps an anonymous ID, date and title for each transcribed episode; delete it any time. Nothing is sent anywhere else, and we keep no copy.
- Transcripts contain whatever was said in the episode, which can include names and personal details of hosts, guests or callers. Treat them as you would the audio itself and follow the privacy rules that apply to you (for example, GDPR) when you store or publish them.

### Your rights to the content

Podcast audio is usually protected by copyright, and a transcript is a copy derived from it. **You must have the rights or permission to transcribe the content you submit** (for example, it's your own show, the license allows it, or your use is covered by an exception such as fair use, research or accessibility in your country). Check each show's terms, especially before you republish a transcript. This is not legal advice.

### FAQ

#### How much does it cost to transcribe a podcast?

$0.006 per audio minute ($0.36 per hour of audio), plus a run start of $0.005 per GB of memory ($0.01 at the default 2 GB). A 30-minute episode costs $0.18. Failed, silent, skipped and already-transcribed episodes are free. Apify's free plan includes monthly usage credit you can spend on this Actor.

#### Are there limits on episode length or the number of episodes?

Up to 500 episodes per show per run (`maxEpisodes`), and audio files up to 1.5 GB. The default 1-hour run timeout fits about 4 hours of audio; raise the timeout for more. `maxTotalMinutes` (180 by default) caps the minutes transcribed in one run.

#### Which languages does it support?

Whisper detects the language automatically. You can also pick one of 26 languages, including English, Spanish, French, German, Portuguese, Italian, Dutch, Polish, Romanian, Russian, Ukrainian, Arabic, Hindi, Japanese, Korean and Chinese. It transcribes in the spoken language and doesn't translate.

#### Can I get transcripts of new episodes automatically?

Yes. Add a schedule in Apify (for example daily) and turn on `skipAlreadyTranscribed`. Each run then transcribes only episodes it hasn't done before, and the ones it skips are free.

#### Does it work with Spotify or YouTube links?

Not with Spotify, which doesn't publish the audio file. Use the show's Apple Podcasts link or RSS feed instead. YouTube isn't supported at the moment.

#### Does it label speakers?

No, the transcript has timestamps but no speaker names.

#### Which formats do I get?

Each episode row has the plain text, timestamped `segments`, `srt` subtitles and, if you turn it on, `vtt`. Copy the `srt` field into a `.srt` file for video editors and players. Results land in an Apify dataset. Download them as JSON, JSONL, CSV, Excel, XML, HTML or RSS from the run page, or read them through the API, Make, Zapier or n8n.

#### Am I allowed to transcribe any podcast?

Only content you have the rights or permission to transcribe. See "Your rights to the content" above.

### How this Actor was made

This Actor was made with AI. An AI agent wrote and tested the code, this README and the store listing, and a human owns and maintains the Actor.

### More Actors from Northloop Labs

- [Luma, Eventbrite & Meetup Events Scraper](https://apify.com/northloop-labs/tech-events-finder): tech, AI and startup events from Luma, Eventbrite and Meetup.
- [Greenhouse, Lever, Ashby & Workable Jobs Scraper](https://apify.com/northloop-labs/company-jobs-finder): open jobs from company career pages.
- [Google Ads Transparency Center Scraper](https://apify.com/northloop-labs/google-ads-transparency-library): a company's ads from the Google Ads Transparency Center.
- [EU TED & UK Find a Tender Scraper](https://apify.com/northloop-labs/public-tenders-monitor): UK and EU public tenders with daily alerts.

### Feedback

Need speaker labels, a more accurate model, translation, YouTube or another source? Open an issue in the **Issues** tab. We read every one.

# Actor input Schema

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

One per line. A podcast RSS feed (https://feeds.example.com/show.xml), an Apple Podcasts show link (…/podcast/name/id123456789), an Apple Podcasts episode link (…/id123456789?i=1000…) or a direct audio file URL (.mp3, .m4a, .wav, .ogg…).

## `maxEpisodes` (type: `integer`):

How many of the newest matching episodes to transcribe from each feed or Apple show link. Episode links and audio URLs always count as one.

## `publishedAfter` (type: `string`):

Only episodes published on or after this date (YYYY-MM-DD). Episodes without a date in the feed are kept.

## `publishedBefore` (type: `string`):

Only episodes published on or before this date (YYYY-MM-DD).

## `titleContains` (type: `string`):

Only episodes whose title contains this text (not case-sensitive).

## `maxTotalMinutes` (type: `integer`):

Hard cap on audio minutes transcribed and charged in this run. Episodes that don't fit in what's left are skipped for free (or cut short, see below). 0 = no cap besides your maximum cost per run.

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

Transcribe only the first N minutes of each episode (handy for intros, previews or cheap tests). 0 = whole episode.

## `transcribePartialEpisodes` (type: `boolean`):

Off (default): an episode longer than the minutes left in the run is skipped and free. On: transcribe as much of it as fits, marked truncated.

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

Spoken language. Auto-detect works well; set it when you know the language to avoid wrong detection on short clips.

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

Add the list of segments with start and end times in seconds.

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

Add a ready-to-use .srt subtitle text.

## `includeVtt` (type: `boolean`):

Add a WebVTT (.vtt) subtitle text too.

## `skipAlreadyTranscribed` (type: `boolean`):

For scheduled runs: remember transcribed episodes in a named key-value store in your account (podcast-transcriber-history) and skip them next time, free of charge.

## Actor input object example

```json
{
  "urls": [
    "https://librivox.org/rss/389"
  ],
  "maxEpisodes": 3,
  "maxTotalMinutes": 180,
  "maxMinutesPerEpisode": 0,
  "transcribePartialEpisodes": false,
  "language": "auto",
  "includeSegments": true,
  "includeSrt": true,
  "includeVtt": false,
  "skipAlreadyTranscribed": false
}
```

# Actor output Schema

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

Show, episode, date, duration, language, word count, billed minutes, status and the full transcript text.

## `details` (type: `string`):

Every field: timestamped segments, SRT/VTT subtitles, chapters, episode metadata and audio URL.

## `runSummary` (type: `string`):

Per-input status, episodes transcribed and audio minutes billed in this run.

# 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://librivox.org/rss/389"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("northloop-labs/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 = { "urls": ["https://librivox.org/rss/389"] }

# Run the Actor and wait for it to finish
run = client.actor("northloop-labs/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 '{
  "urls": [
    "https://librivox.org/rss/389"
  ]
}' |
apify call northloop-labs/podcast-transcriber --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northloop-labs/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/QGQeZrTbx77uAaNxp/builds/1HQcCLTKfOH0KHJVJ/openapi.json
