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"}'| 字段 | 类型 | 示例值 |
|---|---|---|
| 请求体 | ||
| url | string | "https://www.astralcodexten.com"Substack 刊物 URL 或自定义域名,用于获取其近期文章(例如 https://www.astralcodexten.com);或者单篇文章 URL,用于获取那一篇的完整内容(例如 https://www.astralcodexten.com/p/your-book-review)。 |
| contentType | enum | 限定为单一文章类型,或 'all'(例如 newsletter)。 |
| endDate | string | 只返回在该日期当天或之前发布的文章,格式为 YYYY-MM-DD(例如 2024-12-31)。只在扫描的最近 'limit' 篇文章中生效。 |
| includeComments | boolean | 在每篇文章中包含公开评论串及其直接回复(例如 true)。 |
| includeContent | boolean | 包含纯文本、HTML 和 Markdown 格式的完整正文。设为 false 则只返回元数据,速度更快(例如 false)。 |
| limit | integer | 3传入刊物 URL 时返回近期文章的最大数量(1-100,默认 25);传入单篇文章 URL 时忽略,始终返回那一篇。按返回的文章数扣费,所以上限越低,费用越少。 |
| maxComments | integer | 'includeComments' 为 true 时每篇文章收集的最大评论数(0-500,默认 20)。不额外收费(例如 50)。 |
| minComments | integer | 只返回评论数不少于该值的文章(例如 10)。 |
| minReactions | integer | 只返回反应数不少于该值的文章(例如 100)。 |
| minWordCount | integer | 只返回字数不少于该值的文章,可过滤掉简短的笔记和公告(例如 1000)。 |
| onlyFree | boolean | 只返回免费(无付费墙)的文章(例如 true)。 |
| startDate | string | 只返回在该日期当天或之后发布的文章,格式为 YYYY-MM-DD(例如 2024-01-01)。只在扫描的最近 'limit' 篇文章中生效,因此要覆盖更早的日期范围,请调高 'limit'。 |
| 响应 | ||
| data | object | Result payload, or null when nothing was found. |
| data.items | object[] | 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[].authorBio | string | Author bio as shown on their Substack profile. |
| data.items[].authorHandle | string | Substack handle of the post author. Populated whenever the provider has data for the entity. |
| data.items[].authorImage | string | Profile photo URL of the post author. |
| data.items[].authorName | string | Display name of the post author. Populated whenever the provider has data for the entity. |
| data.items[].authorUrl | string | Substack profile URL of the post author. |
| data.items[].commentCount | integer | Number of top-level comments on the post. |
| data.items[].comments | object[] | 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[].authorHandle | string | Substack handle of the comment author. |
| data.items[].comments[].authorImage | string | Profile photo URL of the comment author. |
| data.items[].comments[].authorName | string | Display name of the comment author. |
| data.items[].comments[].authorUrl | string | Substack profile URL of the comment author. |
| data.items[].comments[].commentId | string | Substack comment identifier. |
| data.items[].comments[].createdUtc | number | UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. |
| data.items[].comments[].editedUtc | number | UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. |
| data.items[].comments[].isAuthor | boolean | Whether the comment was written by the post author. |
| data.items[].comments[].isPinned | boolean | Whether the comment is pinned by the publication. |
| data.items[].comments[].reactionCount | integer | Number of reactions on the comment. |
| data.items[].comments[].replies | object[] | Direct replies to this comment. |
| data.items[].comments[].replies[].authorHandle | string | Substack handle of the reply author. |
| data.items[].comments[].replies[].authorImage | string | Profile photo URL of the reply author. |
| data.items[].comments[].replies[].authorName | string | Display name of the reply author. |
| data.items[].comments[].replies[].authorUrl | string | Substack profile URL of the reply author. |
| data.items[].comments[].replies[].commentId | string | Substack comment identifier. |
| data.items[].comments[].replies[].createdUtc | number | UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. |
| data.items[].comments[].replies[].editedUtc | number | UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. |
| data.items[].comments[].replies[].isAuthor | boolean | Whether the reply was written by the post author. |
| data.items[].comments[].replies[].isPinned | boolean | Whether the reply is pinned by the publication. |
| data.items[].comments[].replies[].reactionCount | integer | Number of reactions on the reply. |
| data.items[].comments[].replies[].restackCount | integer | Number of times the reply was restacked. |
| data.items[].comments[].replies[].text | string | Reply body text. |
| data.items[].comments[].restackCount | integer | Number of times the comment was restacked. |
| data.items[].comments[].text | string | Comment body text. |
| data.items[].contentStatus | string | 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. |
| data.items[].createdUtc | number | 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. |
| data.items[].description | string | Short post description, usually the subtitle or an excerpt. |
| data.items[].hasVoiceover | boolean | Whether the post carries a narrated audio version. |
| data.items[].html | string | Article body as HTML. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'. |
| data.items[].image | string | Cover image URL. |
| data.items[].isPaid | boolean | Whether the post is behind a paywall. |
| data.items[].language | string | Two-letter language code of the post. |
| data.items[].markdown | string | Article body as Markdown. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'. |
| data.items[].podcastUrl | string | Audio URL for a podcast post or a narrated voiceover, when the post has one. |
| data.items[].postId | string | Substack post identifier. Populated whenever the provider has data for the entity. |
| data.items[].postType | string | Post type (newsletter, podcast, or thread). Populated whenever the provider has data for the entity. |
| data.items[].publication | object | The publication the post belongs to. |
| data.items[].publication.customDomain | string | Custom domain the publication is served on, when it has one. |
| data.items[].publication.description | string | Publication tagline or hero text. |
| data.items[].publication.id | string | Substack publication identifier. |
| data.items[].publication.image | string | Publication logo URL. |
| data.items[].publication.language | string | Two-letter language code of the publication. |
| data.items[].publication.name | string | Publication name. |
| data.items[].publication.paymentsEnabled | boolean | Whether the publication sells paid subscriptions. |
| data.items[].publication.subdomain | string | Publication subdomain on substack.com. |
| data.items[].publication.subscriberCount | integer | Subscriber count, when the publication publishes it. |
| data.items[].publication.url | string | Publication home URL. |
| data.items[].reactionCount | integer | Number of reactions (likes) on the post. |
| data.items[].replyCount | integer | Number of replies to comments on the post. |
| data.items[].restackCount | integer | Number of times the post was restacked. |
| data.items[].slug | string | Post slug, the last path segment of the post URL. Populated whenever the provider has data for the entity. |
| data.items[].subtitle | string | Post subtitle or deck. |
| data.items[].text | string | Article body as plain text. Present when 'includeContent' is true and 'contentStatus' is 'full' or 'preview_only'. |
| data.items[].title | string | Post title. Populated whenever the provider has data for the entity. |
| data.items[].updatedUtc | number | UTC epoch timestamp in seconds (Unix time). Multiply by 1000 for a JS Date in milliseconds. |
| data.items[].url | string | Canonical post URL. Populated whenever the provider has data for the entity. |
| data.items[].wordcount | integer | Approximate word count of the article. |
| found | boolean | 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. |
| 价格 | ||
| 每次请求价格(上限) | USD | US$0.0444 |
| 价格(/千条结果) | USD | US$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 对经过网关的流量的自有测量,持续重新计算,并非公开承诺的服务等级目标。