REST API 参考
交互式文档
每个 Inkpage Links 实例都会发布 API 文档:
https://your-domain/_docs/openapi.json— 机器可读的 OpenAPIhttps://your-domain/_docs/scalar— 更友好的界面https://your-domain/_docs/swagger— 经典 Swagger 界面
OpenAPI 文档由服务端校验所用的同一套 schema 生成,因此始终与当前部署一致。公开实例:
第一次使用?先看 API 快速上手。
身份认证
在请求头里发送凭据:
Authorization: Bearer YOUR_TOKEN有两种凭据可用:
| 凭据 | 身份 | 权限范围 |
|---|---|---|
NUXT_SITE_TOKEN | 实例所有者(应急凭据) | 完全访问,包括实例配置 |
API 密钥(ink_…) | 具名的集成 | 仅限该密钥被授予的角色 |
创建 API 密钥
API 密钥只创建一次,令牌也只显示一次:
POST /api/api-keys/create
Authorization: Bearer YOUR_SITE_TOKEN
Content-Type: application/json
{ "name": "n8n", "role": "power-user" }{ "key": { "id": "…", "prefix": "ink_ab12cd34ef56", "role": "power-user" }, "token": "ink_…" }请立即保存该令牌 — 之后无法再取回,数据库只保留它的 SHA-256 哈希。
| 操作 | 路由 | 所需权限 |
|---|---|---|
| 列出密钥 | GET /api/api-keys | instance:config |
| 创建密钥 | POST /api/api-keys/create | instance:config |
| 撤销密钥 | POST /api/api-keys/revoke | instance:config |
密钥支持 expiresAt(Unix 秒),且永远不能持有 superadmin 角色。列出接口不会返回令牌或哈希。
也可以在 Dashboard → API keys 页面创建和撤销密钥,无需用 curl。
撤销不是即时的
认证中间件会在每个 Cloudflare 位置缓存密钥最多 60 秒,因此已撤销的令牌可能还能继续工作几秒。
速率限制
每个 API 密钥都有速率限制(默认每分钟 120 次,用 NUXT_API_KEY_RATE_LIMIT 配置);超出时返回 429 并带 Retry-After。站点令牌不受此限制。
会话与 Access
API 密钥和站点令牌不能与浏览器会话混用:启用 Cloudflare Access 后,浏览器还可以使用已验证的 Access 登录。MCP 端点 两种凭据都接受。
CORS
可选。构建时设置 NUXT_API_CORS=true,允许其他网站的浏览器调用 /api/**。仍需要登录。见配置参考。
调用链接 API 前
存储必须就绪
部署后若还没打开过 Dashboard → Links,大多数 /api/link/** 会失败,并提示 「存储未就绪」(HTTP 423)。见存储初始化。
upsert空闲时创建;短链码已存在则返回已有记录且status: "existing"(不覆盖)search匹配短链码、URL、备注和标签check从服务端探测目标 URLverify检查当前如何登录location在 Cloudflare 提供时返回大致坐标- 图片上传:
multipart/form-data格式,必须同时提供file和目标链接slug;需要 R2(JPEG/PNG/WebP/GIF,最大 5 MB)
端点分组
完整请求/响应请看 OpenAPI 界面。
| 分组 | 路由 |
|---|---|
| 链接 | /api/link/create、edit、upsert、delete、query、search、list、check、tags |
| 子域名 | /api/domains、/api/domains/create、/api/domains/update、/api/domains/delete |
| API 密钥 | /api/api-keys、/api/api-keys/create、/api/api-keys/revoke |
| 导入/导出 | /api/link/import、/api/link/export — 导入/导出 |
| 存储初始化 | /api/link/migration/status、/api/link/migration/run — 存储初始化 |
| AI | /api/link/ai、/api/link/og-ai — Workers AI |
| 访问分析 | /api/stats/**、/api/logs/** — 访问分析 |
| 实用工具 | /api/verify、/api/location、/api/upload/image、/api/backup |
| MCP | /api/mcp — MCP Server |
仪表盘能做的,API 都能做
一条链接的全部配置可以放在同一个请求里,没有任何一项只能在仪表盘里设置:
{
"url": "https://example.com/target",
"slug": "promo",
"comment": "内部备注",
"password": "访问密码",
"cloaking": true,
"unsafe": true,
"redirectWithQuery": true,
"expiration": 1798761600,
"title": "预览标题",
"description": "预览描述",
"image": "https://cdn.example.com/cover.png",
"apple": "https://apps.apple.com/app/id000000",
"google": "https://play.google.com/store/apps/details?id=com.example",
"proxy": false,
"tags": ["campaign", "q4"],
"geo": { "BR": "https://example.com/brasil", "US": "https://example.com/us" }
}cloaking让地址栏保持显示短链接,而不是暴露目标 URLpassword由服务端哈希保存;读取时返回掩码,编辑时传空字符串即可清除geo按两位国家代码分流访客image可以是公开的http(s)网址,也可以是/api/upload/image返回的内部键。内部路径上限 128 字符;绝对http(s)网址上限为标准 URL 长度限制
分页
列表接口返回不透明游标(cursor)而不是偏移量。把返回的 cursor 作为参数传入即可取下一页, 当 list_complete 为 true 时结束。每个列表使用自己的数组字段:
| 路由 | 数组字段 | 说明 |
|---|---|---|
/api/link/list | links | 另外支持 sort、tag、status |
/api/domains | domains | 另外支持 q、status |
/api/api-keys | keys | limit 上限 100,默认 50 |
{
"links": [],
"cursor": "eyJzbHVnIjoicHJvbW8ifQ==",
"list_complete": false
}list_complete 为 true 时不再返回 cursor。不要自行构造游标 — 把它当作不透明字符串。 limit 参数限制单页大小,各路由的最大值见 OpenAPI 文档。
错误
错误使用标准 HTTP 状态码。响应体包含 h3 的 statusCode 与 statusMessage,需要补充信息时 还会带 data — 校验失败会列出出错的字段:
{ "statusCode": 400, "statusMessage": "Bad Request", "data": { "issues": [] } }| 状态码 | 含义 |
|---|---|
400 | 请求体或查询参数校验失败,响应体会指出无效字段 |
401 | 凭据缺失、格式错误、已过期或已撤销 |
403 | 凭据有效,但所属角色缺少该路由所需权限 |
404 | 链接、子域名或域名不存在 |
409 | 冲突 — 短链码已占用、子域名已存在、链接被替换或无法分配短链码 |
413 | 仅限 /api/upload/image:文件超过 5 MB |
423 | 存储尚未初始化,或 D1 迁移未完成 |
429 | 超出 API 密钥速率限制;按 Retry-After 秒后重试 |
401 不会透露令牌是否存在,因此请统一按“凭据不可用”处理,直接新建密钥而不是反复试探。
示例
以下示例统一使用 https://your-domain 作为基础地址,并从环境变量读取令牌。
创建带密码保护的链接
curl -X POST https://your-domain/api/link/create \
-H "Authorization: Bearer $INKPAGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/secret-report",
"slug": "report",
"password": "visitor-password",
"cloaking": true
}'一个请求同时创建链接与子域名
/api/domains/create 的标签字段是 name,并可用 url 代替 slug。它在一个事务里创建两条记录:
curl -X POST https://your-domain/api/domains/create \
-H "Authorization: Bearer $INKPAGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "promo", "url": "https://example.com/landing" }'{ "domain": { "name": "promo", "slug": "k3f9xq", "status": "active" } }若要绑定到已存在的链接,把 url 换成 slug。两者同时传或都不传都是校验错误。
为另一个集成签发密钥
创建密钥需要所有者凭据,而不是另一个 API 密钥:
export INKPAGE_SITE_TOKEN="your_instance_site_token"
curl -X POST https://your-domain/api/api-keys/create \
-H "Authorization: Bearer $INKPAGE_SITE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "zapier", "role": "power-user", "expiresAt": 1798761600 }'批量导入链接
负载需要 version 和 links 数组,与导出格式一致:
curl -X POST https://your-domain/api/link/import \
-H "Authorization: Bearer $INKPAGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"version": "1.0",
"links": [ { "url": "https://example.com/a", "slug": "a" } ]
}'让 AI 客户端调用 API
MCP 端点使用 Model Context Protocol over HTTP,接受同样的 Bearer 令牌:
claude mcp add --transport http inkpage https://your-domain/api/mcp \
--header "Authorization: Bearer $INKPAGE_TOKEN"可用工具见集成。
版本策略
API 跟随部署版本,而不是版本号:/api/link/** 与 /api/domains/** 的字段名和语义保持稳定, 同时可能新增可选字段。请以你要接入的实例的 /_docs/openapi.json 为准 —— 它是该部署的权威约定,每次构建都会重新生成。