# Podcast & Audio Transcriber: Speech to Text, RSS, SRT (`nightfallhq/podcast-audio-transcriber`) Actor

Turn podcast episodes and audio files into text, timestamps, SRT and VTT. Uses the show's own transcripts for free where the feed has them, or your own Deepgram, AssemblyAI, ElevenLabs, OpenAI Whisper or Groq key. Keyword alerts and new-episode watchlists. Not affiliated with those companies.

- **URL**: https://apify.com/nightfallhq/podcast-audio-transcriber.md
- **Developed by:** [NightfallHQ](https://apify.com/nightfallhq) (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.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 & Audio Transcriber: Speech to Text, RSS, SRT

**Turn podcast episodes and audio or video files into text, timestamps and subtitles. Paste a podcast RSS feed link and press Start: where the show publishes its own transcript, you get it for free, with no key. Add your own speech-to-text key (Deepgram, AssemblyAI, ElevenLabs, OpenAI Whisper or Groq Whisper) to transcribe any episode. You pay the speech provider directly; this Actor charges $0.004 per audio minute and only for transcripts made by speech to text.**

You get one tidy result row per episode: the full text, timestamped segments, optional speaker labels, keyword mentions with the time they are said, and ready-made SRT, WebVTT, text and JSON files. Schedule it and each run transcribes only the episodes that appeared since the last one.

> Not affiliated with Deepgram, AssemblyAI, ElevenLabs, OpenAI, Groq or Apify. The names are used only to say which services this Actor can call with your own account.

### 3-minute quick start

1. Press **Start** with the pre-filled input. The first feed is a real show that publishes its own transcripts: you get a finished transcript, an SRT file and keyword mentions in seconds. No account, no key.
2. Open the **Transcripts overview** of the dataset. The other two feeds show as free `preview` rows with a cost estimate.
3. To transcribe those too, put in your own feeds, pick a provider, paste your key and press **Start** again.

### Podcast transcript generator

Give it podcast feeds or direct links to mp3, m4a, wav, ogg or mp4 files and get one row per episode: full text, timestamped segments, duration, language and, with Deepgram, AssemblyAI or ElevenLabs, speaker labels. A publisher's own transcript in the feed (the `podcast:transcript` tag) is used first: free, nothing sent to a provider. Otherwise your speech provider transcribes the episode.

### RSS feed to text

It reads standard podcast RSS 2.0 feeds. Choose episodes per feed, a start date, title words, or oldest first to work through a back catalogue a few episodes per run. Switch on **Only new episodes**, name the watchlist and schedule the task: each run transcribes only what is new, so you never pay twice for an episode. It reads feeds and the audio they point to, never websites; YouTube, Spotify and Apple Podcasts pages are refused.

### Audio to text API

Every Apify run is an API call. This request returns the rows of a short run:

`POST https://api.apify.com/v2/acts/nightfallhq~podcast-audio-transcriber/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN`

```json
{ "audioUrls": ["https://example.com/interview.mp3"], "provider": "groq", "apiKey": "YOUR-GROQ-KEY", "language": "en" }
```

For long runs, start the run and read its dataset. Webhooks, n8n, Make and Zapier work the same way: trigger on run finished, get the dataset items, keep `rowType = "transcript"`. AI agents: call it with `{ "feedUrls": ["<RSS link>"] }`, read `text` and `segments`, and on a problem read the last `info` row. With `onlyNewEpisodes` and a fixed `watchlistName`, repeated calls are idempotent. **Never** pass YouTube or Spotify page links.

### SRT subtitle file from audio

Pick **Extra files** (`srt`, `vtt`, `txt`, `json`) and each row links to the file (`srtUrl`, `vttUrl`, `textFileUrl`, `jsonUrl`) in the run's key-value store, ready for a video editor or player. Subtitles come from the same timestamped segments as the result, so timing is as good as the provider's.

### Podcast keyword alerts and mention monitoring

List names, brands or topics under **Keywords to listen for**. Every transcript gets a `mentions` list: each place a keyword is said, with the time (`00:12:34`) and about 20 words around it. Case is ignored, whole words only, phrases in order. Alerts cost nothing extra. The run ends with one free `info` row summing up what was heard and where, so you can send one message per run. Add `"keywords": ["Acme Corp", "interest rates"]` to any input to switch it on.

### Transcribe podcasts with your own Deepgram, AssemblyAI, ElevenLabs, OpenAI or Groq key

| Provider and model | Their price | All-in with this Actor | Free to start |
|---|---|---|---|
| Groq whisper-large-v3-turbo | $0.04 per hour | **$0.28 per hour** | free tier, rate limits |
| AssemblyAI Universal-2 | $0.15 per hour | **$0.39 per hour** | $50 credit |
| ElevenLabs Scribe v2 | $0.22 per hour | **$0.46 per hour** | free plan, some hours |
| Deepgram Nova-3 | $0.26 per hour | **$0.50 per hour** | about $200 credit |
| OpenAI whisper-1 | $0.36 per hour | **$0.60 per hour** | none |

AssemblyAI's more accurate Universal-3.5 Pro costs $0.21 per hour (set **Model**). These are list prices found on 2026-10-13, not your invoice: check your provider. Keys: console.deepgram.com, assemblyai.com/dashboard, elevenlabs.io/app/settings/api-keys (needs the Speech to Text permission), console.groq.com/keys, platform.openai.com/api-keys. For OpenAI and Groq the Actor downloads the file and cuts long episodes into parts of at most 20 minutes, so a two-hour episode works.

### How it compares

All-in cost per hour of audio, as listed on 2026-10-13:

| Option | About per hour |
|---|---|
| This Actor, the show's own transcript | $0 |
| This Actor with your own provider key | $0.28 to $0.60 |
| Cheapest all-in Store Actors | $0.18 to $0.36 |
| Other all-in Actors (some add summaries or chapters) | $0.60 to $3.00 |

The cheapest all-in Actors can cost less. This one adds free publisher transcripts, your own provider account, five engines, speaker labels, SRT and VTT, keyword alerts and a new-episodes memory. If one bill and no setup matter more than price, pick an all-in Actor.

### Use cases

- **Show notes and newsletters:** the full text is raw material for summaries, quotes and chapters.
- **SEO blog posts:** put the transcript on the episode page for search engines.
- **Brand mention alerts:** know when your name or a competitor comes up, and when.
- **AI and RAG datasets:** `text` and timed `segments` split into chunks that point back to the audio.
- **Research quotes:** turn a back catalogue of interviews into searchable text.

### What you get

A real run on the public feed of the Podcasting 2.0 show, October 2026, publisher transcript (text shortened here):

```json
{
  "rowType": "transcript",
  "transcriptSource": "publisher",
  "feedTitle": "Podcasting 2.0",
  "episodeTitle": "Episode 274: \"Vibe Cloning\"",
  "durationMinutes": 101.07,
  "chargedMinutes": 0,
  "wordsCount": 14796,
  "text": "Podcasting 2.0 for October 9th, 2026, episode 274, Vibe Cloning. ...",
  "segments": [
    { "start": 1, "end": 6.759, "text": "Podcasting 2.0 for October 9th, 2026, episode 274, Vibe Cloning." }
  ],
  "mentionCount": 14,
  "mentions": [
    { "keyword": "podcast index", "start": 538.58, "timestamp": "00:08:58", "snippet": "...are reposting. There's a couple thousand people using the podcast index robot.com. ..." }
  ]
}
```

That run had 1,483 segments and cost nothing. The transcript belongs to its publisher and is shown only to illustrate the format. Other `rowType` values: `preview`, `skipped`, `error`, `warning` and one `info` summary.

### Pricing

**$0.004 per audio minute** ($0.24 per hour), only for transcripts made by speech to text. Each file counts its started minutes, rounded up, and is charged after its transcript is saved. Free: the show's own transcripts, previews, failed or skipped files, keyword alerts and `info` rows. Apify's maximum cost per run is never exceeded. Your provider bills you separately. A 45-minute episode costs $0.18 here; a weekly one-hour show $0.24 a week.

### FAQ

**Do you store my API key?** No. Apify stores the key field encrypted in your own account; during the run it is held in memory and sent only to your provider, in a request header. It never reaches logs, rows, files or the watchlist memory. A key made just for Apify, with a spending limit, is a good habit. What your provider keeps is between you and them: check its data-retention page before sending sensitive audio.

**Am I allowed to transcribe this audio?** You must have the right to transcribe the audio: your own recordings, audio you have permission to use, or public domain or licensed material. A publisher's transcript is the publisher's work. You are responsible for your use and your provider's terms.

**The run succeeded but I got no transcripts.** Read the last `info` row: its `code` and `fix` say why. A mistake on your side never turns the run red, and a failed file is never charged.

**How long can an episode be?** Up to 720 minutes and 2 GB. Set the Actor's run timeout to at least **Maximum run time** plus 20 minutes.

**Does it summarise, translate or name speakers?** No. It transcribes; speaker labels are "speaker 0, speaker 1".

**Something not working?** Open an issue on the Actor page with the feed link (never your key).

# Actor input Schema

## `feedUrls` (type: `array`):

One RSS feed link per line. The newest episodes of each feed are taken. Use the feed link from the show's own hosting page (Libsyn, Simplecast, Megaphone, Buzzsprout and so on), not a page of Apple Podcasts, Spotify or YouTube: those are refused. You must have the right to transcribe the audio.

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

One link per line, each pointing straight at an mp3, m4a, wav, ogg or mp4 file. Links to web pages and to private network addresses are refused.

## `provider` (type: `string`):

The service that transcribes the audio. You need your own account and key with it, and it bills you directly. Not needed for free publisher transcripts. Speaker labels work with Deepgram, AssemblyAI and ElevenLabs.

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

Paste your key for the provider chosen above. Leave it empty for a free run: publisher transcripts where the feed has them, and a free cost preview for the other episodes. The key is stored encrypted by Apify, sent only to your provider's own address, and never written to logs, results or files.

Where to get a key (free credit as listed on 2026-10-13, check the provider):

- Deepgram, https://console.deepgram.com (about $200 free credit for new accounts)
- AssemblyAI, https://www.assemblyai.com/dashboard ($50 free credit)
- ElevenLabs, https://elevenlabs.io/app/settings/api-keys (a free plan with some hours of Scribe; the key needs the Speech to Text permission)
- Groq, https://console.groq.com/keys (a free tier with rate limits)
- OpenAI, https://platform.openai.com/api-keys (pay as you go)

## `episodesPerFeed` (type: `integer`):

How many of the newest episodes to take from each feed. With 'Only new episodes' on, this is the most taken in one run.

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

Feeds only. Earlier episodes, and episodes with no date, are left out. Format: 2026-10-01.

## `titleContains` (type: `array`):

Feeds only. One word or phrase per line; an episode is kept when its title contains any of them (case does not matter). Leave empty to keep every episode.

## `oldestFirst` (type: `boolean`):

Off (default): the newest episodes are taken. On: the oldest ones, to work through a whole back catalogue a few episodes per run (with 'Only new episodes' on, each run carries on where the last stopped).

## `onlyNewEpisodes` (type: `boolean`):

For scheduled runs. The first run transcribes the newest episodes and remembers the feed; later runs transcribe only what appeared since, so you never pay twice for the same episode. Failed episodes are tried again next time.

## `watchlistName` (type: `string`):

Names the memory of 'already transcribed' episodes (short ids only, no text, kept in your own account). Use one name per scheduled task; a new name starts over.

## `usePublisherTranscripts` (type: `boolean`):

On (default): when a feed entry carries the show's own transcript (the podcast:transcript tag) it is used. It is free: no key, nothing is sent to a speech provider, and this Actor does not charge for it. Off: always use speech to text (for speaker labels, or the provider's accuracy).

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

Leave empty for the default: nova-3 (Deepgram), universal-2 (AssemblyAI, the cheapest; universal-3-5-pro is more accurate and costs more), scribe_v2 (ElevenLabs), whisper-large-v3-turbo (Groq; whisper-large-v3 is also offered). OpenAI always uses whisper-1 and ignores this field.

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

'auto' detects the language. Or give a language code such as en, es, de, fr, pt-BR. OpenAI and Groq need a two-letter code.

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

Say who speaks when (speaker 0 and 1, or A and B). Works with Deepgram, AssemblyAI and ElevenLabs; ignored for OpenAI and Groq. Some providers charge a little extra for it.

## `timestamps` (type: `boolean`):

Add the list of segments (start, end, text, speaker) to each result row. SRT and VTT files are made from the same segments whether or not this is on.

## `outputFormats` (type: `array`):

The plain text is always in the 'text' column. Pick files to save as well: they are stored in this run's key-value store and linked from the row (textFileUrl, srtUrl, vttUrl, jsonUrl).

## `keywords` (type: `array`):

One word or phrase per line. Every transcript gets a 'mentions' list: each place a keyword is said, with the time and about 20 words around it. Case does not matter; whole words only ('rate' does not match 'migrate'); a phrase matches when its words follow each other. No extra charge.

## `onlyEpisodesWithMentions` (type: `boolean`):

Off (default): every transcript is written. On: only episodes where a keyword is said get a row. The others are still transcribed and billed (the audio was processed) but not written; the run summary says how many.

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

Stops starting files once this many audio minutes are done in this run. Leave empty for no limit. The free preview uses it too, so the cost estimate matches.

## `maxFiles` (type: `integer`):

Stops after this many audio files; the rest wait for the next run. The small pre-filled number keeps a first test cheap: raise it for real use.

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

Larger files are skipped (free) before anything is sent to the provider. OpenAI uploads are limited to 25 MB and Groq to 100 MB whatever you set here.

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

Episodes the feed says are longer are skipped (free). AssemblyAI stops the transcript at this length; for other providers a longer file is still delivered but billed for this many minutes at most.

## `maxRunMinutes` (type: `integer`):

No new file is started after this many minutes; a file already running gets up to 15 more minutes, then it is cut off (free). Set the Actor's run timeout in the Apify Console (Run options) to at least this plus 20 minutes.

## `groqDeveloperTier` (type: `boolean`):

Groq's free tier accepts uploads of up to 25 MB; the paid Developer tier up to 100 MB. Switch this on only if your Groq account is on the paid tier.

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

How many files are sent to the provider in parallel. Higher is faster but may hit your provider's rate limit.

## Actor input object example

```json
{
  "feedUrls": [
    "https://feeds.example.com/my-podcast.xml"
  ],
  "audioUrls": [
    "https://example.com/episodes/ep-12.mp3"
  ],
  "provider": "deepgram",
  "episodesPerFeed": 1,
  "publishedAfter": "2026-10-01",
  "titleContains": [
    "interview",
    "Q&A"
  ],
  "oldestFirst": false,
  "onlyNewEpisodes": false,
  "watchlistName": "my-podcast",
  "usePublisherTranscripts": true,
  "model": "nova-3",
  "language": "en",
  "speakerLabels": false,
  "timestamps": true,
  "outputFormats": [
    "srt"
  ],
  "keywords": [
    "interest rates",
    "Acme Corp"
  ],
  "onlyEpisodesWithMentions": false,
  "maxTotalMinutes": 600,
  "maxFiles": 3,
  "maxFileSizeMb": 200,
  "maxMinutesPerFile": 240,
  "maxRunMinutes": 120,
  "groqDeveloperTier": false,
  "maxConcurrency": 2
}
```

# Actor output Schema

## `transcripts` (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 = {
    "feedUrls": [
        "https://feeds.podcastindex.org/pc20.xml",
        "https://www.nasa.gov/feeds/podcasts/houston-we-have-a-podcast/",
        "https://librivox.org/rss/52"
    ],
    "episodesPerFeed": 1,
    "watchlistName": "default",
    "language": "auto",
    "outputFormats": [
        "srt"
    ],
    "keywords": [
        "podcast index",
        "value for value"
    ],
    "maxFiles": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("nightfallhq/podcast-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 = {
    "feedUrls": [
        "https://feeds.podcastindex.org/pc20.xml",
        "https://www.nasa.gov/feeds/podcasts/houston-we-have-a-podcast/",
        "https://librivox.org/rss/52",
    ],
    "episodesPerFeed": 1,
    "watchlistName": "default",
    "language": "auto",
    "outputFormats": ["srt"],
    "keywords": [
        "podcast index",
        "value for value",
    ],
    "maxFiles": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("nightfallhq/podcast-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 '{
  "feedUrls": [
    "https://feeds.podcastindex.org/pc20.xml",
    "https://www.nasa.gov/feeds/podcasts/houston-we-have-a-podcast/",
    "https://librivox.org/rss/52"
  ],
  "episodesPerFeed": 1,
  "watchlistName": "default",
  "language": "auto",
  "outputFormats": [
    "srt"
  ],
  "keywords": [
    "podcast index",
    "value for value"
  ],
  "maxFiles": 3
}' |
apify call nightfallhq/podcast-audio-transcriber --silent --output-dataset

```

## MCP server setup

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