# Buzzsprout Podcast Show & Episode Scraper (`adam-frank/buzzsprout-podcast-pages`) Actor

Extracts show and episode data from public Buzzsprout podcast pages, priced pay-per-result.

- **URL**: https://apify.com/adam-frank/buzzsprout-podcast-pages.md
- **Developed by:** [Adam Schepis](https://apify.com/adam-frank) (community)
- **Categories:** Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 results

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?

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

## Buzzsprout Podcast Show & Episode Scraper

Extracts show and episode data from public Buzzsprout podcast pages, priced pay-per-result.

### What you get

- Show metadata — title, URL, host/author, description, category, artwork — plus a list of recent episodes, for any public Buzzsprout show page.
- Structured, ready-to-use data — no scraper to build or maintain yourself.
- Pay only for results: $0.004 per show record, nothing for failed or empty runs.
- Runs on Apify's infrastructure with automatic proxy rotation and retries.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `startUrls` | array of URLs | yes | Public Buzzsprout show pages, e.g. `https://<show>.buzzsprout.com` or `https://www.buzzsprout.com/<id>`. |
| `maxResults` | integer | no (default 20) | Stops the run (and pay-per-event charging) once this many **show** records have been produced. |
| `maxEpisodesPerShow` | integer | no (default 20) | Caps how many of each show's most recent episodes are included in its episode list. |

Example input:

```json
{
    "startUrls": [
        { "url": "https://www.buzzsprout.com/100" },
        { "url": "https://buzzcast.buzzsprout.com" }
    ],
    "maxResults": 20,
    "maxEpisodesPerShow": 20
}
```

### Output example

One dataset item per show, with its episodes nested inside:

```json
{
    "showTitle": "Johnson Street Church of Christ Sermon Podcast",
    "showUrl": "https://www.buzzsprout.com/100",
    "host": "Johnson Street Church",
    "showDescription": "This podcast includes the Sunday morning sermons from the Johnson Street Church of Christ in San Angelo, Texas...",
    "category": "Religion & Spirituality",
    "artworkUrl": "https://storage.buzzsprout.com/o01nluf9t5d6694qqhuuqhutm056?.jpg",
    "episodes": [
        {
            "title": "Follow // Lesson 1",
            "publishDate": "2026-09-06T16:00:00.000Z",
            "duration": "28:09",
            "descriptionExcerpt": "Sermon Series // Follow Lesson 1 // The Law of God - Psalm 119 Sunday, September 6, 2026",
            "episodeUrl": "https://www.buzzsprout.com/100/episodes/19761949",
            "audioUrl": "https://www.buzzsprout.com/100/episodes/19761949-follow-lesson-1.mp3"
        }
    ],
    "scrapedAt": "2026-09-08T23:23:03.262Z"
}
```

This is a real, verified sample (truncated to one episode for brevity) — see "Seed results" below for the full local run.

Every dataset item has the same shape. Download results as JSON, CSV, Excel, or via the Apify API.

### Pricing

This Actor uses [pay-per-event pricing](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event). You are charged only for the `result` event, once per **show** record produced (episodes are nested inside that one record, not charged separately); the exact per-event price is set in Apify Console at publish time and shown on the Actor's Store page before you run it.

| Event | When it's charged |
|---|---|
| `result` | Once per show record, up to `maxResults` |

### Why this actor

Buzzsprout hosts show pages for a huge number of independent podcasts, but doesn't offer a public search API for buyers who want structured show/episode data (for directory building, competitive research, guest-booking research, etc.) without visiting each show page by hand. This actor turns any public Buzzsprout show URL into structured JSON in one call.

### How it works

- Fetches the given show page and reads the RSS feed link it points to (the same feed a podcast app would use) to get the show's category, host/author, and episode list — all fields the site publicly exposes to an anonymous visitor via that link.
- If robots.txt disallows a show's RSS path, falls back to parsing the show page's own visible "Latest Episodes" list instead (category and audio URL are not available in that fallback, since they aren't shown on the page itself).
- No login, no pagination beyond `maxEpisodesPerShow`, `maxConcurrency` capped at 3.

### Robots.txt

`https://www.buzzsprout.com/robots.txt` currently disallows exactly one path: `/101612.rss`. This actor fetches and parses that file at the start of every run and will not fetch a show's RSS feed if its path is disallowed — it uses the HTML-page fallback described above instead. No other paths are blocked at the time of writing.

### Notes for buyers

- Category, artwork, and audio URLs come from what the show's RSS feed publishes; a show that hides its RSS link from its page (rare) falls back to page-only data with `category` and episode `audioUrl` as `null`.
- `descriptionExcerpt` is truncated to 300 characters.
- Legacy Buzzsprout shows (some over a decade old) can have episodes with non-standard identifiers; this actor derives episode URLs from the audio file path rather than relying on that identifier, so results are stable even for very old catalogs.

### Reference docs used to build this actor

- Apify SDK for JS: https://docs.apify.com/sdk/js/
- Pay-per-event monetization overview: https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event
- Pay-per-event SDK guide (`Actor.charge`, `ChargingManager`, local test mode): https://docs.apify.com/sdk/js/docs/concepts/pay-per-event
- `Actor.charge` API reference: https://docs.apify.com/sdk/js/reference/class/Actor
- `.actor/actor.json` reference: https://docs.apify.com/platform/actors/development/actor-definition/actor-json
- Built with [Crawlee](https://crawlee.dev) and the [Apify SDK for JavaScript](https://docs.apify.com/sdk/js/).

# Actor input Schema

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

Public Buzzsprout show pages, e.g. https://<show>.buzzsprout.com or https://www.buzzsprout.com/<id>.

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

Stops the run (and pay-per-event charging) once this many show records have been produced.

## `maxEpisodesPerShow` (type: `integer`):

Caps how many of each show's most recent episodes are included in its episode list.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.buzzsprout.com/100"
    },
    {
      "url": "https://buzzcast.buzzsprout.com"
    },
    {
      "url": "https://www.buzzsprout.com/2"
    }
  ],
  "maxResults": 20,
  "maxEpisodesPerShow": 20
}
```

# Actor output Schema

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

Dataset containing all scraped records

# 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://www.buzzsprout.com/100"
        },
        {
            "url": "https://buzzcast.buzzsprout.com"
        },
        {
            "url": "https://www.buzzsprout.com/2"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("adam-frank/buzzsprout-podcast-pages").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://www.buzzsprout.com/100" },
        { "url": "https://buzzcast.buzzsprout.com" },
        { "url": "https://www.buzzsprout.com/2" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("adam-frank/buzzsprout-podcast-pages").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://www.buzzsprout.com/100"
    },
    {
      "url": "https://buzzcast.buzzsprout.com"
    },
    {
      "url": "https://www.buzzsprout.com/2"
    }
  ]
}' |
apify call adam-frank/buzzsprout-podcast-pages --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,adam-frank/buzzsprout-podcast-pages"
        }
    }
}
```

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/yMMbW5Lv5iicp2shN/builds/vLs5AFjDLy0C8Wm55/openapi.json
