Substack Scraper — Posts, Likes, Comments, Full Text, No Login
Pricing
from $0.70 / 1,000 posts
Substack Scraper — Posts, Likes, Comments, Full Text, No Login
Scrape posts from any Substack publication, including custom domains: title, date, likes, comments, restacks, authors, paid/free flag, optional full text — newest first, with date filter and CSV/JSON export. No login.
Pricing
from $0.70 / 1,000 posts
Rating
0.0
(0)
Developer
Chorelet
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
10 days ago
Last modified
Categories
Share
Get the posts of any Substack publication — on *.substack.com or a custom domain — as JSON, CSV or Excel, or straight into your own tools via API. No login, no cookies: it reads the same public archive that powers the publication's own "Archive" page.
Paste publication URLs, subdomains or author handles, set how many posts you need (or a date like "90 days"), optionally turn on Include post content to get the text of every post.
Why this Actor
- Works with custom domains and moved subdomains, and with @author handles
- Likes, comments, restacks, word count, paid/free flag and authors for every post
- Optional full text of free posts — and the public preview of paid ones, exactly as an anonymous reader sees it
- Public archive API only: no login, nothing scraped from HTML
- Checked every day by an automated run; fixed within 24 hours when Substack changes its API
Sample output
One item of the dataset (long values shortened):
{"publication": "www.astralcodexten.com","publicationName": "Astral Codex Ten","publicationAuthor": "Scott Alexander","title": "Your Book Review: This Is Going To Hurt","subtitle": "Finalist #9 in the Book Review Contest","url": "https://www.astralcodexten.com/p/your-book-review-this-is-going-to","date": "2026-09-18T20:53:58.344Z","type": "newsletter","isPaid": false,"wordCount": 12639,"reactionCount": 144,"commentCount": 295,"restacks": 7,"authors": [{"name": "Scott Alexander","handle": "astralcodexten","url": "https://substack.com/@astralcodexten"}]}
What you get
| Field | Description |
|---|---|
publication, publicationName, publicationAuthor | Host (e.g. www.lennysnewsletter.com), name and author of the publication |
id, slug, url, title, subtitle, description | The post and its listing summary |
date, type | Publication time (UTC); newsletter, podcast, thread or video |
audience, isPaid, wordCount | Free vs paywalled, length |
reactions, reactionCount, commentCount, restacks | Engagement as shown publicly |
authors, tags, section, coverImage | Bylines with handles, tags, section |
podcastUrl, podcastDuration | For podcast posts |
previewText | First lines of the post as Substack lists them |
bodyText, bodyHtml | Only with Include post content: full text of free posts; for paid posts the public preview an anonymous reader sees |
Posts come newest first per publication. A per-publication summary (name, author, posts fetched, errors) is saved to the key-value store as SUMMARY.
Input
- Publications — any mix of
lenny,astralcodexten.substack.com,https://www.astralcodexten.com, a post URL, or an author handle@lenny/https://substack.com/@lenny(resolved to the author's primary publication). - Max posts per publication — newest first, read in pages of 25.
- Only posts newer than —
2026-01-31or7 days/2 weeks/3 months/1 year. Scraping stops at the first older post, so a daily run with1 daycosts almost nothing. - Include post content — one extra request per post, charged as a separate event.
- Proxy — off by default.
Limits and notes
- Paywalled posts return exactly what Substack shows to non-subscribers: metadata plus the public preview. The Actor cannot and does not bypass paywalls.
- Comments and Notes are not included.
- A subdomain that was moved to a custom domain (e.g.
lenny.substack.com) is followed automatically. If a subdomain turns out to be a personal profile rather than a publication, the run says so and continues with the rest. - Public data only; the Actor stores nothing beyond the dataset of your run.
Input example
{"publications": ["lennysnewsletter","https://www.astralcodexten.com"],"maxPostsPerPublication": 50,"postedAfter": "90 days","includeContent": false}
How much does it cost?
Pay per post — no subscription, no minimum, no charge for platform usage.
| Volume | Price |
|---|---|
| 1,000 posts | $1.00 (+ $1.00 with content) |
| 10,000 posts | $10.00 (+ $10.00 with content) |
| 100,000 posts | $100.00 (+ $100.00 with content) |
The Apify free plan includes $5 of usage every month — about 5,000 posts with this Actor, no card needed. Nothing else is charged: platform usage is included in the price, and Apify Bronze, Silver and Gold subscribers get 10%, 20% and 30% off these prices.
Use it from code, n8n, Make, Zapier or an AI agent
Run the Actor and download the dataset in one call (JSON by default; add &format=csv or xlsx):
curl -X POST "https://api.apify.com/v2/acts/chorelet~substack-posts-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"publications": ["lennysnewsletter", "https://www.astralcodexten.com"], "maxPostsPerPublication": 50, "postedAfter": "90 days", "includeContent": false}'
Python:
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("chorelet/substack-posts-scraper").call(run_input={"publications": ["lennysnewsletter", "https://www.astralcodexten.com"], "maxPostsPerPublication": 50, "postedAfter": "90 days", "includeContent": false})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
- n8n, Make, Zapier — use the Apify node/module: run the Actor, then "get dataset items".
- Google Sheets, Slack, webhooks — add an integration on the run's Integrations tab.
- AI agents — the Actor is available as a tool through the Apify MCP server; the dataset schema describes every field for the model.
- Schedules — run it hourly, daily or weekly from the Schedules tab.
FAQ
Does it work for publications on their own domain?
Yes. Paste the domain (https://www.astralcodexten.com), the old subdomain or the author's @handle — all are resolved automatically.
Can it read paywalled posts?
No. For paid posts you get the metadata and the public preview that Substack shows to non-subscribers — nothing more.
How do I get the full text?
Turn on includeContent. Free posts come in full (bodyText, bodyHtml); the Actor fetches them four at a time.
How far back can I go?
The whole archive, 25 posts per page. Use postedAfter (90 days) or maxPostsPerPublication to limit it.
What does a run cost?
$1 per 1,000 posts, plus $1 per 1,000 posts when full content is requested. The free plan's $5 a month covers about 5,000 posts.
Support
Questions, missing fields or a source that changed? Open an issue on the Issues tab or write to support@chorelet.app — problems are usually fixed within a day, and the Actor is checked every morning by an automated test run. If the Actor saved you time, a short review on its Store page helps other people find it.