# Podcast Transcript & Mention Extractor (`hypebridge/podcast-transcript-mention-extractor`) Actor

Turns podcast URLs and searches into structured episode records. It returns published episode metadata, Podcasting 2.0 people credits, publisher-provided transcripts, and timestamped literal keyword mentions when timed transcript cues are available.

- **URL**: https://apify.com/hypebridge/podcast-transcript-mention-extractor.md
- **Developed by:** [Hypebridge](https://apify.com/hypebridge) (community)
- **Categories:**
- **Stats:** 1 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.008 / episode metadata

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Podcast Feed Transcript & Mention Extractor

Turn direct podcast feeds and publisher episode pages into structured episode records. The Actor extracts RSS, Atom, RDF, iTunes, and Podcasting 2.0 metadata; downloads publisher-provided transcripts; and finds timestamped literal keyword mentions.

No API account or external catalog credentials are required. The Actor does not transcribe audio and does not claim to search everything spoken across all podcasts.

### What data can the Actor extract?

| Field | Description |
| --- | --- |
| `inputUrl` | Original feed or publisher-page URL |
| `resolvedInputType` | `direct_feed` or `publisher_episode` |
| `feed` | Published feed GUID, title, URL, site, author, categories, and language |
| `episode` | Published GUID, title, page, audio, release date, duration, description, season, episode number, and image |
| `peopleStatus` | Whether people came from episode tags, channel fallback, or were missing |
| `people` | Explicit Podcasting 2.0 name, role, group, avatar, and profile/contact URL |
| `transcriptStatus` | Available, missing, fetch failed, too large, unsupported, or parse failed |
| `transcriptSources` | Every transcript descriptor published for the episode |
| `transcript` | Selected source, detected format, language, and optional text or cues |
| `keywordMentions` | Keyword, source timing, cue ID, precision, context snippet, and audio fragment |
| `coverageReason` | Plain-language explanation for unavailable coverage |
| `sourceUrls` | Feed, transcript, episode, and audio source URLs |
| `scrapedAt` | ISO timestamp when the record was emitted |

### Supported inputs

- Direct RSS, Atom, and RDF podcast feeds
- Publisher episode pages whose HTML advertises an RSS or Atom feed and whose canonical episode URL matches exactly one feed item

Catalog and contextless media URLs are intentionally unsupported:

- Podcast Index, Apple Podcasts, and Spotify catalog URLs
- Search terms, people searches, and category discovery
- Direct audio files
- Standalone transcript files without episode context

Use the podcast publisher's RSS/Atom feed URL instead of a catalog page.

### Input parameters

| Parameter | Description | Default |
| --- | --- | --- |
| `startUrls` | Up to 200 direct feed or publisher episode URLs | `[]` |
| `maxItems` | Global dataset item cap | `100` |
| `keywords` | Up to 100 literal transcript terms | `[]` |
| `maxEpisodesPerFeed` | Newest records accepted from one direct feed | `20` |
| `publishedAfter` | Optional ISO 8601 publication-date lower bound | unset |
| `includeFullTranscript` | Include normalized transcript text | `false` |
| `includeSegments` | Include every normalized transcript cue | `false` |
| `maxTranscriptBytes` | Per-transcript decompressed byte cap | `5242880` |
| `maxMentionsPerEpisode` | Maximum keyword matches per episode | `100` |
| `maxTotalTranscriptBytes` | Global decompressed transcript byte budget | `104857600` |
| `maxRequests` | Global HTTP request budget | `2000` |
| `runTimeoutSeconds` | Run deadline in seconds | `900` |
| `maxConcurrency` | Global concurrent request cap | `10` |
| `proxyConfiguration` | Optional publisher-host proxy configuration | disabled |
| `debugMode` | Store bounded sanitized failure artifacts | `false` |

An empty `startUrls` array finishes successfully with an empty dataset. Malformed, unsupported, or unresolved individual URLs are skipped with warnings so other submitted feeds can continue.

### Examples

#### Extract recent feed episodes

```json
{
  "startUrls": [{ "url": "https://feeds.podcastindex.org/pc20.xml" }],
  "maxItems": 5,
  "maxEpisodesPerFeed": 5
}
```

#### Find transcript mentions

```json
{
  "startUrls": [{ "url": "https://feeds.podcastindex.org/pc20.xml" }],
  "keywords": ["Spotify", "value for value"],
  "includeSegments": true,
  "maxItems": 3
}
```

#### Process multiple feeds within strict budgets

```json
{
  "startUrls": [
    { "url": "https://feeds.podcastindex.org/pc20.xml" },
    { "url": "https://example.com/podcast.xml" }
  ],
  "maxItems": 10,
  "maxEpisodesPerFeed": 5,
  "maxRequests": 100,
  "maxTotalTranscriptBytes": 52428800
}
```

### Output example

```json
{
  "inputUrl": "https://example.com/feed.xml",
  "resolvedInputType": "direct_feed",
  "feed": {
    "guid": "example-podcast-guid",
    "title": "Example Podcast",
    "url": "https://example.com/feed.xml",
    "siteUrl": "https://example.com/podcast",
    "author": "Example Network",
    "categories": ["Technology"],
    "language": "en"
  },
  "episode": {
    "guid": "episode-42",
    "title": "A Practical Example",
    "pageUrl": "https://example.com/podcast/episode-42",
    "audioUrl": "https://cdn.example.com/episode-42.mp3",
    "releaseDate": "2026-08-20T12:00:00.000Z",
    "durationSeconds": 2700
  },
  "peopleStatus": "episode",
  "people": [{ "name": "Alex Example", "role": "host", "group": "cast" }],
  "transcriptStatus": "available",
  "keywordMentions": [{
    "keyword": "example",
    "startTimeSeconds": 123.45,
    "timestamp": "00:02:03.450",
    "precision": "cue",
    "snippet": "Here is a practical example for the discussion."
  }],
  "coverageReason": null,
  "sourceUrls": {
    "feed": "https://example.com/feed.xml",
    "transcript": "https://example.com/episode-42.vtt",
    "episode": "https://example.com/podcast/episode-42",
    "audio": "https://cdn.example.com/episode-42.mp3"
  },
  "scrapedAt": "2026-09-01T12:00:00.000Z"
}
```

### Transcript and mention coverage

Transcript coverage is publisher-dependent. The Actor supports VTT, SRT, JSON, HTML, and plain-text transcripts declared in Podcasting 2.0 feed metadata. Untimed transcript text can produce a literal match but cannot produce a truthful timestamp. Full transcript text and cue arrays are disabled by default.

People are returned only from explicit Podcasting 2.0 metadata; the Actor does not guess guests from titles or descriptions.

### Pricing

The Actor uses pay-per-event billing and charges exactly one event per emitted episode. Episodes with a successfully normalized transcript use the `transcript-enriched-episode` tier; all other emitted episodes use the `episode-metadata` tier. Unresolved inputs, retries, and duplicates are not charged. Current event prices are shown in the Apify Console before a run starts.

### Responsible use

Publishers retain rights in their feeds, transcripts, and audio. Enable full transcript redistribution only when you have a lawful basis and appropriate permission. You are responsible for complying with applicable privacy, copyright, and database laws.

### Support

Use the **Issues** tab for bugs or feature requests and the **API** tab for programmatic runs.

# Actor input Schema

## `startUrls` (type: `array`):

Direct RSS, Atom, or RDF podcast feeds and publisher episode pages that advertise their feed.

## `maxItems` (type: `integer`):

Global dataset item cap across every submitted URL.

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

Literal terms to locate in available publisher transcripts.

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

Newest episode records accepted from any one direct feed.

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

Optional ISO 8601 publication-date lower bound.

## `includeFullTranscript` (type: `boolean`):

Include normalized transcript text. Disabled by default to limit redistribution and output size.

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

Include every normalized transcript cue. Disabled by default because output can be large.

## `maxTranscriptBytes` (type: `integer`):

Per-resource decompressed download cap before parsing.

## `maxMentionsPerEpisode` (type: `integer`):

Cap emitted keyword matches after overlapping context windows are merged.

## `maxTotalTranscriptBytes` (type: `integer`):

Global decompressed transcript download budget.

## `maxRequests` (type: `integer`):

Global request budget across feeds, publisher pages, redirects, and transcripts.

## `runTimeoutSeconds` (type: `integer`):

Stop scheduling work after this many seconds and finish validated records.

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

Global concurrent request limit; stricter per-host limits still apply.

## `proxyConfiguration` (type: `object`):

Normally unnecessary. Publisher hosts may have independent restrictions.

## `debugMode` (type: `boolean`):

Store bounded, sanitized failure artifacts without full transcript bodies.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://feeds.podcastindex.org/pc20.xml"
    }
  ],
  "maxItems": 20,
  "keywords": [],
  "maxEpisodesPerFeed": 20,
  "includeFullTranscript": false,
  "includeSegments": false,
  "maxTranscriptBytes": 5242880,
  "maxMentionsPerEpisode": 100,
  "maxTotalTranscriptBytes": 104857600,
  "maxRequests": 2000,
  "runTimeoutSeconds": 900,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "debugMode": false
}
```

# Actor output Schema

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

Complete dataset containing every normalized output field.

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

Table view focused on episode, transcript, people, and mention coverage.

## `files` (type: `string`):

Bounded sanitized failure artifacts created only when debug mode is enabled.

# 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 = {
    "startUrls": [
        {
            "url": "https://feeds.podcastindex.org/pc20.xml"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("hypebridge/podcast-transcript-mention-extractor").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 = {
    "startUrls": [{ "url": "https://feeds.podcastindex.org/pc20.xml" }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("hypebridge/podcast-transcript-mention-extractor").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 '{
  "startUrls": [
    {
      "url": "https://feeds.podcastindex.org/pc20.xml"
    }
  ],
  "maxItems": 20
}' |
apify call hypebridge/podcast-transcript-mention-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hypebridge/podcast-transcript-mention-extractor"
        }
    }
}

```

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/6tKzSq2IuChkRGbuc/builds/m2o1snNHZHbnL7Kgv/openapi.json
