Substack API

Substack 文章 API

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

POST/v1/run/substack.posts
可用率
100.00%
30d · 10 次调用
请求数
10
30d · 按周,近 12 周
响应时间
3.4s
中位数 · 30d

试一试

发出你的第一个请求

打开于
获取免费密钥
示例响应
免费运行只返回前 3 条结果。为密钥充值即可获得完整响应。
{
  "data": {
    "items": [
      {
        "authorBio": "Alex Rivera",
        "authorHandle": "alex_rivera",
        "authorImage": "https://example.com/image.jpg",
        "authorName": "Alex Rivera",
        "authorUrl": "https://example.com/page",
        "commentCount": 12500,
        "comments": [
          {
            "authorHandle": "alex_rivera",
            "authorImage": "https://example.com/image.jpg",
            "authorName": "Alex Rivera",
            "authorUrl": "https://example.com/page",
            "commentId": "a1b2c3d4",
            "createdUtc": 12.5,
            "editedUtc": 12.5,
            "isAuthor": true,
            "isPinned": true,
            "reactionCount": 12500,
            "replies": [
              null
            ],
            "restackCount": 12500,
            "text": "A short example description of this item."
          }
        ],
        "contentStatus": "A short example description of this item.",
        "createdUtc": 12.5,
        "description": "A short example description of this item.",
        "hasVoiceover": true,
        "html": "example",
        "image": "https://example.com/image.jpg",
        "isPaid": true,
        "language": "en",
        "markdown": "example",
        "podcastUrl": "https://example.com/page",
        "postId": "a1b2c3d4",
        "postType": "general",
        "publication": {
          "customDomain": "example.com",
          "description": "A short example description of this item.",
          "id": "a1b2c3d4",
          "image": "https://example.com/image.jpg",
          "language": "en",
          "name": "Example title",
          "paymentsEnabled": true,
          "subdomain": "example.com",
          "subscriberCount": 12500,
          "url": "https://example.com/page"
        },
        "reactionCount": 12500,
        "replyCount": 12500,
        "restackCount": 12500,
        "slug": "alex_rivera",
        "subtitle": "Example title",
        "text": "A short example description of this item.",
        "title": "Example title",
        "updatedUtc": 12.5,
        "url": "https://example.com/page",
        "wordcount": 12500
      }
    ]
  },
  "found": true,
  "reason": "not_found"
}
响应类型定义
interface SubstackPostsResponse {
  data: {
    items: {
      authorBio?: string;
      authorHandle?: string;
      authorImage?: string;
      authorName?: string;
      authorUrl?: string;
      commentCount?: number;
      comments?: {
        authorHandle?: string;
        authorImage?: string;
        authorName?: string;
        authorUrl?: string;
        commentId: string;
        createdUtc?: number;
        editedUtc?: number;
        isAuthor?: boolean;
        isPinned?: boolean;
        reactionCount?: number;
        replies?: {
          authorHandle?: string;
          authorImage?: string;
          authorName?: string;
          authorUrl?: string;
          commentId: string;
          createdUtc?: number;
          editedUtc?: number;
          isAuthor?: boolean;
          isPinned?: boolean;
          reactionCount?: number;
          restackCount?: number;
          text?: string;
        }[];
        restackCount?: number;
        text?: string;
      }[];
      contentStatus?: string;
      createdUtc?: number;
      description?: string;
      hasVoiceover?: boolean;
      html?: string;
      image?: string;
      isPaid?: boolean;
      language?: string;
      markdown?: string;
      podcastUrl?: string;
      postId?: string;
      postType?: string;
      publication?: {
        customDomain?: string;
        description?: string;
        id?: string;
        image?: string;
        language?: string;
        name?: string;
        paymentsEnabled?: boolean;
        subdomain?: string;
        subscriberCount?: number;
        url?: string;
      };
      reactionCount?: number;
      replyCount?: number;
      restackCount?: number;
      slug?: string;
      subtitle?: string;
      text?: string;
      title: string;
      updatedUtc?: number;
      url: string;
      wordcount?: number;
    }[];
  } | null;
  found: boolean;
  reason?: "not_found";
}

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

参考

请求、响应与价格

最近验证于 2026-09-29 · 可用率和延迟按 30d 统计
POST /v1/run/substack.posts
curl -X POST https://api.getanyapi.com/v1/run/substack.posts \
  -H "Authorization: Bearer $ANYAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"limit":3,"url":"https://www.astralcodexten.com"}'
字段类型示例值
请求体
urlstring"https://www.astralcodexten.com"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包含纯文本、HTML 和 Markdown 格式的完整正文。设为 false 则只返回元数据,速度更快(例如 false)。
limitinteger3传入刊物 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'。
响应
dataobjectResult payload, or null when nothing was found.
data.itemsobject[]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.
data.items[].authorBiostringAuthor bio as shown on their Substack profile.
data.items[].authorHandlestringSubstack handle of the post author. Populated whenever the provider has data for the entity.
data.items[].authorImagestringProfile photo URL of the post author.
data.items[].authorNamestringDisplay name of the post author. Populated whenever the provider has data for the entity.
data.items[].authorUrlstringSubstack profile URL of the post author.
data.items[].commentCountintegerNumber of top-level comments on the post.
data.items[].commentsobject[]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.
data.items[].comments[].authorHandlestringSubstack handle of the comment author.
data.items[].comments[].authorImagestringProfile photo URL of the comment author.
data.items[].comments[].authorNamestringDisplay name of the comment author.
data.items[].comments[].authorUrlstringSubstack profile URL of the comment author.
data.items[].comments[].commentIdstringSubstack comment identifier.
data.items[].comments[].createdUtcnumberUTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.
data.items[].comments[].editedUtcnumberUTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.
data.items[].comments[].isAuthorbooleanWhether the comment was written by the post author.
data.items[].comments[].isPinnedbooleanWhether the comment is pinned by the publication.
data.items[].comments[].reactionCountintegerNumber of reactions on the comment.
data.items[].comments[].repliesobject[]Direct replies to this comment.
data.items[].comments[].replies[].authorHandlestringSubstack handle of the reply author.
data.items[].comments[].replies[].authorImagestringProfile photo URL of the reply author.
data.items[].comments[].replies[].authorNamestringDisplay name of the reply author.
data.items[].comments[].replies[].authorUrlstringSubstack profile URL of the reply author.
data.items[].comments[].replies[].commentIdstringSubstack comment identifier.
data.items[].comments[].replies[].createdUtcnumberUTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.
data.items[].comments[].replies[].editedUtcnumberUTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.
data.items[].comments[].replies[].isAuthorbooleanWhether the reply was written by the post author.
data.items[].comments[].replies[].isPinnedbooleanWhether the reply is pinned by the publication.
data.items[].comments[].replies[].reactionCountintegerNumber of reactions on the reply.
data.items[].comments[].replies[].restackCountintegerNumber of times the reply was restacked.
data.items[].comments[].replies[].textstringReply body text.
data.items[].comments[].restackCountintegerNumber of times the comment was restacked.
data.items[].comments[].textstringComment body text.
data.items[].contentStatusstringHow 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.
data.items[].createdUtcnumberUTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. Populated whenever the provider has data for the entity.
data.items[].descriptionstringShort post description, usually the subtitle or an excerpt.
data.items[].hasVoiceoverbooleanWhether the post carries a narrated audio version.
data.items[].htmlstringArticle body as HTML. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'.
data.items[].imagestringCover image URL.
data.items[].isPaidbooleanWhether the post is behind a paywall.
data.items[].languagestringTwo-letter language code of the post.
data.items[].markdownstringArticle body as Markdown. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'.
data.items[].podcastUrlstringAudio URL for a podcast post or a narrated voiceover, when the post has one.
data.items[].postIdstringSubstack post identifier. Populated whenever the provider has data for the entity.
data.items[].postTypestringPost type (newsletter, podcast, or thread). Populated whenever the provider has data for the entity.
data.items[].publicationobjectThe publication the post belongs to.
data.items[].publication.customDomainstringCustom domain the publication is served on, when it has one.
data.items[].publication.descriptionstringPublication tagline or hero text.
data.items[].publication.idstringSubstack publication identifier.
data.items[].publication.imagestringPublication logo URL.
data.items[].publication.languagestringTwo-letter language code of the publication.
data.items[].publication.namestringPublication name.
data.items[].publication.paymentsEnabledbooleanWhether the publication sells paid subscriptions.
data.items[].publication.subdomainstringPublication subdomain on substack.com.
data.items[].publication.subscriberCountintegerSubscriber count, when the publication publishes it.
data.items[].publication.urlstringPublication home URL.
data.items[].reactionCountintegerNumber of reactions (likes) on the post.
data.items[].replyCountintegerNumber of replies to comments on the post.
data.items[].restackCountintegerNumber of times the post was restacked.
data.items[].slugstringPost slug, the last path segment of the post URL. Populated whenever the provider has data for the entity.
data.items[].subtitlestringPost subtitle or deck.
data.items[].textstringArticle body as plain text. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'.
data.items[].titlestringPost title. Populated whenever the provider has data for the entity.
data.items[].updatedUtcnumberUTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds.
data.items[].urlstringCanonical post URL. Populated whenever the provider has data for the entity.
data.items[].wordcountintegerApproximate word count of the article.
foundbooleanWhether 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.
价格
每次请求价格(上限)USDUS$0.0444
价格(/千条结果)USDUS$0.439604

常见问题

关于 Substack 文章 API

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

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

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

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