Skip to main content
Glama
Apify Public Data & Leads

Apify Public Data & Leads

Substack Publication Posts & Keyword Search

substack_posts
Read-only

Read 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

NameRequiredDescriptionDefault
publicationsYesUp 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_termsNoUp 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_termNoMatching posts to take per keyword per publication, when search_terms are given (hard maximum 10). Each row is billed.
max_posts_per_publicationNoWhen 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

NameRequiredDescriptionDefault
runNo
errorNo
statusYes
resultsYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv1.6.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnly/openWorld/non-idempotent/non-destructive; the description adds what the annotations cannot: a synchronous cloud Actor run, reads of the public /api/v1/archive endpoint, no login/cookies/API key, APIFY_TOKEN requirement, 2-15s latency, $0.002/row with no start fee, and a hard 80-row billing ceiling derived from the caps. The 'Honest limits' block (newest-first only, point-in-time counts, paid posts have no text, loud failure instead of an empty billed dataset) is exactly the failure-mode disclosure an agent needs before spending money. Note: 'creates a billed Actor run and dataset' is a side effect on the caller's account while readOnlyHint=true, but it is disclosed rather than concealed and does not modify the target publications, so it is a transparency win rather than a contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded lead paragraph followed by clearly labeled Behavioral Transparency / Usage Guidelines / Honest limits blocks, which makes it scannable despite its length. Some content is stated more than once — the 'must name at least one publication' rule appears in the lead, in the honest-limits block, and again in the schema, and the full field list duplicates the output schema. Those repetitions cost it a point but the density of unique information justifies the overall length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a billed, network-executing, open-world scraper this covers everything an agent needs: mode selection, identifier formats, hard caps, cost model, latency, auth, failure behavior, and explicit non-capabilities. An output schema exists, so the field enumeration is surplus rather than necessary, but nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline would be 3; the description earns above that by adding billing semantics ('each row is billed', max 80 rows per call), the interaction rule that search_terms switches the mode from newest-posts to per-publication archive search, and the rejection behavior for an empty publications list. The concrete accepted identifier forms (subdomain vs. URL vs. custom domain) largely duplicate the schema's own publication description, which keeps this from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb ('Read') and resource ('public Substack publications') plus the exact payload ('post metadata'), and immediately branches into the two modes (newest posts vs. per-publication archive keyword search). The enumerated row fields make the output scope unmistakable, and 'apple_podcasts_data' / 'a general web scraper' are named as the non-Substack escape hatches, so an agent can separate it from siblings without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit three-way structure: 'When to use' (monitoring, tracking a writer, finding older posts on a topic, dataset building), 'When NOT to use' (no body text, no cross-Substack search, no private/paid-only publications), and named alternatives with the condition that selects each. The boundary that this searches *inside* named publications rather than across Substack is the key routing fact and it is stated twice, unambiguously.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.