Substack Podcasts Scraper avatar

Substack Podcasts Scraper

Pricing

from $0.43 / 1,000 public podcast episodes

Go to Apify Store
Substack Podcasts Scraper

Substack Podcasts Scraper

Export and monitor public Substack podcast episodes, show notes, publication metadata, and public audio enclosure URLs from one or many publication or RSS feed URLs.

Pricing

from $0.43 / 1,000 public podcast episodes

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Categories

Share

Export and monitor public Substack podcasts without downloading audio or opening a browser. Give the Actor one or more publication homepages or RSS feed URLs and receive typed episode records with show notes, dates, GUIDs, images, categories, publication metadata, and public audio enclosure URLs.

The Actor is designed for podcast researchers, media teams, aggregators, newsletter analysts, and data engineers who need repeatable Substack podcast exports. It follows official public RSS feeds, supports publications on custom domains, and excludes paid/private feeds and subscriber-only episodes.

What does Substack Podcasts Scraper do?

The Actor turns public Substack podcast feeds into integration-ready JSON, CSV, Excel, XML, RSS, or HTML through Apify Dataset exports.

It can:

  • accept a Substack publication homepage or its /feed URL;
  • process up to 100 feeds in one run;
  • return only feed items that contain a public audio enclosure;
  • extract publication and episode metadata;
  • exclude records marked for paid subscribers;
  • deduplicate episodes by GUID, canonical URL, or audio URL;
  • filter episodes by publication date;
  • add stable feed and fetch metadata for scheduled monitoring;
  • optionally inspect public audio response headers without downloading audio;
  • stop at a global maxItems limit.

Who is this Substack podcast scraper for?

Podcast researchers

Build a current catalog of episodes, authors, publication dates, show notes, and audio links for analysis.

Media and editorial teams

Monitor public episodes across a list of Substack publications and compare scheduled run exports by episodeId.

Podcast directories and aggregators

Normalize several public feeds into one dataset while preserving each source feed and publication.

Data engineers

Send structured episode records to a warehouse, spreadsheet, webhook, n8n, Make, Zapier, or another Actor.

AI and search teams

Use titles, descriptions, categories, canonical URLs, and source metadata as inputs to lawful indexing or enrichment workflows.

Why use this Actor?

  • Substack-specific access filtering: public post metadata is used to exclude only_paid episodes even if an enclosure appears in the public RSS XML.
  • Feed and homepage inputs: the Actor normalizes publication pages to their public feed automatically.
  • Custom-domain support: redirects such as a *.substack.com URL to the publication's branded domain are followed.
  • Multi-feed provenance: every row includes input URL, final feed URL, feed index, episode index, and fetch timestamp.
  • Low overhead: direct HTTP and structured XML/JSON parsing avoid browser startup and media downloads.
  • Optional audio inspection: request downloadable-audio headers only when your workflow needs them.

What data can you extract?

FieldMeaning
episodeIdStable GUID, canonical URL, or audio URL used for deduplication
titleEpisode title
descriptionPlain-text description or show notes, when present
authorEpisode creator or publication author
publishedAtNormalized ISO 8601 publication timestamp
canonicalUrlPublic Substack episode post URL
guidRSS item GUID
imageUrlEpisode image, falling back to the publication image
categoriesRSS categories
durationRSS duration or whole seconds from public Substack metadata
explicitPodcast explicit-content value, when published
episodeNumberPodcast episode number, when published
accessLevelAlways public; paid-only records are not emitted
audioUrlPublic audio enclosure URL
audioTypeEnclosure MIME type, such as audio/mpeg
audioLengthBytesEnclosure length from RSS when supplied
audioMetadataOptional HEAD response metadata; no audio is downloaded
publicationTitlePublication or podcast title
publicationDescriptionPublication description
publicationAuthorPublication author
publicationUrlPublication homepage
publicationImageUrlPublication image
sourceInputUrlOriginal user input
sourceFeedUrlFinal RSS URL after redirects
feedIndexZero-based successfully processed feed index
episodeIndexZero-based episode position in the source feed
fetchedAtShared ISO 8601 fetch timestamp for the run

Nullable fields are returned as null when the public source does not publish them. audioMetadata is omitted when it is disabled or the optional HEAD request is rejected.

How to scrape public Substack podcast episodes

  1. Open the Actor input page.
  2. Add one or more public publication or /feed URLs to Substack publication or feed URLs.
  3. Set Maximum episodes for the combined dataset.
  4. Optionally add date boundaries for a monitoring window.
  5. Enable Fetch downloadable audio metadata only if response headers are useful to you.
  6. Click Start.
  7. Open the Dataset tab and export the episode rows in your preferred format.

A simple input is:

{
"startUrls": [
{ "url": "https://wethefifth.substack.com" }
],
"maxItems": 10
}

Input parameters

ParameterTypeDefaultDescription
startUrlsarrayrequired1–100 public Substack publication homepages or RSS feed URLs
maxItemsinteger100Global episode limit from 1 to 10,000
publishedAfterstringnoneInclude episodes on or after this ISO 8601 timestamp
publishedBeforestringnoneInclude episodes on or before this ISO 8601 timestamp
fetchAudioMetadatabooleanfalseInspect public audio headers without downloading media

Both date filters apply identically to homepage and direct-feed inputs. An item with no valid publication date is excluded when either boundary is active.

Output example

A current public episode produces a record shaped like this:

{
"recordType": "episode",
"episodeId": "https://www.wethefifth.com/p/the-fifth-gets-a-substitute-teacher",
"title": "The Fifth Gets a Substitute Teacher (w/ Jesse Singal) #568",
"description": "Kmele is joined by Jesse Singal for a new episode...",
"author": "The Fifth Column",
"publishedAt": "2026-07-29T11:03:18.000Z",
"canonicalUrl": "https://www.wethefifth.com/p/the-fifth-gets-a-substitute-teacher",
"guid": "https://www.wethefifth.com/p/the-fifth-gets-a-substitute-teacher",
"imageUrl": "https://substackcdn.com/image/fetch/...",
"categories": [],
"duration": "6075",
"explicit": null,
"episodeNumber": null,
"accessLevel": "public",
"audioUrl": "https://api.substack.com/feed/podcast/208913612/....mp3",
"audioType": "audio/mpeg",
"audioLengthBytes": 0,
"publicationTitle": "The Fifth Column (A Podcast)",
"publicationUrl": "https://www.wethefifth.com",
"sourceInputUrl": "https://wethefifth.substack.com",
"sourceFeedUrl": "https://www.wethefifth.com/feed",
"feedIndex": 0,
"episodeIndex": 1,
"fetchedAt": "2026-08-03T06:00:00.000Z"
}

The example is shortened for readability. Dataset rows retain all schema fields.

How much does it cost to extract Substack podcast episodes?

This is a pay-per-event Actor. It charges one Start event of $0.00005 per run and one Public podcast episode event for each row saved. It does not charge for non-audio posts, subscriber-only episodes, duplicate rows, failed feeds, filtered rows, or optional HEAD requests.

At the BRONZE tier, the episode price is $0.0007128:

Useful outputCalculationPrice
1 episode$0.00005 + 1 × $0.0007128$0.0007628
10 episodes$0.00005 + 10 × $0.0007128$0.007178
100 episodes$0.00005 + 100 × $0.0007128$0.07133

Apify account tiers use lower per-episode prices at higher tiers. The Console always shows the active price before a run starts. The examples above exclude any unrelated integration or storage charges outside this Actor.

Monitor new Substack podcast episodes

For repeat monitoring:

  1. Save the same feed list in an Apify Task.
  2. Schedule it daily or weekly.
  3. Set publishedAfter to the beginning of the monitoring window when appropriate.
  4. Compare datasets by episodeId.
  5. Use fetchedAt to identify the run snapshot and sourceFeedUrl to group publications.

The Actor does not maintain a hidden cross-run database. This keeps each run reproducible and lets you choose the comparison destination.

Example monitoring input:

{
"startUrls": [
{ "url": "https://wethefifth.substack.com" },
{ "url": "https://www.lennysnewsletter.com/feed" }
],
"publishedAfter": "2026-07-01T00:00:00Z",
"maxItems": 100
}

Export and integration workflows

Spreadsheet export

Open the Dataset and select CSV or Excel. Publication, episode, date, and source fields are immediately usable as columns.

Data warehouse

Use the Dataset API to pull JSON and upsert by episodeId. Keep fetchedAt as the observation timestamp.

Webhooks

Attach an Apify webhook to a Task run and notify your workflow after the dataset is ready.

n8n, Make, or Zapier

Run the Actor on a schedule, fetch dataset items, then route new IDs to a database, editorial queue, or notification channel.

AI enrichment

Pass public titles and show notes to a separate classifier or summarizer. Do not assume the extracted description is a complete transcript.

Run with the Apify API

Replace YOUR_TOKEN with an Apify API token.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~substack-podcast-feed-episode-scraper/runs?token=YOUR_TOKEN&waitForFinish=120" \
-H "Content-Type: application/json" \
-d '{"startUrls":[{"url":"https://wethefifth.substack.com"}],"maxItems":10}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/substack-podcast-feed-episode-scraper').call({
startUrls: [{ url: 'https://wethefifth.substack.com' }],
maxItems: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
import os
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/substack-podcast-feed-episode-scraper').call(run_input={
'startUrls': [{'url': 'https://wethefifth.substack.com'}],
'maxItems': 10,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

Use with Apify MCP

Add the Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/substack-podcast-feed-episode-scraper"

Claude Desktop

Add this server to the mcpServers object in Claude Desktop's configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/substack-podcast-feed-episode-scraper"
}
}
}

Cursor

Open Settings → Tools & MCP → New MCP Server and use the same Apify MCP URL shown above.

VS Code

Add an HTTP MCP server in your VS Code MCP configuration using the same Apify MCP URL shown above.

Example prompts:

  • “Extract the latest 10 public podcast episodes from https://wethefifth.substack.com.”
  • “Combine these three public Substack podcast feeds and return episode IDs, dates, show notes, and audio URLs.”
  • “Inspect downloadable audio metadata for the latest five public Lenny's Podcast episodes.”

Public RSS feeds are intended for syndication, but availability does not remove copyright, privacy, database-right, or contractual obligations. Use the records only for a lawful purpose, follow applicable terms and regulations, and obtain permission before republishing audio or substantial show-note content. This Actor does not bypass authentication or paywalls and is not legal advice.

Limits and responsible use

  • Only public, anonymous Substack publication and RSS URLs are supported.
  • Paid/private feeds, personal subscriber feed URLs, authenticated content, and subscriber-only audio are out of scope.
  • The Actor does not bypass paywalls, log in, or accept cookies/credentials.
  • RSS commonly contains only the latest items; this Actor does not promise a publication's complete historical archive.
  • maxItems applies across all feeds, in input order.
  • Source fields can be missing or malformed; nullable output fields reflect what the publisher provides.
  • Optional audio metadata depends on the audio host accepting HEAD requests.
  • Audio files are linked, not downloaded, copied, or transcribed.
  • Respect publisher rights, applicable law, contractual restrictions, and personal-data obligations.
  • Do not republish copyrighted audio or show notes without permission.

Troubleshooting

Why did the run say no episodes were saved?

The feed may contain articles but no public audio enclosures, all recent episodes may be subscriber-only, or your date window may exclude every episode. Open the public /feed URL and check that it is a podcast feed.

Why did one feed fail while other feeds produced rows?

Multi-feed runs continue after an individual invalid, private, removed, or temporarily unavailable feed. The run fails only when no useful public episode is saved.

Why is audioLengthBytes zero or null?

Some RSS feeds publish length="0". Enable fetchAudioMetadata to request the public audio server's current Content-Length, when supported.

Does the Actor download podcast audio?

No. Normal runs read RSS and public post metadata. Optional enrichment sends HEAD requests only.

Can I scrape a private subscriber RSS URL?

No. Do not provide personalized feed tokens or credentials. This Actor intentionally supports public publications only.

Can I obtain transcripts?

No. The Actor returns public show notes and audio metadata, not transcripts. Send lawful public audio to a separate transcription workflow if you have the necessary rights.

FAQ

Do publication homepage URLs work?

Yes. The Actor converts the homepage to /feed and follows a redirect to a custom publication domain when Substack provides one.

Are non-podcast newsletter posts returned?

No. An RSS item must contain a public audio enclosure to become an episode record.

Are duplicates charged?

No. Duplicate episode IDs within a run are discarded before charging and dataset storage.

Can I process several feeds?

Yes. Supply up to 100 URLs. maxItems is the combined output limit.

Is this an official Substack API?

No. It is an independent Actor that reads anonymous public RSS and publication metadata surfaces. It is not affiliated with or endorsed by Substack.