Substack Post Monitor: RSS & Paywall Alert
Pricing
from $1.00 / 1,000 substack post returneds
Substack Post Monitor: RSS & Paywall Alert
Monitor Substack publication posts via RSS feeds with XML parsing, paywall detection, and new-post delta state tracking in Apify KV store.
Pricing
from $1.00 / 1,000 substack post returneds
Rating
0.0
(0)
Developer
Adriana Voss
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
Substack Post Monitor: New Newsletter Posts From the Public RSS Feed
List the Substack publications you care about. Each run reads their public RSS feeds and returns one row per post: title, link, author, publication date and a paywall flag. With monitoring on, a scheduled run returns only posts that were not in the previous run.
Who it's for
The curator of a weekly links digest. You read thirty newsletters and summarise the best pieces on Fridays. Instead of opening thirty inboxes, you want one list of everything published since last Friday, with links.
A venture analyst following a newsletter category. You are mapping which independent writers in a niche publish weekly and which have slowed down. A dated list of posts per publication, collected on a schedule, is the raw material for that chart.
A communications team watching a few outspoken writers. When a critic or a customer-turned-commentator publishes about your company, you want to see it the same morning, not when it is forwarded to you.
Why this one
- No login and no key. Substack publishes an RSS feed for every public publication, and that is the only thing read.
- Custom domains work. A publication on its own domain is read as well as one on
substack.com, because the actor appends/feedto whatever address you give it. We checked one of each. - A paywall flag on every post.
isPaywalledtells you whether the feed text carries a paywall marker. - Monitoring with a memory. Each publication's posts already returned are remembered in your own Apify account.
What you get
One row per post.
| Field | Meaning |
|---|---|
publicationUrl, publicationTitle | The address you gave and the feed's channel title. |
title | The post title. |
postUrl | The link to the post on Substack. |
guid | The feed's unique id for the post, used for monitoring. |
pubDate | Publication time as an ISO timestamp. |
author | The creator name from the feed. |
description | The feed's short description, cut at 500 characters. |
isPaywalled | true if paywall markers were found for the post, otherwise false. |
isNew, firstSeenAt | Monitoring flags, empty when monitoring is off. |
Every row also carries postCount, the number of posts produced for that publication in the run.
What the RSS feed can and cannot see
Everything here comes from one file per publication, so what that file holds sets the limits.
It can see the newest posts. On 2026-10-08 Astral Codex Ten's feed held 20 posts, from 2026-09-07 to 2026-10-07, and Lenny's Newsletter, on its own domain, held 20 from 2026-09-15 to 2026-10-05. We saw a first monitored run on the first publication report "20 new of 20 fetched".
It cannot see anything older than the feed's window. Twenty is the number we measured on both active publications, so treat roughly the 20 newest posts as the ceiling. A publication that posts daily fills the window in 20 days, so a monitor that runs less often than that can miss posts. Some feeds are shorter: one publication we tried held a single post.
It does not carry the body. The actor reads the feed's short description, and the full text is discarded. On our two samples the longest description was 39 characters on one publication and 246 on the other. Follow postUrl for the article.
It does not carry engagement. There are no likes, comments, subscriber counts or restacks in the feed.
The paywall flag means "a marker was seen". It matches phrases and CSS names that Substack puts in paywalled posts' feed text. On the 40 posts above, none was flagged. A false therefore means no marker was found in the feed, not that the post is free to read. Set fetchFullArticle to true and, for every post not flagged by the feed, the actor also requests the post page and looks for the same markers there. That is one extra request per post, so runs get slower.
Pricing
- Substack post returned: $2 per 1,000 posts
Plus a $0.0015 start fee per run. Each event above is billed independently, only when it actually returns data — misses (found:false) are never charged.
Empty results are not billed. This was a billing bug in earlier builds, fixed and confirmed with local runs on 2026-10-08:
- A monitored run in which no post is new returns one row with
found: trueandpostCount: 0, and that row is not charged. You pay only the start fee. - A publication address that does not exist, such as a mistyped name, now returns a
found: falserow with statusNOT_FOUND, which is never charged.
A first full run of a 20-post feed costs $0.04.
How to use
- In the Apify Console. Open the actor page and click Start — the
publication_urlfield is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found. - Via the API. Call it directly with a POST request — no Console needed once you have an API token:
curl "https://api.apify.com/v2/acts/accountable_eel~substack-post-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"publication_url":["https://astralcodexten.substack.com"]}'
- On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.
Input
{"publication_url": ["https://astralcodexten.substack.com"]}
Substack publication URL (e.g., https://astralcodexten.substack.com). Accepted formats: https://astralcodexten.substack.com, astralcodexten.substack.com.
Other settings:
deltaModeswitches on monitoring, anddeltaNamenames the watchlist.maxResultscaps posts per publication. It defaults to 50, which is above what a feed holds.fetchFullArticleadds the paywall check described above.- Two optional word lists,
includeKeywordsandexcludeKeywords, trim the rows after they are fetched. In a monitored run they act before the watch records a post, so a post they hide is not remembered and appears as new if you loosen the lists later. testRunruns only the first five publications, andonlyFoundhides rows with no result.
Sample output
| query | found | status | postCount | publicationUrl | publicationTitle | title | postUrl | guid | pubDate | author | description | isPaywalled | isNew | firstSeenAt | scrapedAt |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| https://astralcodexten.substack.com | true | OK | <post url> | 1970-01-01T00:00:00.000Z |
Use it from Clay, n8n, Make, or an AI agent
This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.
curl "https://api.apify.com/v2/acts/accountable_eel~substack-post-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"publication_url":["https://astralcodexten.substack.com"]}'
n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~substack-post-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"publication_url":["https://astralcodexten.substack.com"]} (swap in an expression from an earlier node for a real value).
Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~substack-post-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"publication_url":["{{publication url}}"]}, mapping the row's publication url into the publication_url array.
MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Substack Post Monitor | Apify" — the agent will find and run this actor.
Tips
- Set
deltaNameonce and keep it. Without it, the monitoring record is keyed on a hash of your publication list, so adding one publication changes the key and restarts every baseline. - Schedule often enough for your busiest writer. With a 20-post window, a writer who publishes 20 posts between two runs pushes the oldest of them out of the feed unseen.
- A recorded
deltaNamewithoutdeltaModestill bills every post. It marksisNewbut drops nothing. TurndeltaModeon to receive only new posts. - Use the bare domain if you like.
astralcodexten.substack.comworks withouthttps://. - Test an address in a browser. Open
<address>/feed. If it shows XML, the actor will read it; if it shows an error page, fix the address before it costs you a post.
vs. alternatives
| What it costs | What you get | Trade-off | |
|---|---|---|---|
This actor (substack-post-monitor) | $0.002 per post returned, $0.0015 per run | A rolling list of the newest posts per publication, with a monitoring memory and a paywall flag | About 20 posts at most, no body text, and no engagement numbers |
Substack Publication Lookup (substack-publication-lookup) | Billed per publication; see its page for the current rate | Name, tagline, posting frequency, the paid-to-free ratio, topics and the last ten posts with reactions and comments | For researching a publication rather than tailing it, this is the better choice. It does not give you a recurring new-post feed. |
FAQ
How many posts can it see?
About the 20 newest, because that is what the feed holds. We measured 20 on two active publications.
Does it read comments or Notes?
No. Only the publication's post feed is read.
Is a post marked isPaywalled: false free?
Not necessarily. It means the feed showed no paywall marker.
Why was I billed for a run that returned nothing?
You should not be. Earlier builds charged one post for an empty monitored run or an unreachable address; that is fixed, and neither is billed now (see Pricing). If you still see such a charge, check that the run used the latest build.
Related actors
- Substack Publication Lookup profiles a publication: posting frequency, paid-to-free ratio and recent posts with reactions.