# Pocket Casts Podcast Scraper - Ratings & Full Episode Archive (`abotapi/pocketcasts-podcast-scraper`) Actor

Scrape Pocket Casts podcast data, including listener ratings, full episode archives, publishing cadence, seasons, transcript availability, direct audio URLs, regional category charts, and global episode search.

- **URL**: https://apify.com/abotapi/pocketcasts-podcast-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 podcast or episode records

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

## Pocket Casts Podcast Scraper

Scrape rich podcast data from **Pocket Casts** - one of the world's most popular podcast apps, with millions of listeners rating shows natively inside the app. This actor exposes data you cannot get from an RSS feed or the website: **native listener ratings**, **full episode archives in a single request**, publishing cadence analytics, season metadata, and transcript availability.

### Features

- 🔍 **Podcast search** - find podcasts by keyword
- 📊 **Category charts** - ranked top-podcast charts per category and region (US, UK, DE, AU, and any other region you pick)
- 🎙️ **Global episode search** - find individual episodes across ALL podcasts by keyword, with direct audio URLs
- 🔗 **URL mode** - paste a podcast link or UUID for full enrichment
- ⭐ **Native ratings** - average rating and total vote count from in-app listeners (exclusive: not in RSS feeds!)
- 📚 **Full episode archives** - every episode of a podcast in one dataset record: title, season, episode number, type (full/trailer/bonus), duration, publish date, file type/size, and the **direct downloadable audio URL**
- 📈 **Cadence analytics** - episode frequency (Daily/Weekly/…), estimated next-episode time, total episode count
- 🎞️ **Season & transcript metadata** - has-seasons, season count, auto-generated-transcript availability, transcript eligibility
- 💸 **Funding links** - the creator's support/donation links

### Input

| Field | Type | Description |
|---|---|---|
| Mode | Select | `Podcast search`, `Category charts`, `Episode search`, or `Paste URLs` |
| Search terms | List | Keywords (Search / Episode search modes) |
| Categories | Multi-select | 19 category charts (Discover mode) |
| Region | Select | Country whose charts to return - 37 fully localized regions (US, UK, DE, AU, CA, FR, ES, IT, NL, SE, NO, DK, FI, PL, PT, IE, NZ, ZA, BR, MX, IN, JP, KR, CN, TW, HK, SG, PH, TR, IL, SA, RU, UA, CZ, AT, CH, BE). An advanced Custom region field can override it; unsupported codes stop discover mode with a clear message. |
| Podcast URLs or UUIDs | List | `play.pocketcasts.com/podcasts/<uuid>` links or bare UUIDs (URL mode) |
| Max podcasts | Integer | Stop after N podcasts (0 = unlimited) |
| Max episodes | Integer | Cap episode-search records (0 = unlimited) |
| Max episodes per podcast | Integer | Cap the embedded episode list, newest first (0 = all) |
| Include episodes | Boolean | Embed the episode archive in each podcast record |
| Include ratings | Boolean | Fetch native ratings for each podcast |
| Resume from a previous run | Text | Paste a prior run/dataset ID to skip already-collected records (no duplicate rows, no duplicate billing) |
| Incremental mode | Boolean | For scheduled monitoring: first run returns everything as NEW, later runs return only NEW / UPDATED / REAPPEARED |
| State key | Text | Name a monitoring campaign to keep or deliberately share its state |
| Emit unchanged / Emit expired | Boolean | Also return UNCHANGED rows, and EXPIRED rows for records that vanished (complete scans only) |
| MCP connectors | List | Optionally pipe results into your apps (Notion page-per-item, others best-effort). Requires authorization under Apify Settings, API & Integrations |

### Output

One dataset item per podcast (or per episode in Episode search mode).

#### Podcast record

```json
{
  "uuid": "873e7420-042d-012e-f9a4-00163e1b201c",
  "url": "https://play.pocketcasts.com/podcasts/873e7420-...",
  "title": "The Joe Rogan Experience",
  "author": "Joe Rogan",
  "slug": "the-joe-rogan-experience",
  "description": "The official podcast of comedian Joe Rogan.",
  "descriptionHtml": "...",
  "category": "Comedy",
  "explicit": true,
  "showType": "episodic",
  "transcriptEligible": true,
  "episodeFrequency": "Daily",
  "estimatedNextEpisodeAt": "2026-08-28T17:00:00Z",
  "episodeCount": 2744,
  "hasSeasons": true,
  "seasonCount": 1,
  "ratingAverage": 4.5,
  "ratingTotal": 262002,
  "feedUrl": "https://feeds.megaphone.fm/GLT1412515089",
  "itunesId": "360084272",
  "episodeCountReturned": 2744,
  "episodes": [
    {
      "uuid": "9d45e19f-e566-414e-8791-7762c3c113a1",
      "url": "https://play.pocketcasts.com/podcasts/.../9d45e19e-...",
      "title": "#2547 - Daniel Everett",
      "slug": "2547-daniel-everett",
      "season": 0,
      "number": 2547,
      "type": "full",
      "durationSec": 9828,
      "publishedAt": "2026-08-27T17:00:00",
      "fileType": "audio/mp3",
      "fileSizeBytes": 0,
      "audioUrl": "https://traffic.megaphone.fm/GLT8609844651.mp3",
      "hasGeneratedTranscript": true,
      "podcastUuid": "873e7420-042d-012e-f9a4-00163e1b201c",
      "podcastTitle": "The Joe Rogan Experience"
    }
  ]
}
```

#### Episode-search record

`uuid`, `title`, `publishedAt`, `durationSec`, `audioUrl`, `podcastUuid`, `podcastTitle`.

### Use cases

- Podcast market research: rank shows by native listener ratings and volume
- Catalog building: complete episode lists with direct audio URLs
- Trend detection: publishing cadence and next-episode estimates across a category
- Lead generation: find podcasts by topic with funding/support links

### Pricing

You are billed per dataset record (podcast with episodes included, or episode-search result) plus a small actor-start fee. See the Apify Console pricing panel for current rates. Incremental mode suppresses unchanged rows, so scheduled monitoring bills only what changed.

### Notes

- Category charts return ~50 podcasts per category per region.
- `feedUrl` and `itunesId` are included when discovered via category charts (useful for artwork lookup).
- Direct `audioUrl` values are time-limited CDN links for some podcasts; re-fetch if expired.

# Actor input Schema

## `mode` (type: `string`):

How to find podcasts: keyword search, category charts, global episode search, or paste Pocket Casts URLs.

## `searchTerms` (type: `array`):

Keywords to search for (Search and Episode search modes).

## `categories` (type: `array`):

Category charts to scrape (Discover mode).

## `region` (type: `string`):

Country whose charts to return (Discover mode). All 37 verified regions are localized.

## `customRegion` (type: `string`):

Optional. Overrides Region with any two-letter code. Only the 37 listed regions have chart data; any other code stops discover mode with a clear message instead of returning wrong data.

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

Pocket Casts podcast links (URL mode). Accepts play.pocketcasts.com/podcasts/<uuid> links, or bare 36-character podcast UUIDs.

## `maxPodcasts` (type: `integer`):

Stop after this many podcasts (0 = no limit).

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

Stop after this many episode records in Episode search mode (0 = no limit).

## `maxEpisodesPerPodcast` (type: `integer`):

Cap the embedded episode list per podcast, newest first (0 = all episodes).

## `includeEpisodes` (type: `boolean`):

Embed the episode archive inside each podcast record.

## `includeRatings` (type: `boolean`):

Fetch Pocket Casts native ratings (average + total votes) for each podcast.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull without returning items already collected there.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching record as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each search, filter and lookup setup; use State key to name or deliberately share a monitoring campaign.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search and filter settings.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return records that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return records that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output.

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

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

Apify Proxy settings. Works on every proxy plan.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [
    "true crime"
  ],
  "categories": [
    "comedy"
  ],
  "region": "us",
  "urls": [
    "https://play.pocketcasts.com/podcasts/873e7420-042d-012e-f9a4-00163e1b201c"
  ],
  "maxPodcasts": 10,
  "maxEpisodes": 100,
  "maxEpisodesPerPodcast": 0,
  "includeEpisodes": true,
  "includeRatings": true,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (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 = {
    "mode": "search",
    "searchTerms": [
        "true crime"
    ],
    "categories": [
        "comedy"
    ],
    "region": "us",
    "urls": [
        "https://play.pocketcasts.com/podcasts/873e7420-042d-012e-f9a4-00163e1b201c"
    ],
    "maxPodcasts": 10,
    "maxEpisodes": 100,
    "maxEpisodesPerPodcast": 0,
    "includeEpisodes": true,
    "includeRatings": true,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "maxNotifyListings": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/pocketcasts-podcast-scraper").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 = {
    "mode": "search",
    "searchTerms": ["true crime"],
    "categories": ["comedy"],
    "region": "us",
    "urls": ["https://play.pocketcasts.com/podcasts/873e7420-042d-012e-f9a4-00163e1b201c"],
    "maxPodcasts": 10,
    "maxEpisodes": 100,
    "maxEpisodesPerPodcast": 0,
    "includeEpisodes": True,
    "includeRatings": True,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "maxNotifyListings": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/pocketcasts-podcast-scraper").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 '{
  "mode": "search",
  "searchTerms": [
    "true crime"
  ],
  "categories": [
    "comedy"
  ],
  "region": "us",
  "urls": [
    "https://play.pocketcasts.com/podcasts/873e7420-042d-012e-f9a4-00163e1b201c"
  ],
  "maxPodcasts": 10,
  "maxEpisodes": 100,
  "maxEpisodesPerPodcast": 0,
  "includeEpisodes": true,
  "includeRatings": true,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/pocketcasts-podcast-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/pocketcasts-podcast-scraper"
        }
    }
}

```

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/1lRMv1KOdP0eQHA5P/builds/Drgtn1gAbNzjCXdvf/openapi.json
