错误处理
API 统一的错误封装结构,以及每个错误码对应的 HTTP 状态和正确的处理方式。
更新于 2026年8月13日
所有端点上的所有错误都使用同一种封装结构:
{
"error": {
"code": "not_found",
"message": "Link not found",
"doc_url": "https://linkprofit.com/docs/api/errors"
}
}
按 error.code 分支处理,把 error.message 展示给用户看。校验类错误还会附带一个 details 数组,其中是逐字段的说明:
{
"error": {
"code": "validation_failed",
"message": "Request failed validation",
"doc_url": "https://linkprofit.com/docs/api/errors",
"details": [
{ "path": "url", "message": "Destination URL is not a valid address" }
]
}
}
错误码
| 错误码 | HTTP | 含义 | 处理方式 |
|---|---|---|---|
| unauthorized | 401 | 密钥缺失、未知、已吊销或已过期 | 检查请求头;签发新密钥 |
| forbidden | 403 | 密钥类型与端点不匹配,或该操作不被允许 | 按文档使用工作区 / 合作伙伴密钥 |
| insufficient_scope | 403 | 密钥缺少必需的权限 | 创建一个带有消息中所指权限的密钥 |
| plan_restricted | 403 | 套餐不包含该能力 | 升级套餐,或从请求中去掉该功能 |
| not_found | 404 | 资源不存在——或属于其他租户 | 核对 id;他人的资源与不存在的资源无法区分 |
| invalid_request | 400 | JSON 格式错误、游标不合法、违反业务规则 | 修正请求 |
| validation_failed | 422 | 请求体或查询参数未通过 schema 校验 | 修正 details 中列出的字段 |
| conflict | 409 | 状态冲突:slug 已被占用、Idempotency-Key 复用但请求体不同 | 换一个值,或换一个新的幂等键 |
| quota_exceeded | 422 | 套餐配额已用尽(短链接、域名、客户) | 升级套餐或释放配额 |
| rate_limited | 429 | 该密钥的请求过多 | 等待 Retry-After 秒;参见速率限制 |
| not_configured | 503 | 该能力在当前环境中未配置 | 稍后重试或联系技术支持 |
| internal | 500/502/504 | 平台意外错误 | 退避后重试;若持续出现请上报 |
| invalid_click_id | 422 | click_id 是伪造的、被篡改过的,或者是在其他工作区签发的 | 把目标地址中出现的点击标识参数值原样传回 |
| attribution_expired | 422 | 这次点击已经超出工作区设定的归因窗口 | 无需重试;如有需要,请在控制台中调整该窗口 |
行之有效的处理规则
- 404 同时也是隔离手段。 来自其他工作区的 id 得到的是
not_found,绝不会是forbidden——API 不会透露别处的 id 是否存在。 - 只重试安全的错误。 对
internal和rate_limited采用退避重试。绝不要盲目重试conflict或validation_failed——那是请求本身有问题。用Idempotency-Key让写操作的重试变得安全。 GET /links永远不会返回 404。 筛选结果为空时返回空列表;对集合返回 404 会产生歧义。