API 参考
基础 URL: https://open.utm.bar/v1
认证方式: Authorization: Bearer sk_live_xxxx 或 X-API-Key: sk_live_xxxx
短链接
创建短链接
POST /v1/links
所需权限: links:write
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
original_url | string | ✅ | 目标跳转 URL |
title | string | — | 链接展示名称 |
custom_code | string | — | 自定义短码(a-z A-Z 0-9 - _,长度 2–64) |
external_id | string | — | 外部系统引用 ID,透传存储(最大 255 字符) |
expires_at | ISO 8601 | — | 过期时间,null 表示永不过期 |
utm_source | string | — | UTM source 参数 |
utm_medium | string | — | UTM medium 参数 |
utm_campaign | string | — | UTM campaign 参数 |
utm_term | string | — | UTM term 参数 |
utm_content | string | — | UTM content 参数 |
curl -X POST https://open.utm.bar/v1/links \
-H "Authorization: Bearer sk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{
"original_url": "https://example.com/page",
"title": "我的链接",
"custom_code": "launch-2026",
"utm_source": "twitter",
"utm_medium": "social"
}'
响应 201 Created
{
"data": {
"id": "...",
"code": "launch-2026",
"short_url": "https://utm.bar/launch-2026",
"original_url": "https://example.com/page",
"title": "我的链接",
"is_active": true,
"click_count": 0,
"external_id": "order_98765",
"expires_at": null,
"utm_source": "twitter",
"utm_medium": "social",
"created_at": "2026-05-25T00:00:00Z"
}
}
自定义短码冲突时返回
409 Conflict。
列出短链接
GET /v1/links
所需权限: links:read
查询参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
page | integer | 1 | 页码 |
page_size | integer | 20 | 每页条数(最大 100) |
q | string | — | 按标题或目标 URL 搜索 |
is_active | boolean | — | 按启用/禁用状态过滤 |
curl "https://open.utm.bar/v1/links?page=1&page_size=20" \
-H "Authorization: Bearer sk_live_xxxx"
响应 200 OK
{
"data": {
"items": [ /* 链接对象数组 */ ],
"total": 42,
"page": 1,
"page_size": 20
}
}
获取单条链接
GET /v1/links/:code
所需权限: links:read
curl https://open.utm.bar/v1/links/launch-2026 \
-H "Authorization: Bearer sk_live_xxxx"
响应 200 OK — 返回单个链接对象。
按 External ID 获取链接
GET /v1/links/external/:external_id
所需权限: links:read
根据创建时传入的 external_id 反向查找短链接,语义与按短码查找对称。未找到返回 404。
curl https://open.utm.bar/v1/links/external/order_98765 \
-H "Authorization: Bearer sk_live_xxxx"
响应 200 OK
{
"data": {
"id": "...",
"code": "launch-2026",
"short_url": "https://utm.bar/launch-2026",
"original_url": "https://example.com/page",
"external_id": "order_98765",
"is_active": true,
"click_count": 42,
"created_at": "2026-05-25T00:00:00Z"
}
}
更新链接元数据
PATCH /v1/links/:code
所需权限: links:write
original_url和code创建后不可修改。如需更换目标地址,请创建新链接并停用旧的。
请求体(所有字段可选)
| 字段 | 类型 | 说明 |
|---|---|---|
title | string | 新标题 |
expires_at | ISO 8601 / null | 更新或清除过期时间 |
utm_source | string | 更新 UTM source |
utm_medium | string | 更新 UTM medium |
utm_campaign | string | 更新 UTM campaign |
utm_term | string | 更新 UTM term |
utm_content | string | 更新 UTM content |
curl -X PATCH https://open.utm.bar/v1/links/launch-2026 \
-H "Authorization: Bearer sk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{ "title": "新标题", "expires_at": "2026-12-31T23:59:59Z" }'
响应 200 OK — 返回更新后的链接对象。
禁用链接
POST /v1/links/:code/disable
所需权限: links:delete
curl -X POST https://open.utm.bar/v1/links/launch-2026/disable \
-H "Authorization: Bearer sk_live_xxxx"
响应 200 OK
启用链接
POST /v1/links/:code/enable
所需权限: links:write
curl -X POST https://open.utm.bar/v1/links/launch-2026/enable \
-H "Authorization: Bearer sk_live_xxxx"
响应 200 OK
删除链接
DELETE /v1/links/:code
所需权限: links:delete
删除操作不可撤销。如果日后可能还需要这个链接,建议改用禁用操作。
curl -X DELETE https://open.utm.bar/v1/links/launch-2026 \
-H "Authorization: Bearer sk_live_xxxx"
响应 204 No Content
获取点击统计
GET /v1/links/:code/stats
所需权限: links:read
查询参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
start | YYYY-MM-DD | 近 7 天 | 起始日期(含) |
end | YYYY-MM-DD | 今天 | 截止日期(含) |
tz | IANA 时区名 | UTC | 用于按时区聚合日期边界 |
curl "https://open.utm.bar/v1/links/launch-2026/stats?start=2026-05-01&end=2026-05-25&tz=Asia/Shanghai" \
-H "Authorization: Bearer sk_live_xxxx"
响应 200 OK
{
"data": {
"total_clicks": 1024,
"unique_clicks": 876,
"tz": "Asia/Shanghai",
"daily": [
{ "date": "2026-05-01", "clicks": 40, "unique_clicks": 35 },
{ "date": "2026-05-02", "clicks": 55, "unique_clicks": 48 }
]
}
}
频率限制
限流以团队为粒度,同一团队下所有 API Key 共享配额。
| 请求类型 | 限制 |
|---|---|
| 写操作(创建 / 更新 / 禁用 / 删除) | 60 次 / 分钟 |
| 读操作(列表 / 详情 / 统计) | 300 次 / 分钟 |
超限时返回 429 Too Many Requests,响应头包含:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1748140860
Retry-After: 30
权限范围
| Scope | 授权操作 |
|---|---|
links:read | 列表查询、获取详情、获取统计 |
links:write | 创建链接、更新元数据、启用链接 |
links:delete | 禁用链接、删除链接 |
错误响应
所有错误使用统一的结构:
{
"error": "error_code",
"message": "人类可读的错误描述",
"request_id": "req_abc123"
}
| 状态码 | error | 含义 |
|---|---|---|
400 | invalid_request | 参数校验失败 |
401 | unauthorized | Key 缺失或无效 |
403 | forbidden | Key 缺少所需权限 |
404 | not_found | 资源不存在 |
409 | conflict | 自定义短码已被占用 |
429 | rate_limited | 超出频率限制 |
500 | internal_error | 服务端错误 |