ResearchOpen SourceFreeActiveMachine-verified· beginner · ~5 min setup

Track a tool's hype curve across any Substack (no API key)

Count how often a tool or model is mentioned in a Substack's posts over time, so you can see a hype curve rise and fade, using only the public archive.

by Shilpa Mitra· verified today· v1.0.0

Run this workflow

CI-verified, 2/2 fixtures passing.

Build this with your agent

One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.

Intended Use

Anyone who wants to measure how a term trends across a newsletter's archive. CI verifies the analyzer deterministically: given dated posts, it counts the posts mentioning a term per month and produces the correct timeline. Pulling a live Substack (the public /api/v1/archive + per-post endpoints) is the fenced step, because the data changes and it is network-bound; the endpoint also rate-limits bulk scraping, so be gentle.

Not for

  • Subscriber counts or growth, Substack's public API exposes none of that, so this measures coverage/mindshare only, never popularity
  • Expecting CI to hit the network, it verifies the counting logic on a fixture; the live pull is fenced

The Stack

Tested Against

substack public archive (2026-06)node@20.x

Side effects & data flow

Network
none, local only
Writes
./posts.json
Credentials
none required

Data privacy

  • nobody in CI; the live step calls public Substack endpoints public post text and dates (retention: no subscriber data is available or collected; public posts only)

Prerequisites

  • node
  • A Substack publication to point it at, for the live step

Steps

  1. 1

    Verify the mention-over-time analyzer (deterministic)

    The core is a counter: given dated posts, count how many per month mention a term. CI runs it on a fixture where the term peaks early then goes silent, the shape of a hype curve, and asserts the exact monthly timeline. No network, no key.

    cat > posts.json <<'JSON'
    [
      {"post_date":"2026-02-10","text":"Everyone is trying AutoGPT this month, it is all anyone writes about."},
      {"post_date":"2026-02-22","text":"More AutoGPT experiments, the autonomous agents hype is peaking."},
      {"post_date":"2026-03-05","text":"AutoGPT is cooling off already, people are moving to the next thing."},
      {"post_date":"2026-05-01","text":"Claude and MCP are everywhere now, the conversation has fully moved on."},
      {"post_date":"2026-06-09","text":"MCP servers keep multiplying; nobody brings up the old tool anymore."}
    ]
    JSON
    node -e '
    const term = (process.env.TERM_Q || "AutoGPT").toLowerCase();
    const posts = JSON.parse(require("fs").readFileSync("posts.json", "utf8"));
    const byMonth = {};
    for (const p of posts) {
      if (p.text.toLowerCase().includes(term)) {
        const m = p.post_date.slice(0, 7);
        byMonth[m] = (byMonth[m] || 0) + 1;
      }
    }
    const line = Object.keys(byMonth).sort().map((m) => m + ":" + byMonth[m]).join(" ");
    const expect = "2026-02:2 2026-03:1";
    if (line === expect) {
      console.log("analyzer OK: AutoGPT mentions " + line + " then silent (a hype curve that peaked and faded)");
    } else {
      console.log("BAD timeline: " + line + " (want " + expect + ")");
      process.exit(1);
    }
    '
  2. 2

    Run it on a real Substack (the live step, not checked by CI)

    Point it at a publication: fetch the archive list (https://PUB.substack.com/api/v1/archive?sort=new&limit=25&offset=0, paginate with offset), then each post (/api/v1/posts/SLUG) for full body_html, strip tags, and feed the dated text through the same counter with your TERM_Q. The data changes and the endpoint throttles bulk pulls, so CI never claims a live result. Remember it is coverage over time, not subscribers.

Eval, 2 fixtures

Last passed: verified today
  • timelinecontainstimeout 30s · max $0

    Expected: analyzer OK: AutoGPT mentions 2026-02:2 2026-03:1 then silent (a hype curve that peaked and faded)

  • clean-exitexit_codetimeout 30s · max $0

    Expected: 0

Results

AI tools rot fast and the conversation moves on. This turns any Substack's public archive into a mention-over-time timeline, so you can watch a tool peak and then go quiet, no API key and no subscriber data involved.

Did this work for you?

Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.

Liked this workflow?

Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).