Substack 文章 API
通过 URL 抓取任意 Substack 刊物的文章,或传入单篇文章 URL(…/p/slug)只获取那一篇。返回标题、副标题、发布日期、付费墙状态、字数、互动数据(反应、评论、转发)、作者主页、刊物信息、纯文本、HTML 和 Markdown 格式的完整正文,以及可选的评论串。
US$2.62/千条结果,按请求付费,无需订阅。
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
Recommendations
{"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 个字段}
价格
Substack 文章 API 价格
试一试
一个请求获取 Substack 文章
这个示例展示了 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,每个字段一个示例值。
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.
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.
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.
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.
- 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 次调用。