Substack Scraper - Newsletters, Posts, Comments & Leaderboards
Pricing
from $0.45 / 1,000 newsletter rows
Substack Scraper - Newsletters, Posts, Comments & Leaderboards
Scrape Substack newsletters, posts and comments: subscriber counts, paid plan prices, author socials and contact emails, leaderboard ranks, full text of free posts, likes, restacks. Search by keyword or category. $0.45 per 1,000 newsletters, $0.27 per 1,000 posts, $0.18 per 1,000 comments.
Pricing
from $0.45 / 1,000 newsletter rows
Rating
0.0
(0)
Developer
Top Api
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
What does Substack Scraper do?
Substack Scraper extracts public data from Substack and turns newsletter links, search terms or leaderboard categories into structured rows: newsletters with subscriber counts, paid plan prices, author socials and contact emails; posts with likes, comments, restacks and the full text of free posts; and comment threads. Built for sponsorship and partnership teams, creator-economy analysts, media researchers and AI teams who need Substack data without an API key.
Substack Scraper - Substack API alternative - Substack newsletter scraper - Substack leaderboard scraper - Substack posts and comments scraper
- Three kinds of rows in one actor: newsletters, posts and comments. The
typefield says which. - Newsletter leads in every newsletter row: subscriber count, paid subscriber band, monthly / annual / founding prices, author followers, X, LinkedIn, Instagram, YouTube, TikTok and website links, contact emails from the About page, post count and posting rate.
- Leaderboards and categories: Substack's paid Bestsellers and Rising leaderboards for all 33 categories, plus each category's Top, Top paid and Top free lists, in rank order.
- Full text of free posts: plain text, HTML or Markdown, with likes, comments, restacks, word count, tags and bylines. Paid posts keep their metadata and Substack's public teaser line.
- Search by keyword: find newsletters or posts on any topic.
- No login, cookies or API key: the actor reads the same public data substack.com shows a signed-out visitor.
- Monitor mode: run it on a schedule and get only new posts and comments, and newsletters whose subscribers, prices or post count changed.
- Pay per row, no start fee: $0.27 per 1,000 posts, $0.45 per 1,000 newsletters, $0.18 per 1,000 comments.
What data can you get from Substack?
| ๐ฐ Newsletter name, link, tagline | ๐ฅ Subscriber count subscriberCount | ๐ฐ Paid subscriber band |
| ๐ณ Monthly, annual, founding price | ๐ Leaderboard rank and category | ๐ Bestseller tier |
| โ๏ธ Author name, handle, bio, followers | ๐ X, LinkedIn, Instagram, YouTube, TikTok, website | ๐ง Contact emails emails |
| ๐๏ธ Created, first and last post date | ๐งฎ Post count, posts per month | ๐๏ธ Podcast, community, sections |
| ๐ Post title, subtitle, link, date | ๐ Audience (free / paid) | โค๏ธ Likes, comments, restacks |
| ๐ Full text, HTML, Markdown | ๐ค Word count, reading time, tags | ๐ฌ Comments with author, likes, depth |
How to scrape Substack with Substack Scraper
- Create a free Apify account (it comes with free monthly credit).
- Open Substack Scraper and click Try for free.
- Paste newsletter links, add search terms, or pick leaderboard categories.
- Choose what to read: posts, full text, comments, and the filters you need.
- Click Start.
- Download the results as JSON, CSV, Excel or HTML, or read them through the API.
Input
Combine any of these in one run. Every field is optional; a run with no input scrapes a small documented sample.
| Parameter | Type | Description |
|---|---|---|
startUrls | array | Newsletter links or names (https://www.lennysnewsletter.com, lenny.substack.com, lenny), post links (โฆ/p/<slug>), profiles (substack.com/@lenny), leaderboard links (substack.com/leaderboard/technology/paid) or search links. |
searchQueries | array | Search terms. |
searchType | string | newsletters (default) or posts. |
maxResultsPerSearch | integer | Newsletters or posts per search term. Default 20. |
leaderboardCategories | array | Category slugs: technology, business, culture, finance โฆ or bestseller (all categories, Rising list). |
boardTypes | array | paid (Bestsellers, default), rising, top, topPaid, topFree. |
maxResultsPerBoard | integer | Newsletters per list in rank order. Default 25; leaderboards hold 100, Top lists up to 525. |
includePublicationInfo | boolean | A newsletter row for each newsletter link. Default on. |
newsletterDetails | boolean | Author profile (followers, socials), About page (emails), sitemap (post count), latest posts (last post date, posts per month). Default on. |
includeRecommendations | boolean | Newsletters each newsletter recommends. Default off. |
minSubscribers, onlyPaidNewsletters, onlyWithEmail | Newsletter filters, applied before the charge. | |
includePosts | boolean | Posts of each newsletter link. Default on. |
scrapePostsOfFoundNewsletters | boolean | Posts of newsletters found by search or leaderboards. Default off. |
maxPostsPerNewsletter | integer | Posts per newsletter after filters. Default 20. 0 = newsletter rows only. |
postSort | string | new (default) or top. |
searchInNewsletter | string | Only posts matching these words (Substack's archive search). |
includeContent | boolean | Full text of free posts. Default on. |
contentFormat | string | textAndHtml (default), text, html, markdown, all. |
audience, postType, dateFrom, dateTo, withinDays, minReactions, minComments, minWordCount, titleContains | Post filters, applied before the charge. | |
includeComments | boolean | Comment rows for every saved post. Default off. |
maxCommentsPerPost | integer | Comments and replies per post. Default 50. |
maxItems | integer | Most rows per run (all kinds together). Default 500. 0 = no cap. |
monitorMode, monitorStoreName | Only rows that are new or changed since the last run, remembered in a named store. | |
proxyConfiguration | object | Optional; Substack answers without a proxy. |
maxConcurrency | integer | Parallel requests. Default 8. |
Input JSON
{"startUrls": ["https://www.lennysnewsletter.com", "newsletter.pragmaticengineer.com"],"maxPostsPerNewsletter": 50,"audience": "free","includeComments": true,"maxCommentsPerPost": 100}
Build a sponsor or partner list from a leaderboard
{"leaderboardCategories": ["technology", "business", "finance"],"boardTypes": ["paid", "rising"],"maxResultsPerBoard": 100,"maxPostsPerNewsletter": 0}
Each newsletter row carries its rank, subscriber count, prices, author socials and emails. Add minSubscribers or onlyWithEmail to keep only the newsletters you can pitch.
Find newsletters on a topic
Put the topic in searchQueries and keep searchType on newsletters. Substack's newsletter search sometimes answers empty; the actor asks again, and if it stays empty it takes the newsletters behind the keyword's matching posts, ranked with the keyword in the newsletter's name or description first. The foundVia field says which route found each one.
Output
Every row has a type: newsletter, post or comment. A newsletter row (excerpt, from a real run):
{"type": "newsletter","rank": 1,"boardType": "paid","category": "Technology","name": "SemiAnalysis","url": "https://newsletter.semianalysis.com","subscriberCount": 325000,"subscriberCountString": "325K+","paidSubscriberDetail": "Tens of thousands of paid subscribers","monthlyPrice": 50,"annualPrice": 500,"currency": "USD","postCount": 349,"lastPostDate": "2026-10-23T19:06:44.981Z","authorName": "Dylan Patel","authorFollowerCount": 378202,"authorTwitterUrl": "https://x.com/dylan522p","authorLinkedinUrl": null,"email": "Sales@SemiAnalysis.com","leaderboardRank": 1,"createdAt": "2025-09-22T15:54:12.958Z"}
A post row (excerpt):
{"type": "post","postId": 197186925,"title": "Open Thread 433","url": "https://www.astralcodexten.com/p/open-thread-433","publishedAt": "2026-05-11T08:43:51.779Z","audience": "everyone","postType": "newsletter","wordCount": 283,"reactionCount": 72,"commentCount": 887,"restacks": 5,"authorName": "Scott Alexander","publicationName": "Astral Codex Ten","bodyText": "This is the weekly visible open thread. Post about anything you want, ask random questions, whatever. ACX has an unofficial subreddit, Discoโฆ"}
A comment row (excerpt):
{"type": "comment","commentId": 200886717,"postTitle": "The Dilbert Afterlife","parentId": 200690507,"depth": 1,"body": "Yeah, I got this feeling, too. I don't think it was the author's intent, but he did end up saying some apologist/sympathizer statements thatโฆ","publishedAt": "2026-01-16T23:15:48.515Z","authorName": "Braden F","authorHandle": "bradenf","reactionCount": 3,"childrenCount": 3,"commentUrl": "https://www.astralcodexten.com/p/the-dilbert-afterlife/comment/200886717"}
Fields
| Row | Field | Type | Meaning | Filled |
|---|---|---|---|---|
| newsletter | name | string | Newsletter name. | 100% |
| newsletter | url | string | Link to the newsletter (custom domain when it has one), the post, or the comment. | 100% |
| newsletter | subscriberCount | integer | Subscribers as a number (exact when Substack shows "Over 1,200,000 subscribers", else from the rounded figure). Null when the newsletter hides it. | 94% |
| newsletter | subscriberCountString | string | Subscriber figure as Substack shows it, e.g. "1.2M+". | 94% |
| newsletter | totalSubscriberDetail | string | Substack's exact subscriber line, e.g. "Over 1,200,000 subscribers". | 94% |
| newsletter | paidSubscriberDetail | string | Paid-subscriber band, e.g. "Tens of thousands of paid subscribers". | 91% |
| newsletter | bestsellerTier | integer | Substack Bestseller badge tier (100, 1000, 10000 paid subscribers). | 100% |
| newsletter | monthlyPrice | number | Monthly plan price. | 99% |
| newsletter | annualPrice | number | Annual plan price. | 99% |
| newsletter | foundingPrice | number | Founding-member plan price (minimum). | 75% |
| newsletter | currency | string | Plan currency. | 99% |
| newsletter | plans | array | Every active plan: name, interval, price, currency, founding. | 99% |
| newsletter | postCount | integer | Posts in its sitemap (every published post link). | 95% |
| newsletter | lastPostDate | string | Date of its newest post. | 71% |
| newsletter | postsPerMonth | number | Posting rate over its latest 12 posts. | 71% |
| newsletter | createdAt | string | When the newsletter was created on Substack. | 100% |
| newsletter | authorName | string | Author name. | 100% |
| newsletter | authorHandle | string | Author Substack handle. | 100% |
| newsletter | authorFollowerCount | integer | Author followers on Substack. | 88% |
| newsletter | authorTwitterUrl | string | Twitter / X link. | 70% |
| newsletter | authorLinkedinUrl | string | LinkedIn link. | 41% |
| newsletter | authorInstagramUrl | string | Instagram link. | 17% |
| newsletter | authorYoutubeUrl | string | YouTube link. | 35% |
| newsletter | websiteUrl | string | Author website. | 41% |
| newsletter | socialLinks | object | Every link on the author profile, by network. | 80% |
| newsletter | email | string | Contact email found on the About page (contact-style mailboxes first). | 27% |
| newsletter | emails | array | Every contact email found on the About page. | 27% |
| newsletter | leaderboardRank | integer | Best leaderboard rank Substack shows for the newsletter. | 84% |
| newsletter | leaderboardCategory | string | Category of that leaderboard rank. | 84% |
| newsletter | rank | integer | Position in the list this row came from (1 = top). | 100% |
| newsletter | boardType | string | List the row came from: paid, rising, top, topPaid, topFree. | 100% |
| newsletter | category | string | Category of the list the row came from, else the newsletter's leaderboard category. | 100% |
| newsletter | contributors | array | Writers and admins: name, handle, role, owner flag, bio, photo. | 99% |
| newsletter | hasPodcast | boolean | Publishes a podcast. | 100% |
| post | postId | integer | Substack post id. | 100% |
| post | title | string | Post title. | 100% |
| post | subtitle | string | Post subtitle. | 100% |
| post | url | string | Link to the newsletter (custom domain when it has one), the post, or the comment. | 100% |
| post | publishedAt | string | When the post or comment was published. | 100% |
| post | audience | string | Who can read it: everyone, only_paid, founding, only_free. | 100% |
| post | postType | string | newsletter, podcast, thread or video. | 100% |
| post | wordCount | integer | Words in the post. | 100% |
| post | reactionCount | integer | Likes. | 100% |
| post | commentCount | integer | Comments. | 100% |
| post | restacks | integer | Restacks (shares on Substack). | 100% |
| post | authorName | string | Author name. | 98% |
| post | authors | array | Every byline: id, name, handle, bio, photo, guest flag. | 98% |
| post | publicationName | string | Newsletter the post or comment belongs to. | 100% |
| post | bodyText | string | Full post text (free posts). | 76% |
| post | bodyHtml | string | Full post HTML (free posts). | 76% |
| post | previousPostSlug | string | Slug of the previous post. | 76% |
| comment | commentId | integer | Substack comment id. | 100% |
| comment | postTitle | string | Title of that post. | 100% |
| comment | parentId | integer | Id of the comment this one replies to (null for a top-level comment). | 72% |
| comment | depth | integer | 0 for a top-level comment, 1 for a reply, and so on. | 100% |
| comment | body | string | Comment text. | 99% |
| comment | publishedAt | string | When the post or comment was published. | 100% |
| comment | authorName | string | Author name. | 99% |
| comment | authorHandle | string | Author Substack handle. | 97% |
| comment | reactionCount | integer | Likes. | 100% |
| comment | childrenCount | integer | Direct replies. | 100% |
| comment | commentUrl | string | Link to the comment. | 100% |
Filled = share of rows with a value on real runs (2026-10-28): newsletters from the 100 Technology Bestsellers, posts from 176 Astral Codex Ten posts (paid posts carry no body), comments from 9,080 Astral Codex Ten comments. Every field is listed with its description in the Output tab's dataset schema (131 fields).
Use cases
- ๐ค Newsletter sponsorship and partnerships: ranked lists of newsletters by category with subscriber counts, prices and the author's contact links.
- ๐ Creator-economy research: paid tiers and prices, subscriber bands and posting rates across the leaderboards over time.
- ๐ Media monitoring: new posts from a watch list of newsletters on a schedule, with likes and comments.
- ๐ง AI and RAG datasets: full text of free posts in Markdown or plain text.
- ๐ฌ Audience research: comment threads with commenter, likes and replies.
- ๐งญ Competitor tracking: a rival newsletter's subscriber count, prices and post count, flagged when they change.
How much does it cost to scrape Substack?
Pay per row, no start fee. Rows removed by your filters, duplicates and unchanged rows in monitor mode are not charged.
| Row | Price per 1,000 |
|---|---|
| Newsletter | $0.45 |
| Post (full text of free posts included) | $0.27 |
| Comment | $0.18 |
| Example run | Rows | Cost |
|---|---|---|
| 10 newsletters | 10 | $0.0045 |
| 100 posts of one newsletter + its newsletter row | 101 | $0.02745 |
| 100 Technology Bestsellers | 100 | $0.045 |
| 1,000 posts | 1,000 | $0.27 |
| 1,000 comments | 1,000 | $0.18 |
Set Maximum cost per run in the run options to cap any run; the actor stops cleanly at the limit.
Integrations, API, scheduling & MCP
- Schedules: run Substack Scraper daily with monitor mode on to collect only new posts and changed newsletters.
- Webhooks: get a call when a run finishes and pull the dataset.
- Make, Zapier, n8n, Google Sheets, Slack: connect through Apify's integrations.
- API: start runs and read results from Python or JavaScript with the Apify client.
- MCP: AI agents can call the actor through the Apify MCP server.
More scrapers from TopApi
- ๐ฆ X Profile Scraper: X (Twitter) profiles, followers and bios
- ๐บ YouTube Channel Email Scraper: creator emails and socials
- ๐ Social Blade Scraper: creator stats, ranks and history
- ๐ฎ Twitch Scraper: channels, live streams, VODs and clips
- ๐ธ Instagram Email Scraper: emails, phones and websites from profiles
All TopApi actors: apify.com/TopApi
Limits & empty runs
- Substack rate-limits each address. The actor paces itself and, when Apify's shared address keeps drawing refusals, moves to a datacenter route. Measured: 100 posts with full text in 84 s, 9,080 comments in 16 s, 25 leaderboard newsletters with details in 30 s, 100 in 4.8-5.7 minutes, 1,000 posts with full text in 16.5 minutes.
- Substack's newsletter search answers empty to about half of requests, and to every request from Apify's addresses; the actor then uses the newsletters behind the keyword's matching posts (
foundVia). - Paid posts: metadata and the public teaser line only.
- Hidden subscriber counts are
null, never 0 (94% of the Technology Bestsellers show one). About-page emails were found for 27% of them. - Leaderboards hold 100 newsletters; Top lists up to 525.
- A free post whose full text Substack refuses is left out, not charged, and listed in the run summary. A run that finds nothing says why and charges nothing.
FAQ
How much does Substack Scraper cost?
$0.45 per 1,000 newsletters, $0.27 per 1,000 posts and $0.18 per 1,000 comments, with no start fee. The full text of free posts is included in the post price.
How many results can Substack Scraper return?
Every post in a newsletter's archive, up to 100 newsletters per leaderboard, up to 525 per category Top list, and as many search results as Substack lists. maxItems caps a run.
Can Substack Scraper find newsletter emails and socials?
Yes. Each newsletter row carries the contact emails written on its About page and the links on the author's Substack profile (X, LinkedIn, Instagram, YouTube, TikTok, website).
Does Substack Scraper get paid posts?
It returns paid posts' metadata (title, date, likes, comments, word count) and Substack's public teaser line. The paid body is not read.
Can I monitor newsletters on a schedule?
Yes. Turn on monitor mode and schedule the actor; each run returns only new posts and comments and newsletters whose subscribers, prices or post count changed.
Can I use Substack Scraper with the Apify API or Python?
Yes. Start runs and read datasets with the Apify client for Python or JavaScript, or plain HTTP.
Can AI agents use Substack Scraper through MCP?
Yes, through the Apify MCP server.
Do I need a Substack account, login or API key?
No. The actor reads public Substack data only.
Why did my Substack Scraper run return no results?
The run's status message says why: the link is not a Substack newsletter, the filters removed everything, or nothing is new in monitor mode. Nothing is charged for an empty run.
Your feedback
Found a bug or need a field? Open an issue in the Issues tab.