Substack API

Substack 文章 API

通过 URL 抓取任意 Substack 刊物的文章,或传入单篇文章 URL(…/p/slug)只获取那一篇。返回标题、副标题、发布日期、付费墙状态、字数、互动数据(反应、评论、转发)、作者主页、刊物信息、纯文本、HTML 和 Markdown 格式的完整正文,以及可选的评论串。

US$2.62/千条结果,按请求付费,无需订阅。

Clearheaded
clearheaded.blog
ClearheadedSubscribe
HomeArchiveAbout

Why roadmaps are guesses

Sep · Priya Nakamura

The three-question standup

A shorter standup that actually surfaces risk

PaidSep · Priya Nakamura

Ask me anything: hiring your first PM

Reader questions from last week's thread

Sep · Priya Nakamura

Clearheaded

Type your email…Subscribe

Recommendations

API 返回的内容items[0]
{
"postId": "148302911",
"title": "Why roadmaps are guesses",
"url": "https://www.clearheaded.blog/p/why-roadmaps-are-guesses",
"slug": "why-roadmaps-are-guesses",
"postType": "newsletter",
"createdUtc": 1758585600,
"wordcount": 2140,
"authorName": "Priya Nakamura",
... 还有 22 个字段
}
可用率
100.00%
30d · 458 次调用
请求数
458
30d · 按周,近 12 周
响应时间
3.0s
中位数 · 30d

试一试

一个请求获取 Substack 文章

打开于
获取免费密钥
示例响应
免费运行只返回前 3 条结果。为密钥充值即可获得完整响应。

这个示例展示了 69 个字段中的 58 个。查看全部字段

{
  "found": true,
  "data": {
    "items": [
      {
        "postId": "148302911",
        "title": "Why roadmaps are guesses",
        "url": "https://www.clearheaded.blog/p/why-roadmaps-are-guesses",
        "slug": "why-roadmaps-are-guesses",
        "postType": "newsletter",
        "createdUtc": 1758585600,
        "wordcount": 2140,
        "authorName": "Priya Nakamura",
        "authorHandle": "priyanakamura",
        "contentStatus": "full",
        "text": "Every roadmap I have shipped was a guess with a deadline attached.",
        "publication": {
          "id": "pub_5521",
          "name": "Clearheaded",
          "url": "https://www.clearheaded.blog",
          "subdomain": "clearheaded",
          "customDomain": "www.clearheaded.blog",
          "description": "Notes on building things without lying to yourself.",
          "image": "https://substackcdn.com/image/fetch/clearheaded/logo.png",
          "language": "en",
          "paymentsEnabled": true,
          "subscriberCount": 38400
        },
        "comments": [
          {
            "commentId": "c_88213",
            "text": "This matches every planning meeting I have sat through for a decade.",
            "createdUtc": 1758600000,
            "authorName": "Devon Okafor",
            "authorHandle": "devonokafor",
            "authorUrl": "https://substack.com/@devonokafor",
            "authorImage": "https://substackcdn.com/image/fetch/clearheaded/devon-avatar.png",
            "reactionCount": 44,
            "restackCount": 2,
            "isPinned": true,
            "isAuthor": false,
            "replies": [
              {
                "commentId": "c_88240",
                "text": "Glad it landed. Curious how your team names the guess out loud.",
                "createdUtc": 1758603600,
                "authorName": "Priya Nakamura",
                "authorHandle": "priyanakamura",
                "authorUrl": "https://www.clearheaded.blog/people/priya-nakamura",
                "authorImage": "https://substackcdn.com/image/fetch/clearheaded/priya-avatar.png",
                "reactionCount": 12,
                "restackCount": 0,
                "isPinned": false,
                "isAuthor": true
              }
            ]
          }
        ]
      },
      {
        "postId": "148190442",
        "title": "The three-question standup",
        "url": "https://www.clearheaded.blog/p/the-three-question-standup",
        "slug": "the-three-question-standup",
        "subtitle": "",
        "description": "A shorter standup that actually surfaces risk",
        "postType": "newsletter",
        "createdUtc": 1757980800,
        "isPaid": true,
        "language": "en",
        "wordcount": 1420,
        "reactionCount": 501,
        "commentCount": 29,
        "replyCount": 6,
        "restackCount": 18,
        "authorName": "Priya Nakamura",
        "authorHandle": "priyanakamura",
        "authorUrl": "https://www.clearheaded.blog/people/priya-nakamura",
        "contentStatus": "preview_only",
        "text": "Most standups answer the same three questions badly. Here is a version that takes six minutes and actually works...",
        "publication": {
          "id": "pub_5521",
          "name": "Clearheaded",
          "url": "https://www.clearheaded.blog",
          "subdomain": "clearheaded"
        },
        "comments": []
      },
      {
        "postId": "148075310",
        "title": "Ask me anything: hiring your first PM",
        "url": "https://www.clearheaded.blog/p/ask-me-anything-hiring-your-first-pm",
        "slug": "ask-me-anything-hiring-your-first-pm",
        "subtitle": "Reader questions from last week's thread",
        "description": "Reader questions from last week's thread",
        "postType": "thread",
        "createdUtc": 1757376000,
        "isPaid": false,
        "language": "en",
        "wordcount": 640,
        "reactionCount": 203,
        "commentCount": 41,
        "replyCount": 9,
        "restackCount": 5,
        "authorName": "Priya Nakamura",
        "authorHandle": "priyanakamura",
        "authorUrl": "https://www.clearheaded.blog/people/priya-nakamura",
        "contentStatus": "metadata_only",
        "publication": {
          "id": "pub_5521",
          "name": "Clearheaded",
          "url": "https://www.clearheaded.blog",
          "subdomain": "clearheaded"
        },
        "comments": []
      }
    ]
  }
}

完整的参数与响应参考:这个接口的每个字段、类型和示例。

参考

一个请求,一种响应结构。

你发送的每个字段和收到的每个字段,都附有真实示例。

最近验证于 2026-11-14 · 可用率和延迟按 30d 统计

请求体

JSON,POST 到这个接口。

  • urlstring

    https://www.clearheaded.blog

    Substack 刊物 URL 或自定义域名,用于获取其近期文章(例如 https://www.astralcodexten.com);或者单篇文章 URL,用于获取那一篇的完整内容(例如 https://www.astralcodexten.com/p/your-book-review)。

  • contentTypeenum

    限定为单一文章类型,或 'all'(例如 newsletter)。

  • endDatestring

    只返回在该日期当天或之前发布的文章,格式为 YYYY-MM-DD(例如 2024-12-31)。只在扫描的最近 'limit' 篇文章中生效。

  • includeCommentsboolean

    在每篇文章中包含公开评论串及其直接回复(例如 true)。

  • includeContentboolean

    true

    包含纯文本、HTML 和 Markdown 格式的完整正文。设为 false 则只返回元数据,速度更快(例如 false)。

  • limitinteger

    3

    传入刊物 URL 时返回近期文章的最大数量(1-100,默认 25);传入单篇文章 URL 时忽略,始终返回那一篇。按返回的文章数扣费,所以上限越低,费用越少。

  • maxCommentsinteger

    'includeComments' 为 true 时每篇文章收集的最大评论数(0-500,默认 20)。不额外收费(例如 50)。

  • minCommentsinteger

    只返回评论数不少于该值的文章(例如 10)。

  • minReactionsinteger

    只返回反应数不少于该值的文章(例如 100)。

  • minWordCountinteger

    只返回字数不少于该值的文章,可过滤掉简短的笔记和公告(例如 1000)。

  • onlyFreeboolean

    只返回免费(无付费墙)的文章(例如 true)。

  • startDatestring

    只返回在该日期当天或之后发布的文章,格式为 YYYY-MM-DD(例如 2024-01-01)。只在扫描的最近 'limit' 篇文章中生效,因此要覆盖更早的日期范围,请调高 'limit'。

你发送。 一个简短的 JSON 请求体。显示的值只是示例,请换成你自己的。

响应

JSON,每个字段一个示例值。

each itemdata.items[]

Post records: title, subtitle, URL, publish date, paywall status, word count, engagement (reactions, comments, restacks), author profile, publication details, the article body as text, HTML and Markdown, and comment threads when requested. Populated whenever the provider has data for the entity.

  • authorBiostring

    Author bio as shown on their Substack profile.

  • authorHandlestring

    priyanakamura

    Substack handle of the post author. Populated whenever the provider has data for the entity.

  • authorImagestring

    Profile photo URL of the post author.

  • authorNamestring

    Priya Nakamura

    Display name of the post author. Populated whenever the provider has data for the entity.

  • authorUrlstring

    Substack profile URL of the post author.

  • commentCountinteger

    Number of top-level comments on the post.

  • contentStatusstring

    full

    How much of the article body this record carries: 'full' for the whole article, 'preview_only' for the public excerpt of a paywalled post, 'metadata_only' when no body was requested or available, or 'failed' when extraction failed. Read this before trusting 'text', 'html', or 'markdown'. Populated whenever the provider has data for the entity.

  • createdUtcnumber

    1758585600

    UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. Populated whenever the provider has data for the entity.

  • descriptionstring

    Short post description, usually the subtitle or an excerpt.

  • hasVoiceoverboolean

    Whether the post carries a narrated audio version.

  • htmlstring

    Article body as HTML. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'.

  • imagestring

    Cover image URL.

  • isPaidboolean

    Whether the post is behind a paywall.

  • languagestring

    Two-letter language code of the post.

  • markdownstring

    Article body as Markdown. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'.

  • podcastUrlstring

    Audio URL for a podcast post or a narrated voiceover, when the post has one.

  • postIdstring

    148302911

    Substack post identifier. Populated whenever the provider has data for the entity.

  • postTypestring

    newsletter

    Post type (newsletter, podcast, or thread). Populated whenever the provider has data for the entity.

  • reactionCountinteger

    Number of reactions (likes) on the post.

  • replyCountinteger

    Number of replies to comments on the post.

  • restackCountinteger

    Number of times the post was restacked.

  • slugstring

    why-roadmaps-are-guesses

    Post slug, the last path segment of the post URL. Populated whenever the provider has data for the entity.

  • subtitlestring

    Post subtitle or deck.

  • textstring

    Every roadmap I have shipped was a guess with a deadline attached.

    Article body as plain text. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'.

  • titlestring

    Why roadmaps are guesses

    Post title. Populated whenever the provider has data for the entity.

  • updatedUtcnumber

    UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.

  • urlstring

    https://www.clearheaded.blog/p/why-roadmaps-are-guesses

    Canonical post URL. Populated whenever the provider has data for the entity.

  • wordcountinteger

    2140

    Approximate word count of the article.

each commentdata.items[].comments[]

Top-level comment threads on the post, each with its direct replies. Empty unless 'includeComments' is true. Replies nested more than one level deep are not returned.

  • authorHandlestring

    devonokafor

    Substack handle of the comment author.

  • authorImagestring

    https://substackcdn.com/image/fetch/clearheaded/devon-avatar.png

    Profile photo URL of the comment author.

  • authorNamestring

    Devon Okafor

    Display name of the comment author.

  • authorUrlstring

    https://substack.com/@devonokafor

    Substack profile URL of the comment author.

  • commentIdstring

    c_88213

    Substack comment identifier.

  • createdUtcnumber

    1758600000

    UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.

  • editedUtcnumber

    UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.

  • isAuthorboolean

    false

    Whether the comment was written by the post author.

  • isPinnedboolean

    true

    Whether the comment is pinned by the publication.

  • reactionCountinteger

    44

    Number of reactions on the comment.

  • restackCountinteger

    2

    Number of times the comment was restacked.

  • textstring

    This matches every planning meeting I have sat through for a decade.

    Comment body text.

each replydata.items[].comments[].replies[]

Direct replies to this comment.

  • authorHandlestring

    priyanakamura

    Substack handle of the reply author.

  • authorImagestring

    https://substackcdn.com/image/fetch/clearheaded/priya-avatar.png

    Profile photo URL of the reply author.

  • authorNamestring

    Priya Nakamura

    Display name of the reply author.

  • authorUrlstring

    https://www.clearheaded.blog/people/priya-nakamura

    Substack profile URL of the reply author.

  • commentIdstring

    c_88240

    Substack comment identifier.

  • createdUtcnumber

    1758603600

    UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.

  • editedUtcnumber

    UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.

  • isAuthorboolean

    true

    Whether the reply was written by the post author.

  • isPinnedboolean

    false

    Whether the reply is pinned by the publication.

  • reactionCountinteger

    12

    Number of reactions on the reply.

  • restackCountinteger

    0

    Number of times the reply was restacked.

  • textstring

    Glad it landed. Curious how your team names the guess out loud.

    Reply body text.

publicationdata.items[].publication

The publication the post belongs to.

  • customDomainstring

    www.clearheaded.blog

    Custom domain the publication is served on, when it has one.

  • descriptionstring

    Notes on building things without lying to yourself.

    Publication tagline or hero text.

  • idstring

    pub_5521

    Substack publication identifier.

  • imagestring

    https://substackcdn.com/image/fetch/clearheaded/logo.png

    Publication logo URL.

  • languagestring

    en

    Two-letter language code of the publication.

  • namestring

    Clearheaded

    Publication name.

  • paymentsEnabledboolean

    true

    Whether the publication sells paid subscriptions.

  • subdomainstring

    clearheaded

    Publication subdomain on substack.com.

  • subscriberCountinteger

    38400

    Subscriber count, when the publication publishes it.

  • urlstring

    https://www.clearheaded.blog

    Publication home URL.

top level
  • foundboolean

    true

    Whether any posts were found for the request.

  • reason"not_found"

    Present only when `found` is false, and says why there is no result. `not_found`: the source states the target does not exist, or returned nothing for it. A `found: false` answer is a successful call, not an error, and `costUsd` is what it actually cost.

你收到。 字段有名称、有类型,无论哪个数据源响应,结构都一样。

常见问题

关于 Substack 文章 API

AnyAPI 的 Substack 文章 API 只需一次 POST 请求 /v1/run/substack.posts,就以统一格式的 JSON 返回 Substack 数据。通过 URL 抓取任意 Substack 刊物的文章,或传入单篇文章 URL(…/p/slug)只获取那一篇。返回标题、副标题、发布日期、付费墙状态、字数、互动数据(反应、评论、转发)、作者主页、刊物信息、纯文本、HTML 和 Markdown 格式的完整正文,以及可选的评论串。无论哪个数据源提供服务,AnyAPI 都返回同一套统一的 schema。费用:每千条结果 US$2.62,单次请求最多 US$0.265,以美元计价,无需订阅,也没有每月最低消费。过去 30 天,通过 AnyAPI 发起的 Substack 文章 API 调用中有 100.0% 成功,响应时间中位数为 3.0 秒,共测量 458 次调用。

费用:每千条结果 US$2.62,单次请求最多 US$0.265,以美元计价,无需订阅,也没有每月最低消费。你只需为一个美元钱包充值,每次调用从中扣费。部分由钱包付费的失败请求会产生处理费用,我们按成本原价转嫁,不加价;错误响应会显示收取的金额。

通过 URL 抓取任意 Substack 刊物的文章,或传入单篇文章 URL(…/p/slug)只获取那一篇。返回标题、副标题、发布日期、付费墙状态、字数、互动数据(反应、评论、转发)、作者主页、刊物信息、纯文本、HTML 和 Markdown 格式的完整正文,以及可选的评论串。响应是统一格式的 JSON,外层结构与每个 AnyAPI 接口相同,所以解析另一个接口只需换一个 URL,别的都不用改。

过去 30 天,通过 AnyAPI 发起的 Substack 文章 API 调用中有 100.0% 成功,响应时间中位数为 3.0 秒,共测量 458 次调用。这些是 AnyAPI 对经过网关的流量的自有测量,持续重新计算,并非公开承诺的服务等级目标。

可以。新的 AnyAPI 账户自带 US$0.10 免费余额,无需绑卡。

向 https://api.getanyapi.com/v1/run/substack.posts 发送 POST 请求,在 “Authorization: Bearer” 请求头中放入你的 AnyAPI 密钥,并以 JSON 请求体传入参数。同一个密钥和同一个钱包适用于所有 AnyAPI 接口。

不需要。你向一个预付费的 AnyAPI 余额充值美元,每个请求从中扣费。没有月度套餐,也没有最低消费,同一个余额可用于所有 AnyAPI 接口。

有。TypeScript 用 npm 安装 @getanyapi/sdk,Python 用 pip 安装 getanyapi。两者都用同一个密钥调用所有 AnyAPI 接口,任何 HTTP 客户端也都可以。

可以。智能体可以连接 https://api.getanyapi.com/mcp 上的 AnyAPI MCP 服务器,或者向 https://api.getanyapi.com/agent/signup 发送一次无需认证的 POST 来创建自己的免费试用密钥,再通过 HTTP 调用这个接口。