YOURLS 1.10.6 API 使用详解
YOURLS 1.10.6 内置 REST API 实战详解:认证方式(用户名密码与 1.10.5 起新 sha256 签名 token)、shorturl/stats/db-stats/url-stats/expand/version 六大 action 参数与实测响应、分页过滤与输出格式、错误码汇总与常见问题排查,全部回显为 Ubuntu 22.04 服务器实测真实结果。
YOURLS 1.10.6 API 使用详解
目标:完整覆盖 YOURLS 1.10.6 内置 REST API 的 6 个 action——认证方式(含 1.10.5 起的新签名机制)、参数、实测响应与错误码,每条请求与回显均为 2026-10-30 在 Ubuntu 22.04 服务器实测真实结果(实例部署见 《YOURLS 1.10.6 Docker Compose 部署指南》)。
一、环境信息
- 操作系统:Ubuntu 22.04(IP 192.168.1.200);
- YOURLS:1.10.6(Apache 2.4.69 + PHP 8.5.12,MySQL 8.0);
- API 端点:
http://192.168.1.200:8134/yourls-api.php; - 实例模式:私密模式(
YOURLS_PRIVATE=true默认值,参数见 《YOURLS 1.10.6 配置参数详解》); - 演示账号:
admin/q1w2e3r4; - 客户端工具:curl(任意 Linux 发行版自带)。
二、前置条件
- 一个可用的 YOURLS 1.10.6 实例(部署见本专栏部署篇);
- 端点确认:API 入口固定为应用根目录下的
yourls-api.php,先验证可达性:
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.1.200:8134/yourls-api.php
实测回显:
200
- 私密模式下需预先取得两套凭据之一:管理账号(用户名+密码)或 Secret signature token(登录后台
admin/tools.php页面查看,官方标注「Your secret signature token」)。
三、API 总览
YOURLS 内置 REST API 的全貌(action 清单来自源码 includes/functions-api.php 实查,2026-10-30):
| action | 功能 | 核心参数 |
|---|---|---|
shorturl | 创建短链 | url(必填)、keyword(可选自定义短码)、title(可选标题) |
stats | 短链列表统计 | filter(排序筛选)、limit(条数)、start(偏移) |
db-stats | 全局统计 | 无 |
url-stats | 单条短链统计 | shorturl(短码或完整短链) |
expand | 短码还原长链 | shorturl |
version | 查询 YOURLS 版本 | 无 |
统一约定:
- 协议与入口:HTTP(S) 单端点
yourls-api.php,全部参数走查询串或表单(POST/GET 均可,含敏感凭据时建议 POST); - 输出格式:
format参数支持json(默认建议)、xml、jsonp、simple四种(源码yourls_api_output的取值集合实查); - 认证:私密模式下每次请求必须携带凭据(见第四节),公开模式(
YOURLS_PRIVATE=false)下无需; - 限流:内置 API 无内建限流机制,高频调用方需自行节流(如需强限流可装社区插件或在反向代理层实现);
- 能做的与不能做的:内置 action 仅「创建 + 各类查询」,没有编辑与删除短链的 API——这两类操作走管理后台 UI 或安装社区插件补齐。这与 Shlink 的 CRUD 全集 API 形成鲜明对比(对比分析见 《Shlink 5.1.8 REST API 与 CLI 命令详解》,极简派参考 《Chhoto URL 7.10.3 REST API 使用详解》)。
四、认证与首次调用
4.1 方式一:用户名 + 密码参数
最直接的方式:每次请求带 username 与 password 参数。首次调用(查询全局统计):
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=db-stats' --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{"db-stats":{"total_links":7,"total_clicks":1},"statusCode":"200","message":"success"}
凭据错误或缺失时的统一拒绝形态:
curl -s -w '\nHTTP:%{http_code}\n' "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=db-stats' --data-urlencode 'format=json'
实测回显:
{"message":"Please log in","errorCode":"403","callback":""}
HTTP:403
4.2 方式二:signature token 签名(1.10.5 起新机制)
不想把账号密码传给第三方调用方时,用后台 Tools 页的 Secret signature token。1.10.5 起 md5 签名已弃用,当前规则(源码 functions-auth.php 实查):默认哈希算法 sha256,允许 sha256/sha384/sha512(可用 hash 参数指定),签名公式为 sha256(timestamp + token),timestamp 有效期与登录 nonce 一致(默认约 ±一个 nonce 生命周期)。
先实测「旧 md5 写法已被拒」(排障要点——大量老教程仍是 md5):
TS=$(date +%s)
SIG_MD5=$(python3 -c "import hashlib; print(hashlib.md5(('$TS'+'admin'+'q1w2e3r4').encode()).hexdigest())")
curl -s "http://192.168.1.200:8134/yourls-api.php?action=db-stats&format=json×tamp=$TS&signature=$SIG_MD5"
实测回显(md5 计算的签名不再被接受):
{"message":"Please log in","errorCode":"403","callback":""}
正确的 sha256 签名调用(token 取自后台 Tools 页,本文实例为 200dba9cfd92ef3ec78d00b38863462d):
TS=$(date +%s)
SIG=$(python3 -c "import hashlib; print(hashlib.sha256(('$TS'+'200dba9cfd92ef3ec78d00b38863462d').encode()).hexdigest())")
curl -s "http://192.168.1.200:8134/yourls-api.php?action=db-stats&format=json×tamp=$TS&signature=$SIG"
实测回显:
{"db-stats":{"total_links":7,"total_clicks":1},"statusCode":"200","message":"success"}
💡 技术拓展:API 凭据传递的常见三种流派——每次请求传用户名密码(YOURLS 方式一,简单但凭据暴露面大)、静态签名 token(YOURLS 方式二,token 只能用于 API 不能登录后台,泄露面更小)、带时效的动态签名(YOURLS 的
timestamp + signature,兼顾防重放)。生产对外发 API 凭据时优先用方式二的签名 token,并为不同调用方各发一个独立账号。
五、各 API 域详解
5.1 shorturl:创建短链
参数:action=shorturl、url(长链,必填)、keyword(自定义短码,可选)、title(标题,可选)、format。
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'url=https://www.quzuo.net/' \
--data-urlencode 'title=Quzuo 主站' \
--data-urlencode 'keyword=quzuo' \
--data-urlencode 'action=shorturl' --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{
"status": "success",
"code": "",
"message": "https://www.quzuo.net/ added to database",
"errorCode": "",
"statusCode": "200",
"url": {
"keyword": "quzuo",
"url": "https://www.quzuo.net/",
"title": "Quzuo \u4e3b\u7ad9",
"date": "2026-10-30 07:21:34",
"ip": "192.168.1.200"
},
"title": "Quzuo \u4e3b\u7ad9",
"shorturl": "http://192.168.1.200:8134/quzuo"
}
关键错误——重复长链返回 409 Conflict(1.10.5 起从 400 改为 409):
curl -s -w '\nHTTP:%{http_code}\n' "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'url=https://www.quzuo.net/' \
--data-urlencode 'action=shorturl' --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{"status":"fail","code":"error:url","message":"https:\/\/www.quzuo.net\/ already exists in database (short URL: 192.168.1.200:8134\/quzuo)","errorCode":"409","statusCode":"409","url":{"keyword":"quzuo","url":"https:\/\/www.quzuo.net\/","title":"Quzuo \u4e3b\u7ad9","date":"2026-10-30 07:21:34","ip":"192.168.1.200","clicks":1},"title":"Quzuo \u4e3b\u7ad9","shorturl":"http:\/\/192.168.1.200:8134\/quzuo"}
HTTP:409
(YOURLS_UNIQUE_URLS=false 时不触发 409,同一长链可重复建码,配置见配置篇 5.3 节实测。)
5.2 stats:短链列表统计
参数:action=stats、filter(top 按点击降序 / last 按时间最新 / bottom 按点击升序 / rand 随机)、limit(返回条数)、start(分页偏移)。
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=stats' --data-urlencode 'filter=last' \
--data-urlencode 'limit=2' --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显(json.tool 格式化展示,响应尾部含 statusCode/message):
{
"links": {
"link_1": {
"shorturl": "http://192.168.1.200:8134/3",
"url": "https://example.org/test-3",
"title": "Example Domain",
"timestamp": "2026-10-30 07:23:36",
"ip": "192.168.1.200",
"clicks": 0
},
"link_2": {
"shorturl": "http://192.168.1.200:8134/2",
"url": "https://example.org/test-2",
"title": "Example Domain",
"timestamp": "2026-10-30 07:23:35",
"ip": "192.168.1.200",
"clicks": 0
}
},
"stats": {"total_links": 7, "total_clicks": 1},
"statusCode": "200",
"message": "success"
}
filter=bottom 实测(取点击最少的 2 条):
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=stats' --data-urlencode 'filter=bottom' \
--data-urlencode 'limit=2' --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{"links":{"link_1":{"shorturl":"http:\/\/192.168.1.200:8134\/ozh","url":"https:\/\/ozh.org\/","title":"ozh.org","timestamp":"2026-10-30 07:20:39","ip":"10.89.59.1","clicks":0},"link_2":{"shorturl":"http:\/\/192.168.1.200:8134\/yourlsblog","url":"https:\/\/blog.yourls.org\/","title":"YOURLS' Blog","timestamp":"2026-10-30 07:20:39","ip":"10.89.59.1","clicks":0}},"stats":{"total_links":7,"total_clicks":1},"statusCode":"200","message":"success"}
5.3 db-stats:全局统计
参数仅 action 与 format。这是最小的一个 action,也是验证认证是否打通的探针(见 4.1 节实测):
{"db-stats":{"total_links":7,"total_clicks":1},"statusCode":"200","message":"success"}
5.4 url-stats:单条短链统计
参数:shorturl(短码 quzuo 或完整短链 URL 均可):
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=url-stats' --data-urlencode 'shorturl=quzuo' \
--data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显(中文标题以 \u4e3b\u7ad9 形式转义返回,为 API 原始输出):
{"statusCode":"200","message":"success","link":{"shorturl":"http:\/\/192.168.1.200:8134\/quzuo","url":"https:\/\/www.quzuo.net\/","title":"Quzuo \u4e3b\u7ad9","timestamp":"2026-10-30 07:21:34","ip":"192.168.1.200","clicks":1}}
短码不存在时的错误形态:
curl -s -w '\nHTTP:%{http_code}\n' "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=url-stats' --data-urlencode 'shorturl=noexist9z' \
--data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{"statusCode":"404","message":"Error: short URL not found"}
HTTP:404
5.5 expand:还原长链
参数:shorturl(短码或完整短链):
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=expand' --data-urlencode 'shorturl=quzuo' \
--data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{"keyword":"quzuo","shorturl":"http:\/\/192.168.1.200:8134\/quzuo","longurl":"https:\/\/www.quzuo.net\/","title":"Quzuo \u4e3b\u7ad9","message":"success","statusCode":"200"}
5.6 version:查询版本
需要认证(未认证返回 403,实测见下):
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=version' --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{"version":"1.10.6"}
六、分页、过滤与输出格式通用约定
- 分页:仅
stats支持,limit(默认 10,源码函数签名yourls_api_stats($filter = 'top', $limit = 10, $start = 0))+start(跳过前 N 条)组合翻页;db-stats/url-stats无分页概念; - 过滤排序:
filter四个取值top(点击降序,默认,实测quzuo因 clicks=1 排首位)/last(时间倒序)/bottom(点击升序)/rand(随机),实测 5.2 节已验证last/bottom/top/rand全部取值; - 输出格式切换:同一请求换
format即得不同形态,format=xml实测:
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'action=db-stats' --data-urlencode 'format=xml' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
<?xml version="1.0" encoding="UTF-8"?>
<root><db-stats><total_links>7</total_links><total_clicks>1</total_clicks></db-stats><statusCode>200</statusCode><message>success</message></root>
format=simple 输出无格式的纯文本(只回显 simple 键值,适合脚本取值),format=jsonp 需配 callback 函数名用于浏览器跨域。
错误码汇总(全部实测确认):
| HTTP 状态码 | 触发场景 | 响应体特征 |
|---|---|---|
| 200 | 成功 | "statusCode":"200" + 对应数据 |
| 400 | action 缺失或未知 | {"errorCode":"400","message":"Unknown or missing \"action\" parameter"} |
| 403 | 凭据缺失/错误/签名过期 | {"message":"Please log in","errorCode":"403"} |
| 409 | 长链已存在且 YOURLS_UNIQUE_URLS=true | "status":"fail","code":"error:url","errorCode":"409" |
| 404 | url-stats 短码不存在 | {"statusCode":"404","message":"Error: short URL not found"} |
400 形态实测(不带 action):
curl -s "http://192.168.1.200:8134/yourls-api.php" --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{"errorCode": "400", "message": "Unknown or missing \"action\" parameter"}
七、常见问题
Q1:老脚本用 md5 签名突然全部 403?
1.10.5 弃用 md5(本文 4.2 节实测老写法被拒),改用 sha256(timestamp + token);确有 md5 依赖且能接受风险时,可用插件通过 allowed_hash_algos 过滤器重新放行(源码注释明确该扩展点),但强烈建议直接升级调用方。
Q2:如何删除或修改一条短链? 内置 API 没有这两个 action(源码 functions-api.php 实查仅 6 个)。临时改用后台 UI 操作;自动化场景安装社区 API 扩展插件(官方 awesome 列表有收录 delete/edit 类插件)。
Q3:signature token 泄露了怎么办?
token 与 YOURLS_COOKIEKEY 盐和账号体系绑定,修改 YOURLS_COOKIEKEY(容器 env 或 config.php)并重启服务即可使所有旧 token 与会话失效,再到 Tools 页取新 token。
Q4:API 创建的短链打不开?
短链域名前缀来自 YOURLS_SITE(响应里 shorturl 字段可见),YOURLS_SITE 与实际访问地址不一致就会出现「API 说建成了、浏览器打不开」的现象——排查配置见配置篇 Q3。
Q5:想批量导入已有短链数据?
API 逐条调用 shorturl 即可(注意 409 处理);更高效的方式是直接写库(yourls_url 表结构见配置篇 5.1 节实测),批量后无需重启。
八、参考链接
- 官方 API 文档:https://yourls.org/docs/guide/essentials/api
- 免签名 token 进阶(Passwordless API):https://yourls.org/docs/guide/advanced/passwordless-api
- 源码 API 实现:https://github.com/YOURLS/YOURLS/blob/master/includes/functions-api.php
- 站内关联:《YOURLS 1.10.6 Docker Compose 部署指南》、《YOURLS 1.10.6 配置参数详解》、《YOURLS 1.10.6 介绍与选型指南》