Substack Scraper: Free-Post Full Text, Likes & Comments avatar

Substack Scraper: Free-Post Full Text, Likes & Comments

Pricing

Pay per event

Go to Apify Store
Substack Scraper: Free-Post Full Text, Likes & Comments

Substack Scraper: Free-Post Full Text, Likes & Comments

Get the full text of every free Substack post, along with likes, comment counts, and dates, so newsletters are ready for analysis or sponsor scouting. A test run returned 60 posts.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Almandine Data

Almandine Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Categories

Security

Limited permissions

Share

Substack Scraper: Posts, Likes, Comments & Free Post Text

Scrape any Substack newsletter archive: post title, date, authors, likes, comments, restacks, word count, paywall flag, and free post text. Export JSON/CSV.

What it does

Reads each publication's public archive and returns posts newest-first with engagement metrics. Optional plain text of free posts. Export clean, deduplicated data as JSON, CSV, Excel, XML, or RSS, or connect directly via the Apify REST API, Python/JavaScript SDKs, CLI, MCP Server, n8n, Make, or Zapier — with no login, cookies, or browser overhead.

Use cases

  • Newsletter Sponsorship & Media Buying: Rank Substack publications by average likes, comments, restacks, posting frequency, and free vs. paywalled ratio.
  • Creator & Journalist Research: Export complete post archives across multiple Substack subdomains or custom domains in seconds without login.
  • AI / RAG Content Datasets: Extract clean plain-text bodies (includeContent: true) from free public Substack articles for research and LLM pipelines.
  • Scheduled Topic Monitoring: Run daily with onlyNew: true to ingest new newsletter issues as soon as they publish.

Why use this scraper?

FeatureThis ActorGeneric Browser / HTML Scrapers
ArchitectureDirect structured API / JSON / feed requests (curl_cffi)Heavy headless browser automation
Speed & reliability2–25 seconds for 50–200 itemsMinutes of high compute burn
Pricing modelPay per result ($0.00 actor-start fee)Monthly rental or high CU overhead
Error handlingFailed inputs logged in ERRORS key-value record and never chargedBills compute time even on failures

Input parameters

  • Publications (publications, array): Substack subdomains (e.g. 'astralcodexten'), *.substack.com URLs or custom-domain Substack URLs.
  • Max posts per publication (maxPostsPerPublication, integer): Newest posts first. You are charged per post returned.
  • Published after (YYYY-MM-DD) (publishedAfter, string): Optional. Stop at posts older than this date.
  • Include free post text (includeContent, boolean): Adds the plain-text body of free posts (higher per-post price). Paywalled bodies are never returned.
  • Only new posts (onlyNew, boolean): On scheduled runs, return only posts not seen in earlier runs.
  • Delay between requests (delaySeconds, number): Polite pause between requests (default 0.7).

Example input

{
"publications": [
"astralcodexten",
"https://www.lennysnewsletter.com"
],
"maxPostsPerPublication": 30
}

Output & example output

One dataset row per result. Default table view columns: coverImage, publicationUrl, title, postDate, authors, likes, comments, restacks, wordcount, isPaywalled, url. Full structured JSON is stored in the run's default dataset.

Example output item

{
"publicationUrl": "https://astralcodexten.substack.com",
"publicationId": 89120,
"postId": 212349428,
"url": "https://www.astralcodexten.com/p/your-book-review-the-ghost-in-my",
"title": "Your Book Review: The Ghost In My Brain",
"subtitle": "Finalist #13 in the Book Review Contest",
"type": "newsletter",
"postDate": "2026-10-23T23:45:42.358Z",
"audience": "everyone",
"isPaywalled": false,
"authors": [
"Scott Alexander"
],
"likes": 130,
"comments": 101,
"restacks": 1,
"wordcount": 4187,
"tags": [],
"coverImage": "https://substackcdn.com/image/fetch/$s_!wVWo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F621384df-793b-4ff7-b...",
"description": "Finalist #13 in the Book Review Contest",
"podcastUrl": null,
"scrapedAt": "2026-10-25T04:27:04+00:00"
}

Pricing (Pay-Per-Result)

This Actor uses transparent Pay-Per-Event pricing with a $0.00 actor-start fee:

EventWhat is chargedPrice
post-resultPost scraped (One post with metadata and engagement)$0.002 / result ($2.00 / 1,000 results)
post-with-contentPost scraped with text (One post with metadata plus free-post body text)$0.003 / result ($3.00 / 1,000 results)
apify-actor-startActor start fee$0.00

Concrete pricing math

  • post-result (Post scraped): 1,000 results = $2.00 (50 results = $0.10, 10,000 results = $20.00). Apify's $5.00/month Free Tier covers up to 2,500 results/month at $0.00 out-of-pocket.
  • post-with-content (Post scraped with text): 1,000 results = $3.00 (50 results = $0.15, 10,000 results = $30.00). Apify's $5.00/month Free Tier covers up to 1,666 results/month at $0.00 out-of-pocket.
  • Empty runs (0 results) & skipped duplicates (onlyNew / onlyChanged): $0.00.

Data and compliance

Free content only: paywalled post bodies are never returned. No subscriber data. Requests are rate-limited and routed through Apify Proxy. Per-input errors are recorded in the run's ERRORS key-value record and are never charged.

FAQ

Do I need an account, login, or API key?
No. This Actor queries public endpoints directly and requires zero credentials.

What happens if I start a run with empty {} input via API or CLI?
Every required input defines both prefill and default values in .actor/input_schema.json, so an empty {} run automatically returns 50+ live records out of the box.