标准 API 接口文档
Short_NURL v1.11.0 面向浏览器前端的标准 API 接入指南
占位符约定
| 占位符 | 含义 | 示例 |
|---|---|---|
{你的域名} | 短链服务部署域名 | s.example.com |
{su_你的Key} | 常驻或一次性 API Key | su_aBcDeFgH1234... |
{目标长链接} | 要缩短的公网 HTTP(S) URL | https://example.com/path |
{短链后缀} | 普通 Key 可用的 1-4 位短码 | a1b2 |
{ISO 8601 过期时间} | 带时区偏移的过期时间 | 2026-05-20T12:00:00+08:00 |
一、路由与认证
标准 API 的业务路由为:
| 方法 | 路径 | 用途 |
|---|---|---|
GET | /api/ping | 无认证健康检查 |
POST | /api/create | 创建短链 |
POST | /api/delete | 删除短链 |
GET | /api/list | 查询短链列表 |
GET | /api/stat | 查询冷/热存储计数与配额 |
除 /api/ping 外,标准链路只从以下来源提取凭证:
X-Token请求头,优先级最高,GET/POST 均可使用。- JSON 请求体中的字符串字段
key,仅在没有X-Token时使用。 X-Headless-Token在标准链路中不会被接受。
因此 POST 示例可以继续把 Key 放在请求体中,但统一封装时也可以全部使用 X-Token。若两处同时提供,服务器只验证 X-Token,不会在其无效时回退到 body.key。
Key 类型与限制
| Key 类型 | 有效期/次数 | 标准 API 权限 |
|---|---|---|
| 常驻 Key(resident) | 默认 7 天,不限次数 | 创建、删除、列表、统计 |
| 一次性 Key(onetime) | 使用前不过期,验证成功时立即消费 | 创建;删除、列表、统计返回 403 |
| 服务 Key(service) | 永不过期,不限次数 | 禁止使用,返回 406;仅供无头链路 |
一次性 Key 在公共 bootstrap 的认证阶段就被原子消费,早于业务参数校验。因此只要凭证已成功提取并验证,后续的坏 JSON、字段类型错误、无效 URL、配额已满、后缀冲突、403/4xx/5xx,以及创建去重命中,均不会退还该 Key。坏 JSON 无法提供可提取的 body.key,此时只有随 X-Token 发送的 Key 才会先被消费。创建成功响应中的 key_consumed: true 只是明确告知已消费;没有成功响应时也可能已经消费。
Key 明文只在 CLI 生成时显示。服务端仅保存 SHA-256 哈希和前缀;比较使用 hash_equals。一次性池不会自动补充,需要通过 CLI 维护。
二、健康检查
GET /api/ping{ "ok": true }该端点直接由 api/ping.php 输出,不加载业务 bootstrap,因此无需 Key,不检查数据文件、domain、panel_enabled,也不设置业务 CORS 头。它只证明 PHP-FPM 与该路由可用,不证明短链存储、认证或 OpenResty 热存储正常。
三、创建短链
POST /api/create
Content-Type: application/json
X-Token: {su_你的Key}{
"url": "{目标长链接}",
"ttl": 0,
"code": "demo"
}也可省略 X-Token,在请求体中加入 "key": "{su_你的Key}"。
Prop
Type
四、删除短链
POST /api/delete
Content-Type: application/json
X-Token: {su_你的Key}{ "code": "{短链后缀}" }code 必须存在且为字符串,trim 后不能为空,随后转为小写。该接口不再次做 1-4 位正则校验,而是按值查询冷存储。一次性 Key 已在认证阶段消费,随后会返回 403。
{ "ok": true, "synced": true }删除先提交冷存储,再调用内部接口删除热存储。synced=false 表示冷存储已删除但热存储同步失败,不回滚冷存储。
| 状态码 | error |
|---|---|
400 | 无效的请求体 |
400 | 短链后缀必须为字符串 |
400 | 缺少短链后缀 |
403 | 一次性密钥无权进行短链管理 |
404 | 该短链不存在 |
430 | 数据文件不可访问,请检查文件权限 |
500 | 数据文件损坏,请检查服务端日志 |
500 | 服务器内部错误 |
五、查询列表
GET /api/list
X-Token: {su_你的Key}{
"permanent": [
{ "id": "a1b2", "url": "https://example.com/", "lurl": "https://{你的域名}/a1b2", "exp": "permanent" }
],
"temporary": [
{ "id": "demo", "url": "https://example.com/page", "lurl": "https://{你的域名}/demo", "exp": "{ISO 8601 过期时间}" }
]
}列表直接读取冷存储;永久条目的 exp 固定为 "permanent",临时列表过滤已过期条目,但不会仅因查询而把过期条目写回删除。一次性 Key 返回 403。存储损坏返回结构化 500。
六、查询统计
GET /api/stat
X-Token: {su_你的Key}{
"perm_count": 12,
"temp_count": 3,
"perm_limit": 10000,
"temp_limit": 500,
"hot_available": true,
"hot_perm_count": 12,
"hot_temp_count": 3
}| 字段 | 权威性与含义 |
|---|---|
perm_count | 冷存储有效永久条目数,业务权威值 |
temp_count | 冷存储未过期临时条目数,业务权威值 |
perm_limit / temp_limit | 普通 Key 配额配置,不是服务 Key 专用配额 |
hot_available | /internal/stat 是否成功返回 |
hot_perm_count / hot_temp_count | 仅热存储可用时出现,只用于诊断漂移 |
热存储不可用时仍返回 200,hot_available 为 false,并省略两个 hot_*_count 字段。一次性 Key 返回 403。
七、通用错误与 430
标准链路错误体为:
{ "error": "中文描述" }430 检查发生在认证之前,客户端收到的消息固定为:
{ "error": "数据文件不可访问,请检查文件权限" }具体失败文件名只写服务器日志,不再暴露给客户端。检查范围默认是 perm.json、temp.json、keys.json:文件存在时要求可读且可写;文件不存在时要求父目录存在且可写。不要依赖固定的 666/777 数字权限,实际要求取决于 PHP-FPM 用户、属主、组和挂载方式。
panel_enabled=false 会在数据检查和认证之前让标准业务 API 返回 403:
{ "error": "前端面板未启用" }/api/ping 不受该开关影响。
八、CORS
标准业务 API 的 bootstrap 设置:
Access-Control-Allow-Origin: {panel_origin 或 domain}
Access-Control-Allow-Headers: Content-Type, X-Token
Access-Control-Allow-Methods: GET, POST, OPTIONS允许源优先取 config.php 的 panel_origin;为空时才回退到短链 domain。它应配置为实际前端面板 Origin,而不是默认理解为短链域名。业务路由的 OPTIONS 由 PHP 返回 204 No Content,但前提是 panel_enabled=true;开关关闭时会先返回 403。无头 API 不设置 CORS。/api/ping 也不加载这组 CORS 头。
示例 Nginx 使用 limit_except GET/POST。是否允许 OPTIONS 到达 PHP 取决于最终部署配置;若 Nginx 在 PHP 前拒绝预检,即使 bootstrap 支持 204,浏览器跨域调用仍会失败。