API 参考
错误
了解所有 Kanorio API 返回的统一错误格式、错误代码与 HTTP 状态码的对应关系,以及如何处理重试机制。
Management API、Content Delivery API 和 Customer API 返回的错误格式完全一致。每个错误代码在所有 API 中均对应相同的 HTTP 状态码,因此您只需编写一个错误处理器即可适用于所有 API。
{ "error": { "code": "SLUG_TAKEN", "message": "Another post already uses this slug.", "details": { "slug": "how-we-feed-our-starter" } } }
| 字段 | 类型 | 备注 |
|---|---|---|
error.code | string | 稳定且机器可读。请根据此字段进行分支处理。 |
error.message | string | 供日志与开发者参考的英文句子。内容随时可能变更,请勿依此进行匹配。 |
error.details | object, optional | 代码的结构化上下文,例如 retryAfter、availableAt、issues 或 requiredScope。 |
成功的响应绝不会包含 error 字段,且 API 不会将成功响应包裹在 ok 标志中。
错误代码对应的 HTTP 状态码
每个错误代码均对应一个状态码。未来新增的代码亦遵循相同规则,因此您可以根据状态码来处理尚未遇到的错误代码。
| 状态 | 含义 | 示例 |
|---|---|---|
400 | 请求格式错误或验证失败 | VALIDATION, INVALID_CURSOR, 以 INVALID_ 开头的代码 |
401 | 无凭证,或凭证无效、过期或已撤销 | UNAUTHORIZED, UNAUTHENTICATED |
403 | 凭证有效但无权访问:权限、计划、角色或模式不符 | FORBIDDEN, OWNER_REQUIRED, LIMIT_REACHED, LOCKED |
404 | 此网站上不存在该资源 | NOT_FOUND, 以 _NOT_FOUND 结尾的代码 |
405 | 此路径不支持该方法 | METHOD_NOT_ALLOWED |
409 | 与当前状态冲突:过时的写入、网址别名已被占用、重复数据 | CONFLICT, SLUG_TAKEN, IDEMPOTENCY_CONFLICT |
413 | 上传文件过大 | FILE_TOO_LARGE |
422 | 输入格式正确,但违反业务规则 | SITE_NOT_PUBLISHED, ASSET_IN_USE |
429 | 请求过多或后端繁忙;请稍后重试 | RATE_LIMITED, SEARCH_BUSY, ANALYTICS_BUSY |
500 | 未预期的服务器错误 | INTERNAL |
502, 503 | 上游服务失败或暂时无法使用 | UPLOAD_FAILED, SERVICE_UNAVAILABLE, SHARED_SENDER_PAUSED |
API 参考文档中的每项操作均列出了其可能返回的错误代码及其含义。OpenAPI 文档中亦包含相同的列表,标记为 x-kanorio-errors。
验证错误
VALIDATION 错误会在 details.issues 中列出所有验证失败的字段。path 字段使用点号(.)来表示嵌套结构。
{ "error": { "code": "VALIDATION", "message": "Input does not match the capability schema.", "details": { "issues": [ { "path": "title", "message": "Required", "code": "invalid_type" } ] } } }
Content Delivery API 的表单提交若包含无效回答,会以相同方式报告,并将问题 ID 作为 path。
重试机制
- 针对
429、502和503错误,请使用退避算法(backoff)进行重试。若响应中包含Retry-After标头或details.retryAfter字段,请至少等待该秒数后再重试。 - 请勿直接重试其他
4xx错误,应先修正请求内容。 - 若写入操作出现
409 CONFLICT,代表资源在您读取后已被他人修改。请重新读取资源、合并变更,并使用新的时间戳再次发送写入请求。 - 请使用 幂等性键值 确保创建请求可安全重试。
权限错误
403 响应会在 details 中说明缺失的权限,例如令牌缺乏的 requiredScope,或是当服务账号调用账号层级操作时显示 reason: "principal_not_allowed"。遇到此类错误时,请引导用户进行修正,而非进行重试。
请求 ID
Content Delivery API 和 Customer API 的响应均包含 X-Request-Id 标头。若需联系支持团队查询特定请求,请提供此 ID。
错误代码
下表列出了目前各 API 可能返回的所有错误代码,内容由 OpenAPI 文档自动生成。
Management API codes
| Code | HTTP status |
|---|---|
EMPTY_SLUG | 400 |
INVALID_BODY | 400 |
INVALID_CURSOR | 400 |
INVALID_EDITED_PATH | 400 |
INVALID_FORMAT | 400 |
INVALID_ORDER | 400 |
INVALID_SUBDOMAIN | 400 |
UNSUPPORTED_EDITED_PATH | 400 |
VALIDATION | 400 |
UNAUTHENTICATED | 401 |
UNAUTHORIZED | 401 |
CUSTOM_DOMAIN_CHANGE_FORBIDDEN | 403 |
CUSTOM_DOMAIN_LIMIT_REACHED | 403 |
FORBIDDEN | 403 |
LIMIT_REACHED | 403 |
MODERATION_LOCKED | 403 |
OWNER_REQUIRED | 403 |
PLAN_CANNOT_PUBLISH | 403 |
PRO_REQUIRED | 403 |
REDIRECT_LIMIT | 403 |
SUBDOMAIN_CHANGE_FORBIDDEN | 403 |
TOKEN_WEBSITE_SCOPED | 403 |
HEADER_NOT_FOUND | 404 |
HOME_PAGE_NOT_FOUND | 404 |
NOT_FOUND | 404 |
OWNER_NOT_FOUND | 404 |
PAGE_NOT_FOUND | 404 |
PARENT_NOT_FOUND | 404 |
PRODUCT_NOT_FOUND | 404 |
WEBSITE_NOT_FOUND | 404 |
METHOD_NOT_ALLOWED | 405 |
CONFLICT | 409 |
CUSTOM_DOMAIN_TAKEN | 409 |
HAS_CHILDREN | 409 |
HOSTED_ONLY | 409 |
HOSTNAME_CONFLICT | 409 |
IDEMPOTENCY_CONFLICT | 409 |
IDEMPOTENCY_IN_PROGRESS | 409 |
KEY_TAKEN | 409 |
PRIMARY_HEADER_PROTECTED | 409 |
READD_COOLDOWN | 409 |
REDIRECT_CONFLICT | 409 |
SLUG_TAKEN | 409 |
SUBDOMAIN_TAKEN | 409 |
TAKEN | 409 |
BLOCKED | 422 |
BREADCRUMB_PARENT_INVALID | 422 |
CONTENT_VALIDATION_FAILED | 422 |
CORE_SECTION_VIOLATION | 422 |
CUSTOM_DOMAIN_BLOCKED | 422 |
CUSTOM_DOMAIN_HIGH_RISK_TLD | 422 |
CUSTOM_DOMAIN_TOO_LONG | 422 |
DEPTH_EXCEEDED | 422 |
DNS_NOT_PROPAGATED | 422 |
DOMAIN_CHANGE_NOT_ALLOWED | 422 |
EMPTY_CONTENT | 422 |
FOREIGN_PAGE | 422 |
HIGH_RISK_TLD | 422 |
HOME_HAS_HIERARCHY | 422 |
HOME_NOT_CREATABLE | 422 |
HOME_NOT_DELETABLE | 422 |
HOME_NOT_SORTABLE | 422 |
HOME_SLUG_IMMUTABLE | 422 |
LINK_IN_BIO_DEDICATED_ENTRY | 422 |
LINK_IN_BIO_NOT_DUPLICABLE | 422 |
META_NOT_LIVE | 422 |
NO_PUBLIC_URL | 422 |
OWNERSHIP_REQUIRED | 422 |
PAGE_LIMIT_REACHED | 422 |
PARENT_NOT_ALLOWED | 422 |
RESERVED_SEGMENT | 422 |
RESERVED_SLUG | 422 |
RESERVED_SUBDOMAIN | 422 |
SANITIZE_FAILED | 422 |
SEARCH_CONSOLE_AUTH_EXPIRED | 422 |
SEARCH_CONSOLE_NOT_CONNECTED | 422 |
SEARCH_CONSOLE_PERMISSION_DENIED | 422 |
SEARCH_CONSOLE_PROPERTY_NOT_FOUND | 422 |
SEGMENT_TOO_LONG | 422 |
SITEMAP_NOT_REACHABLE | 422 |
SUBDOMAIN_MISSING | 422 |
SYSTEM_PAGE_LOCKED | 422 |
TEMPLATE_PRODUCT_LOCKED | 422 |
ANALYTICS_BUSY | 429 |
DAILY_LIMIT_REACHED | 429 |
RATE_LIMITED | 429 |
SEARCH_BUSY | 429 |
SEARCH_CONSOLE_QUOTA_EXCEEDED | 429 |
STOCK_BUSY | 429 |
INTERNAL | 500 |
SEARCH_CONSOLE_ERROR | 502 |
BUSY | 503 |
SEARCH_CONSOLE_UNAVAILABLE | 503 |
SERVICE_UNAVAILABLE | 503 |
WRITE_FROZEN | 503 |
Content Delivery API codes
| Code | HTTP status |
|---|---|
BAD_HOST | 400 |
FILE_TYPE_NOT_ALLOWED | 400 |
INVALID_ANSWERS | 400 |
INVALID_BODY | 400 |
INVALID_CURSOR | 400 |
INVALID_KIND | 400 |
INVALID_LIMIT | 400 |
INVALID_PATH | 400 |
INVALID_QUERY | 400 |
QUERY_REQUIRED | 400 |
QUERY_TOO_LONG | 400 |
QUERY_TOO_SHORT | 400 |
TOO_MANY_PARAMS | 400 |
UNKNOWN_BOT | 400 |
UNSUPPORTED_LOCALE | 400 |
VALIDATION | 400 |
VERIFICATION_EXPIRED | 400 |
NOT_PREVIEW | 403 |
COLLECTION_NOT_FOUND | 404 |
FORM_NOT_FOUND | 404 |
HEADER_NOT_FOUND | 404 |
ITEM_NOT_FOUND | 404 |
PAGE_NOT_FOUND | 404 |
PRODUCT_NOT_FOUND | 404 |
SITE_NOT_FOUND | 404 |
UNIT_NOT_FOUND | 404 |
DUPLICATE_SUBMISSION | 409 |
FILE_TOO_LARGE | 413 |
RATE_LIMITED | 429 |
SEARCH_BUSY | 429 |
QUERY_TIMEOUT | 503 |
UPLOAD_UNAVAILABLE | 503 |
UPSTREAM_UNAVAILABLE | 503 |
Customer API codes
| Code | HTTP status |
|---|---|
BAD_HOST | 400 |
INVALID_CODE | 400 |
INVALID_CURSOR | 400 |
INVALID_EMAIL | 400 |
INVALID_LIMIT | 400 |
VALIDATION | 400 |
UNAUTHENTICATED | 401 |
BOT_PROTECTION_FAILED | 403 |
DOWNLOAD_NOT_ALLOWED | 403 |
EXPIRED | 403 |
FORBIDDEN | 403 |
LIMIT_REACHED | 403 |
LOCKED | 403 |
NOT_RELEASED | 403 |
NO_ATTEMPTS_LEFT | 403 |
REVIEWS_DISABLED | 403 |
CERTIFICATE_DISABLED | 404 |
DELIVERABLE_NOT_FOUND | 404 |
NOT_FOUND | 404 |
NO_FILE | 404 |
NO_RECEIPT | 404 |
ORDER_NOT_FOUND | 404 |
SITE_NOT_FOUND | 404 |
UNIT_NOT_FOUND | 404 |
WEBSITE_NOT_FOUND | 404 |
METHOD_NOT_ALLOWED | 405 |
ALREADY_REVIEWED | 409 |
FILE_NOT_PROTECTED | 409 |
NOT_A_QUIZ | 409 |
QUIZ_NOT_READY | 409 |
ACCOUNT_BLOCKED | 422 |
ALREADY_REGISTERED | 422 |
CHALLENGE_EXPIRED | 422 |
EMAIL_NOT_VERIFIED | 422 |
METHOD_DISABLED | 422 |
VERIFY_FAILED | 422 |
RATE_LIMITED | 429 |
SHARED_SENDER_PAUSED | 503 |
SIGN_FAILED | 503 |
UPSTREAM_UNAVAILABLE | 503 |