Substack Scraper - Publication Posts, Reactions & Paywall
Pricing
from $0.25 / 1,000 posts
Substack Scraper - Publication Posts, Reactions & Paywall
Substack scraper for the posts in a publication's archive, one row each: title, link, date, authors, word count, comments, reactions, restacks and whether it sits behind the paywall. No account or cookies. No article text, which the archive does not publish. $0.26 per 1,000 posts.
Pricing
from $0.25 / 1,000 posts
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Give it a Substack handle and get the publication's archive back, one row per post: title, link,
date, author, word count, comments, reactions, restacks, and whether the post sits behind the
paywall. A handle like astralcodexten is enough.
Read this before you buy: no row carries the article text. A publication's public archive does
not publish post bodies, for free posts either, so there is nothing to hand you. What you do get is
audience, the real free-or-paid flag, and Substack's own short preview on roughly half of
publications.
| Input | Substack handles or domains, up to 20 per run |
| Output | One row per post: title, link, date, authors, word count, comments, reactions, restacks and the paywall flag |
| Ceiling | 2,000 posts per publication, 20 publications per run |
| Speed | Roughly 800 to 950 posts a minute, measured on runs of 400 and 1,474 posts |
| Account needed | None, no cookies, no browser |
| Price | $0.26 per 1,000 posts on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 19,000 |
🔍 What Substack Publication Scraper does
It reads a publication's own archive and walks it to the depth you ask for. A handle on its own is enough. If the publication moved onto its own domain, give that domain: a publication on its own domain only answers there, and its old substack.com address hands back an empty archive rather than an error.
You can point it at 20 publications in one run, and each gets its own post budget, so one prolific newsletter cannot eat the whole run.
A word on what arriving means. Three different wrong answers all come back looking like success: a publication that has moved returns an empty list, one redirects to a profile page, and a site that is not Substack at all serves its own page from the same address. Each of those is caught and turned into an uncharged row that says what to do about it. Nothing is billed for an answer that was not an archive.
📋 What data you get from each Substack post
| What you get | Field |
|---|---|
| The publication, the post title and its subtitle | publication, title, subtitle, description |
| The canonical link, slug and Substack's post id | url, slug, postId |
| When it was published | postDate |
| Free or paid, in Substack's words and as a boolean | audience, isPaywalled |
| Substack's own short preview, when it has one | previewText |
| Word count of the full post | wordCount |
| Comments, reactions and restacks | commentCount, reactionCount, restackCount |
| Every byline | authors |
| Newsletter, podcast, thread and so on | postType |
| Cover image and language | coverImage, language |
▶️ How to scrape a Substack archive
- Open Substack Publication Scraper and click Try for free.
- Put one handle per line into Substack publications.
- Set Posts per publication. Start around 10 while you are looking at the output shape.
- Pick an Order if reverse date order is not what you want.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it from the Apify API.
💰 How much does it cost to scrape Substack?
$0.26 per 1,000 posts on the Free plan. Paid plans pay a little less: $0.258 on Starter, $0.256 on Scale and $0.254 on Business. On the free plan, the $5 Apify gives you each month covers about 19,000 posts.
You pay per post row delivered. Duplicates, the sample row and diagnostic rows are free, and a publication that returns nothing writes a free row instead of posts.
📥 What you give it
{"publications": ["astralcodexten", "www.bigtechnology.com"],"maxPostsPerPublication": 50,"sort": "new"}
| Field | Default | What it is |
|---|---|---|
publications | none | One per line, up to 20. A bare handle works, so does a full address. Give the publication's own domain if it has one. The form opens with astralcodexten and www.bigtechnology.com. |
maxPostsPerPublication | 50 | Posts to take from each publication, 1 to 2,000. A publication with fewer simply returns fewer. This is also your spending cap. |
sort | new | new is the archive in reverse date order, top is the publication's most popular, community puts discussion threads first. |
proxyUrls | none | Optional. Your own servers, one URL per line as http://user:pass@host:port. Leave it empty for a normal run. |
📤 What you get back
A real row from a real run:
{"ok": true,"charged": true,"recordType": "post","publication": "astralcodexten.substack.com","title": "Your Book Review: This Is Going To Hurt","url": "https://www.astralcodexten.com/p/your-book-review-this-is-going-to","postDate": "2026-09-18T20:53:58.344Z","audience": "everyone","isPaywalled": false,"subtitle": "Finalist #9 in the Book Review Contest","description": "Finalist #9 in the Book Review Contest","previewText": null,"wordCount": 12639,"commentCount": 295,"reactionCount": 152,"restackCount": 7,"authors": "Scott Alexander","postType": "newsletter","slug": "your-book-review-this-is-going-to","postId": "216363681","coverImage": "https://substack-post-media.s3.amazonaws.com/public/images/916daf3c-...png","language": "en","scrapedAt": "2026-09-21T02:09:44.003Z"}
| Field | How to read it |
|---|---|
postId | Substack's own id. Stable, so use it to dedupe across runs. |
audience | everyone or only_paid, straight from Substack. isPaywalled is that same fact as a boolean. |
previewText | Present on some publications and null on others, as above. It is not the article. |
wordCount | Substack's count for the full post, including the part you cannot read. |
authors | Every byline joined with commas, or null when the post has none. |
restackCount | Substack restacks, its own share count. |
url | The canonical link, which is the publication's own domain when it has one. |
🧾 Reading the output
Three kinds of row can land in your dataset, and recordType tells them apart.
| Row | How to spot it | Billed |
|---|---|---|
| A post | recordType: "post" | yes |
| The sample row | _sample: true, recordType: "sample" | no |
| A diagnostic | _diagnostic: true and an errorCode | no |
The charged field is a label on the row, not a receipt. It is stamped when the row is built,
before billing happens, so treat it as the same signal as recordType: it separates real posts from
the sample and diagnostic rows, nothing more.
| Code | What it means |
|---|---|
NOT_FOUND | No Substack publication answers at that address. Check the spelling, or use the publication's own domain. |
NO_RESULTS | The address answered but returned no posts, which is what a publication that has moved to its own domain does. |
TIME_BUDGET | The run ran out of time before reaching that publication. Everything already delivered is complete. |
RATE_LIMITED | Substack asked the run to slow down and it gave up on that item. Re-run it. |
NOT_SERVED | This post was not served this run. Re-run it later. Runs before 13 October 2026 wrote BLOCKED here. |
SERVER_ERROR | Substack returned a server error. Usually passes on its own. |
NETWORK | Substack was unreachable. Re-run it. |
PROXY_INPUT_ADJUSTED | A connection setting in your input was not usable, so the run used its own. |
CHARGE_ERROR | Billing could not be recorded for some rows. Rare, and worth telling us about. |
One bad publication never stops the others, and a diagnostic row never fails the run. The one exception is an unexpected error on our side before anything came back: that run ends as failed, with an UNEXPECTED_ERROR row.
💡 What people use it for
- Tracking which posts a newsletter puts behind the paywall and which it leaves open, using
audienceover time. - Ranking a publication's back catalogue by
reactionCountorcommentCountto see what actually landed. - Pulling 20 newsletters in one field into a single sheet to compare posting cadence.
- Watching a competitor's publishing rhythm on a schedule, deduped on
postId.
🚧 What it does not do
- No article text. The archive does not publish post bodies.
previewTextis Substack's own snippet, and plenty of publications never fill it. - No subscriber counts, no revenue, no email list size. None of that is public.
- No comments themselves, only how many there are.
- A publication on its own domain only answers on that domain. Its old substack.com address returns an empty archive, and you will get a row saying so.
topandcommunityare Substack's own orderings, so asking for 20 of them gives you the 20 it serves first.- No Substack Notes, no podcasts beyond the post record, and no cross-publication search.
- Rows are a snapshot. Reaction and comment counts move, and
scrapedAtrecords when they were read. - Up to 20 publications per run. Split a longer list across runs.
- It is not an official Substack tool. Dami's Studio is independent and is not affiliated with or endorsed by Substack, or by any other company named on this page.
🧭 Which news scraper do you need?
| If you want | Use |
|---|---|
| Posts in a Substack publication's archive | This one |
| DEV.to articles by tag or author | DEV.to Scraper |
| News articles by keyword, with the publisher's real link | Google News Scraper |
| World news by keyword, in 65+ languages | GDELT News Scraper |
| Hacker News stories and comments | Hacker News Scraper |
❓ Questions people ask
Do I need a Substack account?
No. No account, no cookies, no browser.
Can I get the post text?
No. Substack's public archive does not carry post bodies, for free posts or paid ones.
How do I know if a Substack post is paywalled?
isPaywalled, or audience if you want Substack's own wording. Every row has it.
What do I put in for a publication on its own domain?
That domain. www.bigtechnology.com, not the old substack.com address, which answers empty.
Can I call it from code or connect it to an AI assistant?
The API tab has code for Python, JavaScript
and the CLI. MCP clients like Claude and ChatGPT use
https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/substack-publication-scraper; coding assistants can
load our skill
file. All
three bill your Apify account at the same price.
Is scraping Substack archives legal?
These are public archive pages. Rows carry author names, which is personal data under GDPR, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a sensible starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the run ID and the publication you used. The
errorCode on the diagnostic row usually names the problem on its own.