Substack Notes Scraper
Pricing
$0.01 / 1,000 notes
Substack Notes Scraper
Collect public Substack Notes from topic phrases or public source URLs. Save note text, stable IDs, public links, author details, times, engagement, media, and discovery data.
Pricing
$0.01 / 1,000 notes
Rating
0.0
(0)
Developer
Maxime Dupré
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
📝 Track public Substack Notes
Researchers, marketers, and newsletter teams can collect public Substack Notes without copying them by hand. This Actor returns one structured row per saved Note with text, stable identity, a public URL, source details, times, author and publication context, visible engagement, media, and links.
Use it to:
- Compare Note and post formats with Substack Notes Vs Posts when planning a Substack research workflow.
- Check Substack Notes Character Limit examples when Note length matters.
- Explore public Note ranking questions with Substack Notes Algorithm.
- Learn How To Use Substack Notes by collecting public Notes for a topic.
- Review How To Post A Note On Substack ideas before a publishing session.
- Compare public social conversations with Substack Notes Vs Twitter when researching a topic.
- Build a repeatable public Note workflow with Substack Notes Strategy.
📦 Structured Note data
Each saved row describes one public Substack Note. It includes the visible Note text, stable Note ID, canonical URL, source type, publication and collection times, author and publication context, visible engagement, media, outbound links, and thread fields. If the same Note appears again through another phrase or submitted URL, the first eligible match is saved and later matches are ignored. discoveredFrom shows only the phrase or URL that first produced the row. Missing public values stay null when the source does not show them, and arrays can be empty.
▶️ Run a public Notes collection
Choose a target
Select Topic search for phrases, or Public source URLs for public profile, feed, or Note pages.
Set a limit
maxItems is an optional positive limit for unique Notes. Leave it empty to return all available results until the source is exhausted.
Filter dates
dateField checks publication time or change time. startDate and endDate are inclusive UTC dates.
Skip known Notes
Add stable Note IDs in excludeNoteIds when you already have them.
Public search ranking, availability, rate limits, and source changes can affect what is returned. This Actor does not collect newsletter posts, full article bodies, or private or subscriber-only content.
⚙️ Input
Input fields
| Field | Type | What it does |
|---|---|---|
target | string | Required. Choose topicSearch for topic phrases or sourceUrls for public source URLs. |
topicPhrases | array of strings | Adds one or more phrases for Topic search. This field is ignored when target is sourceUrls. |
searchOrder | string | Chooses relevance or recent order for Topic search. It is ignored when target is sourceUrls. |
sourceUrls | array of objects | Adds public Substack profile, feed, or Note URLs. This field is ignored when target is topicSearch. |
sourceUrls[].url | string | A public Substack profile, feed, or Note URL to read. |
dateField | string | Chooses whether dates check published time or changed time. |
startDate | string | Optional inclusive UTC start date in YYYY-MM-DD format. |
endDate | string | Optional inclusive UTC end date in YYYY-MM-DD format. |
excludeNoteIds | array of strings | Skips the listed stable Note IDs. |
maxItems | integer | Optional positive limit for unique Notes. Leave it empty to return all available results until the source is exhausted. |
Example input
This is the public input from a successful current-beta default-input run:
{"target": "topicSearch","topicPhrases": ["technology"],"searchOrder": "relevance","dateField": "published","maxItems": 100}
🧾 Output
Every saved row uses the same shape for topic, profile, feed, and Note sources. Values can be null when a public source does not show them. Arrays can be empty.
Output fields
| Field | Type | What it does |
|---|---|---|
noteId | string | Stable public ID for the Note. |
text | string | Visible text of the public Note. |
noteUrl | string | Canonical public URL for the Note. |
sourceType | string | Says how the Note was found: topicSearch, profile, feed, or note. |
discoveredFrom | object | Groups the first topic phrase or public source URL that produced the Note. |
discoveredFrom.type | string | Says whether the first discovery value was a topicPhrase or sourceUrl. |
discoveredFrom.value | string | The first topic phrase or public source URL that produced the Note. |
publishedAt | string | UTC time when the Note was published. |
editedAt | string or null | UTC time when the Note was last edited, when public edit time is available. |
collectedAt | string | UTC time when the Actor collected the Note. |
author | object | Groups public author identity and profile details. |
author.id | string or null | Public author ID, when available. |
author.name | string or null | Visible author name, when available. |
author.handle | string or null | Visible author handle, when available. |
author.profileUrl | string or null | Public author profile URL, when available. |
author.photoUrl | string or null | Public author photo URL, when available. |
author.bio | string or null | Visible author bio, when available. |
publication | object or null | Groups the public publication linked to the Note, when available. |
publication.id | string or null | Public publication ID, when available. |
publication.name | string or null | Visible publication name, when available. |
publication.url | string or null | Public publication URL, when available. |
engagement | object | Groups visible counts and reaction details. |
engagement.likes | number or null | Visible like or reaction count, when available. |
engagement.restacks | number or null | Visible restack count, when available. |
engagement.replies | number or null | Visible reply count, when available. |
engagement.total | number or null | Total visible engagement count, when available. |
engagement.reactions | array of objects or null | Lists visible reactions and their counts, when available. |
engagement.reactions[].emoji | string | The visible reaction or emoji label. |
engagement.reactions[].count | number | Visible count for that reaction. |
media | array of objects | Lists media attached to the Note. It can be empty. |
media[].url | string | Public URL for attached media. |
media[].type | string or null | Media type, when exposed. |
media[].width | number or null | Media width in pixels, when available. |
media[].height | number or null | Media height in pixels, when available. |
outboundLinks | array of strings | Public URLs found in the Note text. It can be empty. |
thread | object | Groups reply status and public parent or root Note relationships. |
thread.isReply | boolean or null | Says whether the Note is a reply, when available. |
thread.parentNoteId | string or null | Public ID of the direct parent Note, when available. |
thread.parentUrl | string or null | Public URL of the direct parent Note, when available. |
thread.rootNoteId | string or null | Public ID of the root Note, when available. |
thread.rootUrl | string or null | Public URL of the root Note, when available. |
Example row
This is a genuine, unshortened row from a successful current-beta profile run:
{"noteId": "321255318","text": "Also as we are going to kickstart our new training series - AI Avatar Training and Social Media Domination.\n\nWe are doing a limited time 50% off on our Substack plan.\n\nAnd you will be having full zoom access and replay and all our previous ai courses.\n\nDetails here:\n\nhttps://sifuyik.substack.com/p/24-hours-only-100-hours-of-ai-training","noteUrl": "https://substack.com/@sifuyik/note/c-321255318","sourceType": "profile","discoveredFrom": {"type": "sourceUrl","value": "https://substack.com/@sifuyik"},"publishedAt": "2026-08-24T01:32:51.983Z","editedAt": null,"collectedAt": "2026-08-25T16:34:50.254Z","author": {"id": "73134922","name": "Sifu Yik Chan","handle": "sifuyik","profileUrl": "https://substack.com/@sifuyik","photoUrl": "https://substack-post-media.s3.amazonaws.com/public/images/658267de-b7ce-4827-a4a4-bf4aec4d9ddc_866x866.jpeg","bio": "AI Tips and News"},"publication": {"id": "7223942","name": "Sifu Yik's Substack","url": "https://sifuyik"},"engagement": {"likes": 2,"restacks": 0,"replies": 0,"total": 2,"reactions": [{"emoji": "❤","count": 2}]},"media": [{"url": "https://substack-post-media.s3.amazonaws.com/public/images/831fada1-9358-40eb-9a73-f000a1804f6e_2560x3200.png","type": "image","width": 2560,"height": 3200}],"outboundLinks": ["https://sifuyik.substack.com/p/24-hours-only-100-hours-of-ai-training"],"thread": {"isReply": false,"parentNoteId": null,"parentUrl": null,"rootNoteId": null,"rootUrl": null}}
💳 Pricing
Pay per event. The primary event is Note at $0.00001 for each public Note saved to your dataset. The total follows the number of Notes saved.
🔌 Integrations
Start the Actor in Apify Console or through the standard Actor API. Read the dataset through its API link or export it after the run.
❓ FAQ
What does this Actor collect?
It collects public Substack Notes from topic searches and public profile, feed, or Note sources. It does not collect newsletter posts, full article bodies, or private and subscriber-only content.
Can I use more than one topic phrase?
Yes. Add several topic phrases to one Topic search run. They use the same search order, date filters, exclusions, and note limit.
Can I use a public profile, feed, or Note URL?
Yes. Choose Public source URLs and add one or more public Substack URLs. The URL can point to a profile, feed, or Note page.
What happens when the same Note matches twice?
The first eligible match is saved. Later matches from another phrase or submitted URL are ignored, and discoveredFrom keeps the first matching value.
Can I filter Notes by a date range?
Yes. Choose publication time or change time, then add an inclusive UTC start date, end date, or both.
Does this return every available Note?
No result set can promise full coverage. Public availability, search ranking, rate limits, and source changes can affect which Notes are returned.
What happens when a public field is missing?
The Actor keeps the missing value as null when the schema allows it. It does not invent a name, count, URL, or time.
Do I need a Substack account or API key?
No. The Actor reads anonymous public Substack surfaces and does not require authenticated access.
📝 Changelog
0.0: Initial release
🆘 Support
For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡
🔗 Related Actors
- Substack Recommendations - Map public newsletter recommendation links from known publication pages.
- Twitter (X) Scraper - Collect public X posts for social listening alongside Substack Notes.
- Reddit Comments Search Scraper - Search public Reddit comments to compare discussion around the same topic.
- Substack Notes Search and Author Monitor - Search public Substack Notes and track author activity with stable IDs and engagement.
- Substack Notes Scraper - Extract Substack search results with author details, images, and engagement metrics.
Made with ❤️ by Maxime Dupré