Substack Publication Posts & Keyword Search
substack_postsRead public Substack publications to retrieve recent posts or keyword-matched archive results, including titles, URLs, authors, dates, reactions, and comments for monitoring or analysis.
Instructions
Read public Substack publications and get post metadata in one call: the newest posts of each publication you name, or the posts matching keywords inside each publication's own archive search. Each row carries post id, title, subtitle, canonical URL, author, publication name/subdomain/domain, publication date, post type (newsletter or podcast), audience (everyone / only_paid), wordcount, reaction count, comment count, restack count, a short description and the cover image URL. A call must name at least one publication; a call that names none is refused before any billed run starts.
Behavioral Transparency:
Execution: Network call executed synchronously in the cloud via Apify Actor 'captainhandsome/substack-posts-scraper'.
Side Effects: Reads each publication's public /api/v1/archive endpoint and creates a billed Actor run and dataset on your Apify account. No login, no cookies, no API key, no browser.
Authentication: Requires APIFY_TOKEN environment variable.
Latency & Limits: Typically 2-15 seconds. $0.002 per row ($2 per 1,000 posts), no per-run start fee. This tool sends at most 4 publications, at most 2 keywords, and at most 10 posts per publication or per keyword-publication pair, so one call bills at most 80 rows.
Usage Guidelines:
When to use: Use for newsletter/media monitoring, tracking what a writer published and when, finding older posts on a topic inside a publication, or building post-metadata datasets for analysis and AI pipelines.
When NOT to use: Do not use when you need the post body text (this returns metadata and URLs only; paywalled posts stay paywalled), for cross-Substack keyword search (this Actor searches inside each publication you name), or for private/paid-only publications you cannot read.
Named alternatives: Use 'apple_podcasts_data' for Apple Podcasts shows and episodes; use a general web scraper when the target is not a Substack publication.
Honest limits: newest-first only, no date filter; reaction/comment/restack counts are a point-in-time snapshot; posts marked audience only_paid have no public text; a run that can read nothing fails loudly instead of billing for an empty dataset; publication and keyword lists are sent explicitly on every call, so nothing is scraped that the caller did not name.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"publications": "<publications>"
},
"name": "substack_posts"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| publications | Yes | Up to 4 publications to read: a subdomain ('noahpinion'), a URL ('https://noahpinion.substack.com'), or a custom domain ('https://www.noahpinion.blog'). Required: a call must name at least one; a call with an empty list is refused. | |
| search_terms | No | Up to 2 keywords. When set, each publication's own archive search is used and matching posts are returned per publication per keyword, newest first. Leave empty to read the newest posts instead. | |
| max_posts_per_term | No | Matching posts to take per keyword per publication, when search_terms are given (hard maximum 10). Each row is billed. | |
| max_posts_per_publication | No | When no search_terms are given: how many of the newest posts to return per publication (hard maximum 10). Each row is billed; defaults to 5. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| run | No | ||
| error | No | ||
| status | Yes | ||
| results | Yes |