Substack Newsletter Scraper — Posts, Reactions & Authors avatar

Substack Newsletter Scraper — Posts, Reactions & Authors

Pricing

$3.00 / 1,000 post delivereds

Go to Apify Store
Substack Newsletter Scraper — Posts, Reactions & Authors

Substack Newsletter Scraper — Posts, Reactions & Authors

Scrape any Substack newsletter's posts from its public API: title, URL, publish date, free/paid, word count, reactions, comments, restacks, tags and authors — with optional full body text. No API key, no login, no browser.

Pricing

$3.00 / 1,000 post delivereds

Rating

0.0

(0)

Developer

Berkan Kaplan

Berkan Kaplan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Categories

Share

Substack Newsletter Scraper — Posts, Reactions & Authors 🚀

foXLabs creator & content data: Bluesky · Product Hunt · Y Combinator

🎉 Scrape any Substack newsletter's posts straight from its public API — one clean row per post with title, URL, publish date, free/paid, word count, reactions, comments, restacks, tags and authors, plus optional full body text. No API key, no login, no browser.

🔍 What is the Substack Newsletter Scraper — and when should you use it?

Give this Actor a list of newsletters and it returns their posts as structured data — built for content & competitive intelligence (what a newsletter publishes and how it performs), creator lead-gen (the authors), and topic/trend research.

Use it when you need: a newsletter's posts with engagement (reactions/comments/restacks); to see what's free vs paid; or the authors and tags behind a publication.

Use something else when: you need subscriber counts (behind Substack's login — not available); other creator sources → Bluesky, Product Hunt.

🤖 Use with AI agents

Already on the Apify MCP server? Ask for this Actor by name: foxlabs/substack-newsletter-data.

Your agent can pay for its own runs. This Actor is pay-per-event with agentic payments, so an agent can discover it, run it and settle the bill over x402 (USDC on Base) or Skyfire — no Apify account or API token of its own. Billing is per delivered post, never for errors.

Otherwise paste this into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

I want Substack newsletter posts using the Apify Actor
`foxlabs/substack-newsletter-data`.
Input: `newsletters` is a list of handles/URLs; `maxPostsPerNewsletter` caps rows; `postedAfter`
filters by date; `includeBody` adds full text. Each row has title, postDate, audience (free/paid),
reactionCount, commentCount, restacks, authors and tags.
Start with:
{ "newsletters": ["bariweiss", "https://www.lennysnewsletter.com"], "maxPostsPerNewsletter": 20 }
Ask me which newsletters to track, run the Actor, then summarise the posts by engagement.

The machine-readable API, MCP config and OpenAPI definition live at apify.com/foxlabs/substack-newsletter-data.md.

📋 Overview

Everything you need to turn a Substack newsletter into clean, structured data — posts, engagement, audience and authors — in one Actor, with no login, cookies or API key.

Why teams pick this Actor:

  • ✅ Engagement, not just text — reactions, comments and restacks per post.
  • 💵 Free vs paid — each post's audience and an isPaid flag show a newsletter's monetisation.
  • ✍️ Authors & tags — the bylines behind each post and its topic tags.
  • 🎯 Honest nulls — a value Substack didn't give is null, never 0; subscriber counts (login-only) are not faked.
  • 💰 Pay only for results — one post event per delivered row; unreachable newsletters return a free error row.
  • 🤖 Agent-ready — MCP + x402 agentic payments.

✨ Features

  • 🔍 Posts by newsletter — handle, .substack.com URL or custom domain; newest first, paginated.
  • 📊 Performance — reactionCount, commentCount, childCommentCount, restacks, wordcount.
  • 💵 Monetisation — audience (everyone / only_paid) + isPaid.
  • ✍️ Attribution — authors, authorHandles, tags.
  • 📝 Optional full text — includeBody adds bodyText (HTML stripped). 🗓️ postedAfter date filter.

🎬 Quick Start

curl -X POST "https://api.apify.com/v2/acts/foxlabs~substack-newsletter-data/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"newsletters": ["bariweiss", "https://www.lennysnewsletter.com"], "maxPostsPerNewsletter": 20}'

🚀 Getting Started (3 steps)

  1. List your newsletters — one per line: a handle, a .substack.com URL or a custom domain.
  2. Set the cap & filters — maxPostsPerNewsletter, postedAfter, includeBody for full text.
  3. Run and export — get a clean dataset as JSON, CSV or Excel.

📥 Input

FieldDefaultWhat it does
newslettersrequiredOne per line: bariweiss, bariweiss.substack.com, or a custom domain (www.lennysnewsletter.com). For a custom domain use the exact host that serves the newsletter.
maxPostsPerNewsletter100Posts per newsletter, newest first.
postedAfter—Keep only posts on/after this date (YYYY-MM-DD).
includeBodyfalseAdd the post's full body as plain text (bodyText).
maxResults0Max posts across all newsletters (0 = no cap).
{ "newsletters": ["bariweiss", "https://www.lennysnewsletter.com"], "maxPostsPerNewsletter": 20 }

📤 Output

One row per post. A value Substack didn't give is null, never 0.

FieldWhat it is
newsletterthe host the post came from
title, subtitle, slug, urlthe post
typenewsletter / podcast / thread
audience, isPaideveryone / only_paid, and a paid flag
postDate, updatedAtpublish and update times
wordcountword count
reactionCount, commentCount, childCommentCount, restacksengagement
authors, authorHandles, tagsbylines and topic tags
coverImage, description, teasermedia and summary
bodyTextfull text (with includeBody)
language, source, scrapedAtmeta
{
"newsletter": "www.lennysnewsletter.com",
"title": "All of the Lenny & Friends Summit talks",
"url": "https://www.lennysnewsletter.com/p/all-of-the-lenny-and-friends-summit",
"type": "newsletter",
"audience": "everyone",
"isPaid": false,
"postDate": "2026-09-29T...",
"wordcount": 1276,
"reactionCount": 287,
"commentCount": 7,
"restacks": 5,
"authors": ["Lenny Rachitsky"],
"tags": [],
"source": "Substack"
}

💼 Use cases

1. Competitive content intelligence — what a rival newsletter publishes and how it performs. Input: competitor newsletters, scheduled. Output: posts + reactions/comments/restacks. Use: benchmark cadence and what resonates.

2. Creator lead-gen — the authors behind newsletters in your niche. Input: a list of newsletters. Output: authors + authorHandles. Use: build an outreach list.

3. Monetisation research — how much a newsletter gates behind paid. Input: the newsletters. Output: audience/isPaid per post. Use: study free-vs-paid strategy.

🔗 Integration

JavaScript / Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('foxlabs/substack-newsletter-data').call({
newsletters: ['bariweiss', 'https://www.lennysnewsletter.com'], maxPostsPerNewsletter: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);

Python

from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('foxlabs/substack-newsletter-data').call(
run_input={'newsletters': ['bariweiss', 'https://www.lennysnewsletter.com'], 'maxPostsPerNewsletter': 20}
)
for item in client.dataset(run.default_dataset_id).iterate_items():
print(item)

Written for apify-client 3 for Python, where call() returns a run object; with version 1 or 2 it returns a dict — write run['defaultDatasetId'] there.

Automation (n8n / Zapier / Make): schedule → HTTP request to the Actor API with your newsletters → handle the JSON dataset → push to a sheet, CRM or dashboard.

📊 Pricing

Pay per event, one event per delivered row: post. An unreachable newsletter returns a free error row — not charged. View current pricing.

❓ FAQ

Do I need a Substack account or API key? No. It reads each newsletter's own public post API — no key, no login, no browser.

Can I get subscriber counts? No — those are behind Substack's login. This Actor returns posts, engagement, audience and authors, never a fabricated subscriber number.

How do I enter a custom-domain newsletter? Use the exact host that serves it (often www. or the .substack.com subdomain). If a host doesn't serve the API you get a clear error row.

Can I get the full article text? Yes — turn on includeBody (HTML stripped to plain text). Paid posts may be truncated behind the paywall.

Can I export to CSV / Excel / JSON? Yes — directly from the Apify dataset.

🐛 Troubleshooting

  • A newsletter returns an error row — the host doesn't serve the public post API; use the exact Substack host (often www. or {handle}.substack.com).
  • Fewer posts than expected — maxPostsPerNewsletter/postedAfter capped them, or the newsletter has that many.
  • Empty tags — not every post is tagged; returned only when present.
  • No subscriber count — it's login-only; not provided (never faked).

⚠️ Trademark

Independent, third-party tool. Not affiliated with, endorsed by or connected to Substack Inc. "Substack" and related marks belong to their owners and are used here for identification only.

This reads each newsletter's own public post API — the same endpoint the site itself calls. Posts carry author names (published publicly); personal data is protected by the GDPR and similar laws, so only process it with a legitimate basis. See Apify's blog post on the legality of web scraping.

🤝 Support & contact

Changelog

0.1.0 — 2026-10-12

  • Initial release: structured posts from any Substack newsletter via its public API — title, date, free/paid, word count, reactions, comments, restacks, tags, authors, optional full body; postedAfter filter; pay-per-event (post); pure HTTP, no key, no browser.