# Podcast Transcripts from RSS (Published, No Speech-to-Text) (`ahmed.fouaad82/podcast-published-transcripts`) Actor

Get podcast transcripts as text from podcast RSS feeds. Returns the exact transcripts podcasts publish (Podcasting 2.0 podcast:transcript: SRT, VTT, JSON, HTML) as clean text plus timestamped speaker segments and episode metadata. No audio download, no speech-to-text.

- **URL**: https://apify.com/ahmed.fouaad82/podcast-published-transcripts.md
- **Developed by:** [Ahmed Fouad](https://apify.com/ahmed.fouaad82) (community)
- **Categories:** AI, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 transcripts

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 Transcripts from RSS (Published, No Speech-to-Text)

Get **podcast transcripts as text** straight from podcast RSS feeds. Give the Actor podcast RSS feed URLs; it finds every episode that publishes a [Podcasting 2.0 `<podcast:transcript>`](https://podcastindex.org/namespace/1.0#transcript) file (SRT, WebVTT, JSON, HTML or plain text), downloads that exact file and returns **clean plain text plus timestamped speaker segments** together with episode metadata.

No audio download and no speech-to-text, so it is fast, cheap and returns the creator's own transcript word for word. It is built for AI agents and RAG pipelines as much as for people: one call, one row per episode, predictable JSON.

### What you get per episode

| Field | Meaning |
|---|---|
| `podcastTitle`, `feedUrl` | Podcast and the feed it came from |
| `episodeTitle`, `guid`, `episodeUrl`, `publishedAt`, `audioUrl`, `durationSeconds`, `episodeNumber`, `season` | Episode metadata |
| `hasTranscript` | `true` when a published transcript was downloaded and parsed |
| `transcriptUrl`, `transcriptType`, `transcriptFormat`, `language` | Which transcript file was used (`vtt`, `srt`, `json`, `text`, `html`) |
| `text` | Full transcript as plain text; one paragraph per speaker turn, `Name: ` labels optional |
| `segments` | `[{start, end, speaker?, text}]` in seconds when the transcript has timing |
| `segmentCount`, `wordCount`, `speakers` | Quick stats |
| `availableTranscripts` | Every transcript alternative the feed lists |
| `transcriptError` | Why a metadata-only row has no transcript |

When a feed offers several formats, the Actor picks the richest: WebVTT, then SRT, then JSON (word-level JSON is merged into readable segments), then plain text, then HTML.

Example row (shortened):

```json
{
  "podcastTitle": "Buzzcast",
  "episodeTitle": "Your Podcast Idea Doesn’t Have To Be Perfect To Get Started",
  "publishedAt": "2026-10-30T12:00:00.000Z",
  "durationSeconds": 751,
  "hasTranscript": true,
  "transcriptFormat": "vtt",
  "language": "en-us",
  "text": "Jordan: Alban, do you remember when we did that Buzzcast episode...\n\nAlban: No. I have no recollection of it...",
  "segments": [{ "start": 0.08, "end": 8.08, "speaker": "Jordan", "text": "Alban, do you remember when we did that Buzzcast episode..." }],
  "wordCount": 2478,
  "speakers": ["Jordan", "Alban", "Kevin"]
}
```

### How to use it

1. Paste one or more **podcast RSS feed URLs** into `feedUrls`. (Tip: a podcast's RSS link is usually on its website or host page. Name search is not offered, because Apple's robots.txt disallows automated use of its search pages and this Actor only fetches robots-allowed paths.)
2. Set `maxEpisodesPerFeed` (newest first; default 5).
3. Run. Each row is one episode with its transcript.

Useful options: `onlyWithTranscripts` (default on; off adds free metadata-only rows), `publishedSince`, `includeSegments`, `includeSpeakerLabels`, `maxResults` (total cap).

### Which podcasts have transcripts?

Only podcasts that **publish** a transcript in their feed. In a 59-feed sample taken on 2026-11-04 (top Apple Podcasts results for 20 popular topics), **10 feeds (17%) carried transcript tags**, and 44 of the 286 newest episodes (15%) had one. Hosts that publish them include **Omny Studio** (iHeart, Bloomberg, Fox Sports and other networks), **Buzzsprout** (when the creator enables transcripts), **Podcast Index** shows and some **Spotify for Creators** (Anchor) feeds. Most Megaphone, Simplecast, Acast, Art19 and Libsyn shows in the sample did not publish one. If a podcast has no published transcript, this Actor does not invent one; use a speech-to-text Actor for those.

### Pricing

Pay per event: **$2.00 per 1,000 transcripts** (`transcript` event, $0.002 each). Metadata-only rows (episodes without a transcript, returned only when `onlyWithTranscripts` is off) are free. Failed or blocked downloads are never charged.

For comparison, speech-to-text costs roughly $0.006-$0.05 per audio **minute**; a one-hour episode here costs a fraction of a cent.

### Good citizenship and limits

- Public feeds only: no logins, no cookies, no paywalled or private feeds.
- Respects `robots.txt` for every feed and transcript host and its crawl-delay; disallowed URLs are skipped and listed in the run `SUMMARY` (for example `changelog.com` disallows all bots, so its feeds are not read).
- Plain HTTP, no browser and no proxy. At least 1 second between requests to the same host. Private and internal network addresses are blocked.
- Files above `maxResponseMb` (default 15 MB) are refused rather than partly read.
- With `onlyWithTranscripts` on, up to about 10x `maxEpisodesPerFeed` (at least 100) newest episodes are scanned per feed to find transcripts.
- Transcripts are the publisher's text; check the podcast's terms before redistributing them.

### Run records

The key-value store holds `SUMMARY` (rows, transcripts, episodes scanned, per-feed stats, stop reason and errors) and `STATE` (resume point; a migrated or restarted run continues without duplicate rows or double charges).

# Actor input Schema

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

Public podcast RSS feed URLs (up to 100), for example https://feeds.buzzsprout.com/231452.rss. Transcripts are found through each episode's <podcast:transcript> tag. Hosts such as Buzzsprout, Omny Studio (iHeart, Bloomberg, Fox Sports), Podcast Index and some Spotify for Creators feeds publish them; many large shows do not.

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

Maximum rows per podcast, newest episodes first. With onlyWithTranscripts on, episodes without a transcript are skipped and the Actor keeps scanning older episodes (up to about 10x this number, at least 100) to fill the quota.

## `maxResults` (type: `integer`):

Hard cap on dataset rows across all podcasts. Use it to cap cost.

## `onlyWithTranscripts` (type: `boolean`):

On (default): return only episodes whose published transcript was downloaded and parsed. Off: also return metadata-only rows (hasTranscript=false, not charged) for episodes without a transcript.

## `publishedSince` (type: `string`):

Optional ISO date such as 2026-01-01. Older and undated episodes are skipped.

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

Return segments \[{start, end, speaker, text}] in seconds when the transcript has timing. Turn off to get plain text only (smaller rows).

## `includeSpeakerLabels` (type: `boolean`):

Prefix each speaker's paragraph in the plain text with "Name: " when the transcript names speakers.

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

How many feeds are processed at once. Requests to the same host always stay at least the per-host delay apart.

## `delayMillis` (type: `integer`):

Minimum gap between requests to one host; raised automatically to honour robots.txt crawl-delay.

## `maxResponseMb` (type: `integer`):

Size limit for each feed or transcript file. Larger files fail instead of being partially read.

## Actor input object example

```json
{
  "feedUrls": [
    "https://feeds.buzzsprout.com/231452.rss"
  ],
  "maxEpisodesPerFeed": 2,
  "maxResults": 100,
  "onlyWithTranscripts": true,
  "publishedSince": "",
  "includeSegments": true,
  "includeSpeakerLabels": true,
  "maxConcurrency": 3,
  "delayMillis": 1000,
  "maxResponseMb": 15
}
```

# Actor output Schema

## `dataset` (type: `string`):

Episode transcript rows

## `records` (type: `string`):

STATE and SUMMARY (feed stats, skipped episodes, errors)

# 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.buzzsprout.com/231452.rss"
    ],
    "maxEpisodesPerFeed": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed.fouaad82/podcast-published-transcripts").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.buzzsprout.com/231452.rss"],
    "maxEpisodesPerFeed": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed.fouaad82/podcast-published-transcripts").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.buzzsprout.com/231452.rss"
  ],
  "maxEpisodesPerFeed": 2
}' |
apify call ahmed.fouaad82/podcast-published-transcripts --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed.fouaad82/podcast-published-transcripts"
        }
    }
}
```

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/kvdgt5JMeITlNyim5/builds/hLXYKvXR0H2IPOk5l/openapi.json
