Substack Notes Scraper avatar

Substack Notes Scraper

Pricing

from $0.02 / 1,000 substack notes

Go to Apify Store
Substack Notes Scraper

Substack Notes Scraper

Collect public Substack Notes, author profiles, engagement, attachments, publication links, and thread context for monitoring and creator research.

Pricing

from $0.02 / 1,000 substack notes

Rating

0.0

(0)

Developer

Hanna Nosova

Hanna Nosova

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

This Substack scraper collects public Substack Notes for topic monitoring, creator research, and social listening. Use the Substack Notes scraper to export Note text, authors, reactions, restacks, replies, attachments, publication links, and stable thread identifiers as structured records—and access them like a practical Substack API.

Quick start

{
"startUrls": [{ "url": "https://substack.com/notes" }],
"queries": [],
"maxItems": 25
}

A result looks like:

{
"id": "309223436",
"entityKey": "c-309223436",
"type": "comment",
"url": "https://substack.com/@saribotton/note/c-309223436",
"content": "A public Note...",
"publishedAt": "2026-08-06T11:37:55.617Z",
"authorName": "Sari Botton",
"authorHandle": "saribotton",
"reactionCount": 5,
"restackCount": 2,
"replyCount": 0,
"engagementTotal": 7
}

What data can you export?

FieldDescription
id, entityKey, typeStable source identifiers and entity type
urlCanonical public Note URL
content, contentTextLengthPlain Note text and character count
publishedAt, editedAt, scrapedAtPublication, edit, and collection timestamps
authorId, authorName, authorHandlePublic author identity
authorUrl, authorPhotoUrl, authorBioPublic profile links and metadata
reactionCount, reactionsTotal and per-emoji public reactions
restackCount, replyCount, engagementTotalPublic engagement metrics and derived total
attachments, hasAttachmentsAttached media/post metadata, URLs, and dimensions
publicationId, publicationName, publicationUrlLinked public publication where available
parentId, rootId, isReplyThread and reply relationships
sourceUrl, sourceQueryExact collection provenance

Input settings

InputTypeDescription
startUrlsarrayPublic Notes feed, profile Notes, or individual Note URLs
queriesarrayTopic or author phrases to search
maxItemsintegerGlobal unique Note limit, 1–1,000
changedSincestringInclusive ISO date-time for incremental monitoring

Input recipes

Monitor newly published Notes

{"startUrls":[{"url":"https://substack.com/notes"}],"maxItems":100,"changedSince":"2026-08-01T00:00:00Z"}

Collect a public author feed

{"startUrls":[{"url":"https://substack.com/@hamishmckenzie/notes"}],"maxItems":50}

Pricing

This Actor charges a small start event and one result event for each Note successfully saved. Failed or skipped Notes are not charged. See the live Pricing tab for current tier rates.

Tips and limits

  • Use changedSince for scheduled monitors and deduplicate downstream by id.
  • Public optional fields can be null or empty when an author or Note does not expose them.
  • Anonymous Substack surfaces can return fewer records than requested and may change without notice.
  • One failed target does not discard valid output from other targets; inspect the run summary for partial failures.
  • This Actor accesses public Notes only and does not log in or expose private, subscriber-only, or dashboard data.

Who is it for?

  • Social-listening teams tracking public creator conversations
  • Newsletter and creator-economy researchers comparing engagement
  • Content strategists discovering active authors and recurring themes
  • Analysts building scheduled datasets for dashboards or alerts

Substack API usage and integrations

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/substack-notes-scraper').call({
startUrls: [{ url: 'https://substack.com/notes' }],
maxItems: 25,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python

from apify_client import ApifyClient
client = ApifyClient('APIFY_TOKEN')
run = client.actor('fetch_cat/substack-notes-scraper').call(run_input={
'startUrls': [{'url': 'https://substack.com/notes'}],
'maxItems': 20,
})
items = client.dataset(run['defaultDatasetId']).list_items().items

cURL

curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~substack-notes-scraper/runs?token=APIFY_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"startUrls":[{"url":"https://substack.com/notes"}],"maxItems":20}'

MCP and AI agents

Connect through Apify MCP and ask your agent to collect public Notes for a monitoring workflow.

$claude mcp add apify https://mcp.apify.com/?tools=fetch_cat/substack-notes-scraper
{
"mcpServers": {
"apify": { "url": "https://mcp.apify.com/?tools=fetch_cat/substack-notes-scraper" }
}
}

Example prompts:

  • "Collect 20 recent public Substack Notes and summarize the most active authors."
  • "Run the Substack Notes scraper for my saved topic monitor and return reaction totals."
  • "Export Notes since yesterday and group them by linked publication."

FAQ

What data can I export with Substack scraper?

Note text, public author profiles, engagement metrics, attachments, publication links, thread relationships, stable IDs, and collection provenance.

Can I run Substack Notes Scraper through an API, schedule, or MCP client?

Yes. Call it through the Apify API example above, create an Apify schedule, or connect through Apify MCP.

How much does it cost to use Substack Notes Scraper?

You pay for the run start and each successfully saved Note. The live Pricing tab shows current tier rates before you run it.

Can it scrape private or paid content?

No. It is limited to anonymous public Substack Notes surfaces.

How do I update a monitoring dataset?

Schedule the Actor with changedSince, then merge records by stable id.

Why are some publication or attachment fields empty?

Not every public Note is linked to a publication or includes media. Empty optional values reflect the source truthfully.

Support

Open an issue from the Actor's Issues tab with the public target URL, input, and run ID. Do not include private credentials or cookies.