公开 API
当前 v1 REST API 的实际参考文档,覆盖文章、站点和 Webhook。
本页只描述当前真实对外开放的
/api/v1接口。当前 v1 公开能力仅包含文章、站点和 Webhook 管理。
快速开始
基础 URL
https://postion.app/api/v1认证方式
所有请求都必须带上 Bearer Token:
Authorization: Bearer pk_your_api_key_here新建 API Key 时,原始密钥只会展示一次。请在创建时妥善保存。
限流
每个 API Key 在每个 endpoint 上的限制是 100 次请求/分钟。响应头会包含:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset
Scope 权限
请为不同集成授予最小必要权限:
| Scope | 用途 |
|---|---|
posts:read | GET /posts、GET /posts/{id} |
posts:write | POST /posts、PUT /posts/{id} |
posts:delete | DELETE /posts/{id} |
sites:read | GET /sites |
webhooks:read | GET /webhooks |
webhooks:write | POST /webhooks |
响应约定
大多数成功响应都使用 data 包裹:
{
"data": {}
}列表接口还会返回分页信息:
{
"data": [],
"pagination": {
"page": 1,
"limit": 10,
"total": 42,
"pages": 5
}
}校验失败或权限失败时会返回 error 字段,部分接口还会带上 details 或 resetTime。
接口列表
GET /api/v1/posts
获取当前 API Key 所属用户的文章列表。
查询参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
page | integer | 1 | 最小值为 1 |
limit | integer | 10 | 取值范围 1-100 |
siteId | string | - | 只查询某个站点 |
published | boolean | - | 使用 true 或 false |
search | string | - | 在标题和描述中做不区分大小写搜索 |
示例
curl "https://postion.app/api/v1/posts?page=1&limit=10&published=true" \
-H "Authorization: Bearer pk_your_api_key_here"返回的每条文章包含:
id、title、description、slug、imagestatus、published、public、isPaidpricingsitetagsstats.likes、stats.comments、stats.bookmarkscreatedAt、updatedAt
POST /api/v1/posts
在你拥有的站点下创建文章。
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
title | string | 是 | 最大长度 200 |
siteId | string | 是 | 必须属于当前 API Key 的拥有者 |
content | JSON | 否 | 富文本 JSON 或你自己的 JSON 结构 |
description | string | 否 | 简要摘要 |
slug | string | 否 | 不传时会根据标题自动生成 |
image | string | 否 | 必须是合法 URL |
status | string | 否 | 默认值 draft |
published | boolean | 否 | 默认走模型默认值 |
tags | string[] | 否 | 不存在的标签会自动创建 |
public | boolean | 否 | 默认值 true |
isPaid | boolean | 否 | 默认值 false |
pricing.price | number | 否 | 传 pricing 时必填 |
pricing.currency | string | 否 | 3 位货币码,默认 USD |
pricing.isPaid | boolean | 否 | 默认值 false |
pricing.previewLength | integer | 否 | 预览长度 |
说明
- slug 在同一个站点内必须唯一,冲突时会返回
409 Conflict。 - 如果只传
status: "published"或status: "draft",没有单独传published,API 会自动同步对应的布尔值。 - 如果标题无法生成可用 slug,系统会回退到自动生成的 slug。
pricing中的金额在响应里可能会以字符串形式返回,因为底层使用 Decimal 序列化。
示例
{
"title": "API 上线检查清单",
"siteId": "site_123",
"description": "公开 API 发布前需要确认的事项",
"published": true,
"tags": ["api", "launch"],
"public": true
}GET /api/v1/posts/{id}
获取单篇文章详情,返回完整的 content、tags、pricing、site 和 stats。
PUT /api/v1/posts/{id}
更新你拥有的文章。
当前支持更新的字段:
titlecontentdescriptionslugimagestatuspublishedtags
如果请求体里带了 tags,系统会用你传入的标签列表完整替换原有标签。如果只更新 status 为 draft 或 published,没有单独传 published,API 也会自动同步这个布尔字段。
DELETE /api/v1/posts/{id}
软删除文章,响应如下:
{
"message": "Post deleted successfully"
}GET /api/v1/sites
列出当前用户拥有的站点。
每个站点会返回:
id、name、description、logosubdomain、customDomaincreatedAt、updatedAtstats.posts
GET /api/v1/webhooks
列出当前用户配置的 Webhook。
查询参数
| 参数 | 类型 | 说明 |
|---|---|---|
siteId | string | 可选,按站点过滤 |
响应包含:
data:Webhook 列表availableEvents:支持的事件类型
出于安全考虑,列表接口不会返回 Webhook secret。
POST /api/v1/webhooks
创建一个新的 Webhook。
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 最大长度 100 |
url | string | 是 | 必须是合法 URL |
events | string[] | 是 | 至少包含一个支持的事件 |
siteId | string | 否 | 只接收某个站点的事件 |
headers | object | 否 | 每次投递附带的自定义字符串头 |
retryCount | integer | 否 | 取值范围 0-10 |
timeoutSeconds | integer | 否 | 取值范围 5-300 |
当前支持的事件
post.createdpost.publishedpost.deleteduser.registereduser.updatedsite.createdsubscription.createdsubscription.cancelledtest.event
创建成功的响应中会返回 webhook 的 secret。请在创建时保存,因为后续的列表接口不会再次返回它。
Webhook 投递
平台会对出站 Webhook 进行签名,签名头为 X-Webhook-Signature,算法为基于原始请求体的 HMAC-SHA256。
每次投递都会带上这些请求头:
X-Webhook-SignatureX-Webhook-EventX-Webhook-DeliveryUser-Agent: Position-Webhooks/1.0
Payload 结构如下:
{
"id": "delivery_payload_id",
"event": {
"type": "post.published",
"data": {},
"timestamp": "2026-04-04T12:00:00.000Z",
"site_id": "site_123",
"user_id": "user_123"
},
"webhook": {
"id": "webhook_123",
"name": "Production Listener"
}
}更完整的签名校验和处理示例,请查看 Webhooks。
错误码
| 状态码 | 含义 |
|---|---|
400 | 参数校验失败或查询参数不合法 |
401 | API Key 缺失、无效或已过期 |
403 | API Key 没有对应 scope |
404 | 资源不存在,或不属于当前 API Key 的拥有者 |
409 | 文章 slug 冲突 |
429 | 命中限流 |
500 | 服务内部错误 |
接入建议
- API Key 只放在服务端,不要放到前端代码里。
- 创建 Webhook 时立即保存 secret。
- 对自动化场景,尽量优先使用 Webhook,而不是轮询。
DELETE /posts/{id}是软删除,不会做物理删除。
版本策略
API 通过 URL 路径做版本控制。破坏性变更会在新版本路径中发布,例如 /api/v2。