Paragraph API 是 Paragraph(一个 web3 出版与 newsletter 平台)提供的 REST API 与 TypeScript SDK,用于在不安装任何 CLI 工具的情况下管理文章、出版物、订阅者与代币。若需要 CLI 或 MCP 访问,应改用 paragraph-cli 技能。
接口选择
提供两种接口:REST API 无需安装,适合任意语言、curl 与快速脚本;TypeScript SDK 需执行 npm install @paragraph-com/sdk,适合需要类型安全的 TypeScript/JavaScript 项目。
认证
在出版物设置中生成 API 密钥。许多读取端点是公开的,无需密钥;写入端点(创建、更新、删除文章,管理订阅者等)需要认证。REST API 以 Bearer token 传递密钥,例如:
curl https://public.api.paragraph.com/api/v1/me
-H "Authorization: Bearer <api-key>"
TypeScript SDK 中,公开端点可直接 new ParagraphAPI(),认证端点需传入 apiKey:new ParagraphAPI({ apiKey: "<api-key>" })。
工作约定
未经用户明确批准不得发布。发布会使内容上线,并可选向订阅者发送邮件。默认创建草稿,除非显式设置 status: "published"。未经用户明确批准不得发送自定义邮件,api.emails.send(及 POST /v1/emails/send)会发送真实邮件且不可撤销;应先起草主题与正文,使用 dryRun: true 预览过滤结果后再真实发送;遇到 403 应提示“该出版物尚未获准使用自定义邮件”并停止,不要重试。草稿内容不会发送,api.content(及 /v1/content)只写入出版物的内容库,不会发布到 X 或 LinkedIn、不会发邮件、不会定时,需由作者在 Paragraph 应用中发送。分页使用 cursor,响应包含 pagination.cursor 与 pagination.hasMore。遵守速率限制,遇到 429 应退避重试,避免分页请求间紧密循环。写入前检查认证,调用 GET /v1/me 或 api.me.get() 验证凭据有效。
TypeScript SDK 主要能力
安装:npm install @paragraph-com/sdk
文章(Posts)
支持创建草稿、列出文章(可按 status 过滤)、按 ID 或 slug 获取单篇、按出版物分页获取、更新标题与内容、发布(设置 status: "published",可选 sendNewsletter: true 发送 newsletter)、定时发布(scheduledAt)、取消定时(scheduledAt: null)、回溯发布日期(publishedAt)、设置或替换封面图(imageUrl,URL 会被抓取并重新托管到 Paragraph CDN,并生成占位图)、移除封面图(clearImage: true)、按 ID 或 slug 删除、发送测试 newsletter 邮件(仅草稿)、获取 feed 与按标签获取文章。
内容(Content)
出版物的短内容库:X 帖子与线程、LinkedIn 帖子、一次性邮件与 X Articles。此处所有内容均为草稿,创建或编辑不会发布、发邮件或定时。长文 Paragraph 文章属于不同资源,应使用 api.posts。kind 可为 tweet、linkedin、newsletter、x_article。body 采用对应 kind 的结构,校验方式与 Paragraph 应用一致。通过 API 创建的草稿仅支持文本,媒体需先上传到 X 或 LinkedIn,API 暂不支持。支持创建、列表(按最新活动排序,不含正文)、读取单条(含正文,编辑前应先读取)、编辑(body 会完全替换原内容,需发送完整内容)、重命名(即使排队发送已锁定文字也始终允许)、归档与恢复。列表的 status 默认 all,即除已归档外的全部;已投递的内容无论是否归档都会列出。lockedReason 说明当前为何无法编辑,为 null 表示可编辑;排队或发送中的内容会锁定文字,需先在应用中取消定时。
内容分组(Content groups)
一个分组是某篇文章及其衍生内容的统一身份——文章、由其生成的 X 线程、LinkedIn 版本、newsletter。在 Paragraph 应用的 Content 下显示为单行堆叠。在复用文章时,应将草稿归入同一分组:从文章播种分组,然后在每个衍生内容上传递 id 作为 bucketId。否则作者会得到互不相关的草稿。支持为文章获取或创建分组(可重复调用,返回相同 id)、读取分组、将已有草稿归入分组、查找文章分组而不创建、列出所有分组。每个内容在读写时都会报告其 bucketId。成员的 kind 指示读取方式:post 用 api.posts.get({ id }),content 用 api.content.get({ id });kind 为 other 表示 Paragraph 已分组但 API 无法获取。已归入其他文章的内容会返回 409 而非移动,需提示用户在应用中取消分组;从分组中移除内容需在应用中进行,API 不支持。
出版物(Publications)
支持按 ID、slug(如 @my-blog)或域名获取出版物。更新拥有 API 密钥的出版物的设置,仅更改提供的字段:名称、摘要、主题色、标题字体;精选文章(featuredPost,接受 "latest"、"popular"、"disabled" 或文章 ID,指定 ID 必须属于该出版物);置顶文章(pinnedPostIds,替换现有列表,上限 50 个 ID,每个 ID 必须属于该出版物);邮件通知(emailNotifications,合并到当前设置,仅更改发送的开关)。
订阅者(Subscribers)
支持列表(分页)、计数、添加(邮箱或钱包)、移除(硬删除,不可逆;至少提供邮箱或钱包之一,若同时提供必须指向同一用户)、导入 CSV。
代币(Coins)
支持按 ID 或合约地址获取代币信息、热门代币、持有者(按 ID 或合约地址)、价格报价(金额以 wei 计)、买入与卖出(需要 viem WalletClient 与 Account)。
搜索(Search)
支持搜索文章、博客与代币。
用户(Users)
支持按 ID 或钱包获取用户。
我(Me)
使用 API 密钥获取自己的出版物信息。
自定义邮件(Custom emails)
从出版物向指定收件人列表发送一次性 markdown 邮件。每位收件人单独收到,带强制退订页脚(使用与 newsletter 相同的投递管道)。适用场景:定向分群发送(如“给打开上一篇的所有人发邮件”“跟进最活跃的 50 位订阅者”“联系精选的 20 位读者”),可通过 api.analytics.query 或 api.subscribers.get 构建分群;向作者本人发送通知(如“订阅者达到 1000 时邮件我”“每周分析摘要”),可配合 api.me.get() 查找作者邮箱;向非订阅者地址外联(如会议联系人 CSV、媒体名单、朋友的朋友),收件人可来自任何地方,不必在 api.subscribers.get() 中(曾退订者仍会被抑制);重新激活不活跃订阅者(如“给 90 天未打开的人发邮件”),可通过 api.analytics.query 针对 subscriber_engagement_scores 或 newsletter_metrics 识别分群;向少数协作者发送草稿评审(如“把草稿提案发给 3 位合著者征求意见”),当需要发给出版物所有者以外的人时使用,api.posts.sendTestEmail 仅发给所有者。不要用于 newsletter 群发:要向所有订阅者发送文章邮件,应在 api.posts.create 或 api.posts.update 上设置 sendNewsletter: true,那是 newsletter 管道;api.emails.send 用于你提供的定向列表。资格:出版物必须经 Paragraph 批准才能使用自定义邮件,不符合条件的出版物会收到 403。逐收件人过滤在服务端进行:格式错误的地址返回 invalid,先前退订返回 suppressed,队列失败返回 scheduling_failed(唯一可安全重试的原因)。上限:每次调用最多 10,000 名收件人。发送前务必确认:邮件真实发出且不可撤销,应先起草主题与正文,再调用发送;使用 dryRun: true 预览接受/跳过情况而不实际发送。
认证(基于浏览器的登录)
适用于需要在不使用 API 密钥的情况下认证的 CLI 或无头客户端:创建认证会话,返回用户在浏览器中打开的 URL。
适用场景与限制
适用于通过 REST API 或 TypeScript SDK 以编程方式管理 Paragraph 平台的文章、草稿内容、出版物、订阅者与代币,尤其适合需要类型安全的 TypeScript/JavaScript 项目、快速脚本、定向邮件发送与内容复用分组。限制包括:写入端点需要认证;发布与发送邮件需用户明确批准;草稿内容不会自动发布或发送;通过 API 创建的内容草稿仅支持文本,媒体需先上传到 X 或 LinkedIn;自定义邮件需出版物获准,否则返回 403;每次自定义邮件最多 10,000 名收件人;从分组中移除内容需在应用中进行;分页需使用 cursor,遇 429 需退避重试。