Pocket Casts Podcast Scraper - Ratings & Full Episode Archive
Pricing
from $1.80 / 1,000 podcast or episode records
Pocket Casts Podcast Scraper - Ratings & Full Episode Archive
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.
Pricing
from $1.80 / 1,000 podcast or episode records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Pocket Casts Scraper: Podcast Ratings, Episode Archives & Charts
Pocket Casts Scraper turns the Pocket Casts catalog into structured podcast data. Search by keyword, pull ranked category charts by region, search episodes globally across every show, or paste podcast links or UUIDs for full enrichment. Every podcast record can carry native Pocket Casts listener ratings, publishing cadence, season metadata and a complete episode archive with direct audio URLs, data that a plain RSS feed or the website does not expose. Export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Four ways to find podcasts. Search by keyword, pull ranked category charts per region, search episodes globally across every show, or paste podcast links or UUIDs.
- Native listener ratings. Average rating and total vote count straight from Pocket Casts' own listeners, not available in an RSS feed.
- Full episode archives in one record. Every episode's title, season, number, type, duration, publish date, file type and size, and a direct playable audio URL.
- Cadence and season intelligence. Publishing frequency, an estimated next-episode time, season count and transcript availability.
- 37 localized regions and 19 category charts for market research across countries and topics.
- Built for monitoring. Resume an interrupted podcast run without paying twice, or turn on incremental mode so scheduled runs return only new and changed shows.
- Optional export into your workspace. Send results into Notion, Linear or Airtable as an extra delivery step after the scrape.
Use Cases
- Podcast market research: rank shows by native listener ratings and volume across categories and regions.
- Catalog and directory building: pull complete episode archives with direct audio URLs for indexing or syndication.
- Trend and cadence tracking: monitor publishing frequency and estimated next-episode times across a niche.
- Content and creator discovery: find podcasts by topic or keyword, including their funding and support links.
- Global content monitoring: schedule recurring runs and collect only new or updated shows and episodes.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
uuid | "c1a2b3d4-0000-4000-8000-aabbccddeeff" |
url | Pocket Casts share link for the podcast |
title | "Midnight Static" |
author | "Alex Rivera" |
slug | "midnight-static" |
description / descriptionHtml | plain text and HTML show notes |
category | "True Crime" |
explicit | false |
showType | "episodic" (also "serial") |
transcriptEligible | true |
episodeFrequency | "Weekly" |
estimatedNextEpisodeAt | "2026-10-05T09:00:00Z" |
episodeCount | 184 |
hasSeasons / seasonCount | true / 4 |
ratingAverage / ratingTotal | 4.6 / 3120 (when Include ratings is on) |
feedUrl / itunesId | RSS feed URL and iTunes catalog id (Discover mode only) |
website | the podcast's own site (Discover mode only) |
fundings | the creator's support or donation links |
episodeCountReturned | 1 |
episodes | the embedded episode archive (see below) |
episodes[].audioUrl / episodes[].durationSec | direct playable file / length in seconds |
Each entry in episodes also carries uuid, url, title, slug, season, number, type, publishedAt, fileType, fileSizeBytes, hasGeneratedTranscript, podcastUuid and podcastTitle. Episode search mode returns a lighter standalone record instead of a podcast record: uuid, title, publishedAt, durationSec, audioUrl, podcastUuid and podcastTitle only, no season, number, type, file metadata or transcript flag.
How to Use
- Pick a mode:
search(by keyword),discover(category charts),episodes(global episode search), orurl(paste links or UUIDs). - Fill in the fields for that mode, and switch ratings and episode inclusion on or off.
- Set Max podcasts or Max episodes to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search for podcasts by keyword:
{"mode": "search","searchTerms": ["cold case mysteries"],"maxPodcasts": 5,"includeRatings": true}
A category chart for a region:
{"mode": "discover","categories": ["comedy", "true-crime"],"region": "gb","maxPodcasts": 10}
Global episode search:
{"mode": "episodes","searchTerms": ["climate solutions"],"maxEpisodes": 50}
Paste a podcast link or UUID:
{"mode": "url","urls": ["https://play.pocketcasts.com/podcasts/00000000-0000-4000-8000-000000000001"],"includeEpisodes": true,"maxEpisodesPerPodcast": 20}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/pocketcasts-podcast-scraper").call(run_input={"mode": "search", "searchTerms": ["cold case mysteries"], "maxPodcasts": 5})for podcast in client.dataset(run["defaultDatasetId"]).iterate_items():print(podcast["title"], podcast["ratingAverage"], podcast["episodeCount"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/pocketcasts-podcast-scraper').call({ mode: 'search', searchTerms: ['cold case mysteries'], maxPodcasts: 5 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset ID and Podcast search, Discover and URL mode skip everything already collected there, so you don't pay twice. Episode search mode does not honor Resume yet: a resumed run in Episode search mode currently re-collects and re-bills every matching episode from scratch, including ones already returned by the pasted run. If you run Episode search on a schedule, use Incremental mode instead of Resume. - Incremental mode (
incrementalMode) is for running the same search, chart or URL list again and again (for example daily) and getting only what changed. Each record is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that scanned its whole tracked scope, and only withemitExpired).stateKeynames or shares the stored state. With incremental mode off, output is exactly as before. emitExpiredis not capped by Max podcasts or Max episodes. The expired pass runs after the normal scan and pushes one row for every previously tracked record this run did not see again, with no limit of its own. If a run is capped or resumed, expired detection is skipped for that run entirely, but if today's search, chart or URL list simply returns fewer live results than your stored baseline (not because a limit was hit), every one of those older baseline records is pushed asEXPIREDin that single run, however large Max podcasts or Max episodes says the run should be. A monitoring campaign with a large tracked history can therefore emit and bill far more rows than the caps suggest the moment it is turned on. TestemitExpiredon a small, fresh state key first, and expect the run's total row count to include the full expired count on top of the declared cap.- A refused request can be mistaken for a clean, empty result. When a search term, category chart or episode search is still refused after its retries, the actor treats it as "no results" rather than "could not be checked". So if one term or category fails for a whole run while the others succeed,
emitExpiredstill fires and can tombstone that term's previously tracked podcasts or episodes asEXPIREDeven though they were never re-checked. The same applies to a single podcast whose details could not be fetched in that run: it is dropped from the run and, withemitExpiredon, markedEXPIRED. Track one search term or category per State key if you rely onemitExpired, so a refusal empties the whole run (which disables expired detection) instead of only part of it, and treat an isolatedEXPIREDrow as a prompt to re-check rather than proof the show is gone.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify, Settings, API & Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search, discover, episodes, or url. |
searchTerms | array | ["true crime"] | Keywords to search (Search and Episode search modes); each term is searched separately and merged. |
categories | array | ["comedy"] | Category charts to scrape (Discover mode); pick from the 19 listed categories. |
region | string | us | Country whose charts to return (Discover mode); all 37 listed regions are localized. |
customRegion | string | (none) | Optional two-letter code overriding Region; unsupported codes stop discover mode with a clear message. |
urls | array | sample | Pocket Casts podcast links or bare UUIDs (URL mode). |
maxPodcasts | integer | 10 | Stop after this many podcasts (0 = no limit). |
maxEpisodes | integer | 100 | Stop after this many episode records in Episode search mode (0 = no limit). |
maxEpisodesPerPodcast | integer | 0 | Cap the embedded episode list per podcast, newest first (0 = all episodes). |
includeEpisodes | boolean | true | Embed the episode archive inside each podcast record. |
includeRatings | boolean | true | Fetch Pocket Casts native ratings (average and total votes) for each podcast. |
resumeFromRunId | string | (none) | Continue one interrupted run without returning items already collected there. |
incrementalMode | boolean | false | Return only new and changed records on scheduled runs. |
stateKey | string | (none) | Name or share an incremental-mode state. |
emitUnchanged | boolean | false | Also return (and bill) unchanged records. |
emitExpired | boolean | false | Also return (and bill) records that were tracked before but are no longer found. |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
proxyConfiguration | object | Apify Proxy | Connection settings; works on every proxy plan. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"uuid": "c1a2b3d4-0000-4000-8000-aabbccddeeff","url": "https://play.pocketcasts.com/podcasts/c1a2b3d4-0000-4000-8000-aabbccddeeff","title": "Midnight Static","author": "Alex Rivera","slug": "midnight-static","description": "A weekly look at unsolved mysteries and cold cases.","descriptionHtml": "<p>A weekly look at unsolved mysteries and cold cases.</p>","category": "True Crime","explicit": false,"showType": "episodic","audioOnly": true,"isPrivate": false,"transcriptEligible": true,"episodeFrequency": "Weekly","estimatedNextEpisodeAt": "2026-10-05T09:00:00Z","episodeCount": 184,"hasSeasons": true,"seasonCount": 4,"hasMoreEpisodes": false,"fundings": [{ "url": "https://example.com/support-midnight-static", "title": "Support the show" }],"ratingAverage": 4.6,"ratingTotal": 3120,"feedUrl": "https://feeds.example.com/midnight-static","itunesId": "1000000001","website": "https://midnightstatic.example.com","episodeCountReturned": 1,"episodes": [{"uuid": "d5e6f7a8-0000-4000-8000-112233445566","url": "https://play.pocketcasts.com/podcasts/c1a2b3d4-0000-4000-8000-aabbccddeeff/d5e6f7a8-0000-4000-8000-112233445566","title": "Episode 142: The Vanishing Signal","slug": "episode-142-the-vanishing-signal","season": 4,"number": 142,"type": "full","durationSec": 2760,"publishedAt": "2026-09-28T09:00:00","fileType": "audio/mp3","fileSizeBytes": 44200000,"audioUrl": "https://cdn.example.com/midnight-static/episode-142.mp3","hasGeneratedTranscript": true,"podcastUuid": "c1a2b3d4-0000-4000-8000-aabbccddeeff","podcastTitle": "Midnight Static"}]}
Plan Requirement
The default proxy setting works out of the box, and the actor rotates connections automatically when one is refused. For large or frequent runs, the residential proxy group gives more headroom; pick it under Connection.
FAQ
How much does it cost?
You pay per record returned (a podcast with its episodes included counts once, an episode-search result counts once), plus a small actor-start fee. The Pricing tab shows the current rates. Use Max podcasts or Max episodes to cap the cost of any run.
Is it legal to scrape Pocket Casts?
This actor collects only publicly available podcast catalog data. You are responsible for how you use it: follow Pocket Casts' terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Show and episode metadata are generally facts, but artwork, audio files and show descriptions may be subject to third-party rights.
Can I get only new or changed podcasts on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared records, and unchanged ones are not billed unless you turn on Emit unchanged.
Why did an incremental run with Emit expired return far more rows than Max podcasts?
emitExpired tombstones every previously tracked record this run did not see again, and that pass has no cap of its own: it is not limited by Max podcasts or Max episodes. It only runs at all when the scan was not capped or resumed, but if today's search or chart simply turns up fewer live results than your stored history, the whole gap between the two gets pushed as EXPIRED in one run. Start emitExpired on a small state key before pointing it at a large tracked campaign, and expect the total row count (and bill) to include that full expired count.
Does Resume work in Episode search mode?
Not yet. resumeFromRunId correctly skips already-collected records in Podcast search, Discover and URL mode. In Episode search mode it is currently ignored, so a resumed run re-collects and re-bills every matching episode from scratch. Use Incremental mode for recurring Episode search runs instead.
Why did my run fail instead of returning an empty dataset?
If the actor found podcasts to fetch but none of their details could be read, the run stops with a clear message so "nothing available" is never confused with "the request never got through". An unsupported Discover region also fails loudly by design, naming the region, instead of silently returning zero podcasts. One gap remains: if the search, chart or episode search request itself is refused for every term or category, the run currently finishes successfully with an empty dataset rather than failing. If a search you expect to have results comes back empty, run it again in a few minutes before concluding there is nothing to find.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
๐ More scrapers you might like
Pair this actor with these related scrapers from the same team:
| ๐งฉ AniList Anime & Manga Scraper Scrape AniList anime and manga: titles (romaji/English/native), scores, popularity... | ๐งฉ TuneIn Scraper Scrape TuneIn by keyword, category, genre, location or URL. Extract stations and podcasts... |
| ๐งฉ Anghami Scraper Scrape Anghami's public catalog by keyword or player URL. Rows carry their kind (song... | ๐งฉ WEBTOON Scraper Scrape the WEBTOON catalog into structured data. Extract series, genres, rankings and... |
| โฝ JioHotstar Scraper Scrape the JioHotstar catalog by content type or URL. Extract shows, movies, episodes... | ๐ค Udio Scraper Collect public Udio tracks with the complete generation prompt, full lyrics, style tags... |
๐ Browse all abotapi scrapers
๐ฌ Support & custom scrapers
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- โญ Enjoying it? A quick review on the actor page helps other users find it.