Substack Comments Scraper avatar

Substack Comments Scraper

Pricing

from $0.15 / 1,000 comments

Go to Apify Store
Substack Comments Scraper

Substack Comments Scraper

Public comments and replies under Substack posts with the commenter's name and handle, date, likes, reply count and thread depth. Give post links or newsletter names, and schedule the new-only mode to get only the comments added since the last run.

Pricing

from $0.15 / 1,000 comments

Rating

0.0

(0)

Developer

deriverge s.r.o.

deriverge s.r.o.

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Substack Comments Scraper returns the public comments under Substack posts, one row per comment or reply: the commenter's display name and handle, the time, the text, likes, the number of replies and the comment's place in the thread. Paste post links into Post links, or name newsletters to read the comments under their newest posts, and click Start. Substack shows comments under paid posts to subscribers only, so such posts return no rows. It costs $0.30 per 1,000 comments on the Free plan ($0.15 on Business), and the $5 of monthly credit in Apify's Free plan covers about 16,000 comments.

What data does it return?

FieldDescription
id, keySubstack's numeric ID of the comment, and comment:<id>, which the new-only mode compares between runs.
postId, postUrl, postTitleThe post the comment is under: its ID, its link on the newsletter's own address and its title.
newsletterSubdomainThe newsletter's substack.com subdomain, such as garymarcus, also for newsletters on their own domain: comments under Noahpinion posts on www.noahpinion.blog give noahpinion.
parentId, depthThe comment this one answers, null for a comment on the post itself, and the level in the thread: 0 at the top, 1 for a reply, 2 for a reply to a reply.
author, authorHandleThe display name and Substack handle shown next to the comment, such as Gary Marcus and garymarcus.
publishedAtWhen the comment was posted, as an ISO 8601 UTC timestamp.
bodyThe comment text with its line breaks.
likesLikes on the comment at the time of the run.
repliesHow many direct replies the comment has. Replies to those replies are counted on the comment they answer.
editedtrue when the commenter changed the comment after posting it.
typeThe row type, always comment in this actor.

How to scrape Substack comments

  1. In Post links, add one link per line in the form https://<newsletter address>/p/<slug>. Posts on a substack.com subdomain and on a custom domain such as https://www.noahpinion.blog both work.
  2. To follow whole newsletters, add them to Newsletters as a subdomain (lenny), a substack.com address or a custom domain. The actor reads the comments under each newsletter's newest posts, as many as Maximum posts per newsletter allows (5 by default). Both fields can be used in one run.
  3. Pick the Comment order: Best first, Newest first or Oldest first. Rows come in thread order, each top-level comment followed by its replies, and Maximum comments per post (500 by default) counts replies too, so a capped post can end in the middle of a thread.
  4. Set Maximum rows and click Start. Comments appear in the Output tab, where you can download them as CSV, Excel or JSON. The SUMMARY record in the key-value store counts posts and comments and lists every link that was skipped.

As an API input:

{
"posts": ["https://garymarcus.substack.com/p/we-must-recall-open-ended-ai-agents"],
"newsletters": ["lenny", "https://www.noahpinion.blog"],
"maxPostsPerNewsletter": 10,
"maxCommentsPerPost": 1000,
"commentSort": "newest_first"
}

Example output

A reply by the newsletter's author under one of his posts, from a run on 11 October 2026. Comments by readers have the same fields, with the name and handle they comment under.

{
"type": "comment",
"key": "comment:357345097",
"id": 357345097,
"postId": 219679899,
"postUrl": "https://garymarcus.substack.com/p/we-must-recall-open-ended-ai-agents",
"postTitle": "We must recall open-ended AI agents with internet access from the market, now",
"newsletterSubdomain": "garymarcus",
"parentId": 357326579,
"depth": 1,
"author": "Gary Marcus",
"authorHandle": "garymarcus",
"publishedAt": "2026-10-10T07:19:34.804Z",
"body": "I don’t think the AI itself has motivation.",
"likes": 7,
"replies": 1,
"edited": false
}

How much does it cost to scrape Substack comments?

Free planStarterScaleBusiness
1,000 comments$0.30$0.24$0.195$0.15

You pay only for the events in the table. There is no start fee, and compute time and proxies are included.

The 15 newest posts of Lenny's Newsletter, Noahpinion and Gary Marcus's newsletter held 792 public comments on 11 October 2026, which cost $0.2376 on the Free plan and $0.1188 on Business. Posts without public comments add nothing to the bill, and comments the new-only mode skips are not charged.

Limits

  • Substack serves each post's whole discussion in one response, so runs are short: the 792 comments above took under 4 seconds, and a single post with 76 comments about 3 seconds.
  • Comments under paid posts are hidden from visitors without a subscription. Four of the five newest posts in Lenny's Newsletter were for paid subscribers on 11 October 2026, and they returned no comments although they showed 1 to 21 each.
  • Deleted comments and comments Substack has not published are left out, so a post can show one or two more than the actor returns: a Gary Marcus post that showed 130 comments gave 129 rows.
  • Threads can run deep. A Noahpinion post on utilitarianism had a reply at depth 10.
  • With Newsletters, the newest posts are read first and there is no date filter. To reach older posts, raise Maximum posts per newsletter.
  • A link without /p/ is skipped and named in SUMMARY. Substack Notes and chats are not read.
  • A run stops after 10,000 rows unless you raise Maximum rows.

Alerts for new comments

Turn on Return only rows new since the last run, give the run a Watch name or save it as a task, and schedule it. Each run returns only comments whose id the previous run under that name had not seen, and comments that did not fit under Maximum rows come with the next run. With Newsletters filled, a daily schedule also picks up the comments under posts published since the day before. Choose Newest first so that fresh comments fall inside Maximum comments per post.

FAQ

The actor reads the comments that Substack shows to any visitor under free posts, without logging in. A display name and handle can identify a person, so data protection laws such as the GDPR may apply to how you store and use them. The actor collects nothing else about commenters: no emails, profiles or subscriptions. You are responsible for how you use the data.

Can I rebuild the comment threads?

Yes. Each reply carries the id of the comment it answers in parentId, and the rows of a post come in the order Substack nests them. Start from the rows where parentId is null and attach the replies below them, or use depth to indent them in a spreadsheet.

Does it return the posts too?

No, only comments, with each post's ID, link and title on every row. For the posts with their text, likes and restacks, use our Substack Scraper, which can also add comments to the posts of the newsletters you name.

Support

This actor is built and maintained by deriverge s.r.o., a software company based in the Czech Republic. If a run fails or a field you need is missing, please open an issue in the Issues tab or write to us at info@deriverge.com. We respond in English and Czech. Runs can be scheduled in Apify Console or started from the API tab, which has examples for Python, JavaScript and cURL and works with Make, Zapier, n8n and the Apify MCP server. If the actor saves you time, a short review helps other people find it.