Substack Scraper - Posts, Subscribers & Paid Plan Prices
Pricing
$0.70 / 1,000 post rows
Substack Scraper - Posts, Subscribers & Paid Plan Prices
Scrape any Substack newsletter archive: post title, subtitle, date, full text, paywall state, likes, restacks and comment counts, plus the publication's subscriber size, paid plan prices and bestseller tier. Custom domains supported. No login, one flat price.
Pricing
$0.70 / 1,000 post rows
Rating
0.0
(0)
Developer
Crikit
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Scrape any Substack newsletter and get its full post archive plus the numbers that describe the newsletter itself: how many subscribers it has, what it charges for a paid subscription, whether it is a bestseller, and how each post actually performed. Point it at a publication URL, a custom domain or a bare handle and it returns clean, structured rows ready for a spreadsheet, a database or an LLM pipeline.
No login, no cookies, no API key. One flat price per post returned.
What is Substack Scraper?
Substack Scraper is an Apify Actor that turns a Substack publication into structured data. Give it https://sherwood.substack.com, www.slowboring.com or just sherwood, and every post in the archive comes back as a row with its title, subtitle, publish date, word count, paywall state, likes, restacks and comment count, alongside the publication's subscriber size and paid plan prices.
- Walk the complete archive, not the first page. Substack serves a short first page (23 rows) and then full 50-row pages after it. Scrapers that stop on a short page truncate an archive of hundreds down to 23 posts. This one advances by the exact row count Substack returned and stops only when a page comes back genuinely empty, so a 900-post archive returns 900 posts.
- Get newsletter economics, not just post metadata. Every row carries the publication's subscriber count, its monthly, annual and founding plan prices in dollars, its bestseller tier and its paid-subscriber band. That is the data you need to rank newsletters, size a sponsorship, or research a market.
- Search inside a publication before you pay for it. A keyword is passed to Substack's own archive search, so only matching posts are fetched and billed. Twenty posts about one topic costs twenty rows, not the whole archive.
- Custom domains work.
www.thefp.comandwww.slowboring.comare Substack publications on their own domains and both are scraped exactly like a*.substack.comhost. - Filter before you are charged. Post type, free versus paywalled and a publish-date window are applied before rows are written, so you only pay for posts you actually asked for.
- Full article text on demand. Turn on the body option to get each post's complete text, as plain text or as HTML with links and images intact.
What data does Substack Scraper extract?
Every row is one post, stamped with its publication's own stats.
Post fields
| Field | Description |
|---|---|
title, subtitle, description | Post headline, deck and meta description |
postUrl, slug, postId | Canonical URL (custom domain aware), slug and numeric id |
postDate | Publish timestamp, ISO 8601 |
postType | newsletter, podcast, thread or video |
audience, isPaywalled, isFreeToRead | Raw Substack audience value plus plain booleans |
wordCount | Word count as Substack counts it |
reactionCount, reactions | Total likes plus the emoji breakdown |
restackCount | Times the post was restacked on Substack Notes |
commentCount | Comment count |
authorName, authorHandle, authors | Bylines, including multi-author posts, with profile URLs |
excerpt | Substack's own truncated preview text |
bodyText, bodyHtml | Full article text and HTML, when the body options are on |
coverImageUrl | Post cover image |
podcastUrl, podcastDurationSeconds, hasVoiceover | Audio fields for podcast posts and voiceovers |
sectionName, language, isGeoblocked | Section, language and geoblock flag |
Newsletter fields
| Field | Description |
|---|---|
publicationName, publicationUrl, publicationHost | Newsletter identity, including the custom domain |
publicationSubdomain, publicationCustomDomain, publicationId | Both hostnames and the numeric publication id |
subscriberCount, subscriberCountLabel | Exact subscriber count where Substack publishes it, plus the displayed band such as 200K+ |
paidSubscriberLabel | Substack's own paid-subscriber band, such as Tens of thousands of paid subscribers |
monthlyPriceUsd, annualPriceUsd, foundingPriceUsd | Live paid plan prices in dollars |
acceptsPayments, isInviteOnly | Whether the newsletter sells subscriptions and whether it is invite only |
bestsellerTier | Substack's bestseller badge tier |
publicationAuthorName, publicationAuthorHandle | The newsletter's owner |
publicationLaunchedAt, publicationFirstPostAt | When the newsletter was created and first published |
hasPodcast, publicationLanguage, publicationLogoUrl, publicationDescription | Podcast flag, language, logo and tagline |
scrapedAt, sourceUrl, resultPosition, sortedBy, searchQuery | Provenance for every row |
How to scrape Substack posts
- Open the Actor and paste one or more publications into Publications. A URL (
https://sherwood.substack.com), a custom domain (www.slowboring.com), a handle (sherwood) or any post URL all work. - Set Max results. Use
0to walk every publication's entire archive. - Optional: type a keyword into Search within the publication to fetch only matching posts.
- Optional: choose Sort by
Top posts firstto get the publication's best performing posts instead of the newest. - Optional: narrow by Post type, Paywall, Published after and Published before.
- Optional: turn on Include full post text or Include full post HTML for complete articles.
- Click Start and export the results as JSON, CSV or Excel, or pull them from the API.
Input example
{"publications": ["www.slowboring.com", "sherwood"],"maxItems": 500,"maxPostsPerPublication": 250,"sortBy": "new","postType": "newsletter","audience": "free","publishedAfter": "2026-01-01","includeBodyText": true,"includePublicationStats": true}
Output example
{"postId": 214556400,"postUrl": "https://www.slowboring.com/p/the-case-for-more-housing","title": "The case for more housing","subtitle": "Supply matters more than the discourse admits","postDate": "2026-09-10T10:02:11.000Z","postType": "newsletter","audience": "everyone","isPaywalled": false,"isFreeToRead": true,"wordCount": 2761,"reactionCount": 412,"reactions": { "❤": 412 },"restackCount": 37,"commentCount": 289,"authorName": "Matthew Yglesias","authorHandle": "matthewyglesias","publicationName": "Slow Boring","publicationHost": "www.slowboring.com","subscriberCount": 200000,"subscriberCountLabel": "200K+","paidSubscriberLabel": "Tens of thousands of paid subscribers","monthlyPriceUsd": 9,"annualPriceUsd": 80,"foundingPriceUsd": 500,"bestsellerTier": 10000,"hasPodcast": true,"publicationLaunchedAt": "2020-11-05T16:20:32.177Z","scrapedAt": "2026-09-10T13:58:04.221Z"}
How much does it cost to scrape Substack?
One flat price of $0.70 per 1,000 posts. There is no start fee, no per-publication fee, no separate charge for the newsletter stats, and no surcharge for full article text.
| Posts returned | Cost |
|---|---|
| 100 | $0.07 |
| 1,000 | $0.70 |
| 10,000 | $7.00 |
| 100,000 | $70.00 |
Posts removed by a filter are never charged, and neither is a publication that turns out to be unreachable.
Two things to compare against when you price this out. Most Substack scrapers charge more per post the moment you ask for the article body, typically around twice the metadata rate, and several add a per-run start fee on top. Here the body is included in the same flat $0.70 per 1,000, and there is no start fee, so a 5,000-post run with full text costs $3.50 and nothing else.
What can you use Substack data for?
- Find newsletters to sponsor. Rank publications in a niche by subscriber band, paid tier and posting cadence, then read the engagement on their recent posts.
- Track a competitor's newsletter. Watch their publishing frequency, which posts they put behind the paywall, and what their audience actually reacts to.
- Research newsletter pricing. Pull monthly, annual and founding plan prices across a whole category to see where your own price should sit.
- Build a content dataset for an LLM. Export full article text with the body option and feed a retrieval index or a fine-tuning corpus.
- Monitor a topic across publications. Run a keyword search over dozens of newsletters and get every post that mentions it.
- Analyse what performs. Compare likes, restacks and comments against word count, post type and paywall state.
- Source writers and experts. Author names, handles and profile URLs come with every post.
Tips and limits
- Substack caps one archive page at 50 posts. The Actor pages through automatically, so this only affects speed, not completeness.
- The archive's first page returns fewer rows than the ones after it. That is normal Substack behaviour and is handled; do not read a 23-row first page as the end of an archive.
subscriberCountis only populated when a publication chooses to display an exact number.subscriberCountLabelcarries the band Substack shows publicly, and it is far more widely available.- Paywalled posts return their title, metrics and preview text. Their full body is not readable without a paid subscription, so
bodyTextis the public portion. substack.com/@someoneis a reader profile, not a publication. Use the publication's own host instead.- Turning on full bodies adds one request per post, so a large archive takes noticeably longer.
Integrations
Connect Substack Scraper to Google Sheets, Airtable, Slack, Zapier, Make, GitHub or almost any HTTP API through Apify integrations, or trigger runs and read results from the Apify API and the JavaScript and Python clients. Schedule it daily to keep a newsletter dataset current.
Related Actors
- Google News Scraper for headlines across publishers
- YouTube Video Search Scraper for video content in the same niche
- Bluesky Profile and Posts Scraper for social conversation around a newsletter
- Telegram Channel Posts Scraper for channel-based publishing
Substack Scraper FAQ
Is scraping Substack legal?
Substack Scraper reads only pages and API responses that Substack serves publicly to any visitor, with no login and no cookies. Collecting public data is broadly lawful, and courts in the United States have repeatedly declined to treat scraping public web pages as unauthorised access. You are responsible for how you use what you collect: respect copyright in the article text, and if you handle personal data such as author names, comply with GDPR, CCPA and the other rules that apply to you. If in doubt, take legal advice for your specific use case.
Do I need a Substack account or a paid subscription?
No. The Actor never logs in and never asks for a cookie. It sees exactly what an anonymous visitor sees, which includes every post's metadata and metrics, and the public part of paywalled posts.
Can it scrape the full text of paywalled posts?
No. Paid-only content is not served to anonymous readers, so the Actor returns the post's title, date, metrics and public preview and leaves the paid body out. Everything a logged-out reader can see is returned.
How many posts can it return from one publication?
The whole archive. Set Max results to 0 and the Actor pages through every post the publication has ever published, in order, without gaps.
Does it work on newsletters with their own domain?
Yes. Publications on custom domains such as www.thefp.com and www.slowboring.com are handled identically to *.substack.com hosts, and both hostnames are reported on every row.
How do I get only posts about one topic?
Put a keyword in Search within the publication. Substack filters the archive server side, so unmatched posts are never fetched and never charged.
How much does it cost?
$0.70 per 1,000 posts, flat, with no start fee and no extra charge for full article text. A 250-post archive costs about 18 cents.
Support
Found a publication that does not scrape correctly, or a field that comes back empty when it should not? Open an issue on the Actor's Issues tab with the publication URL and the input you used, and it will be looked at.