# エラー

> すべてのKanorio APIが返す共通のエラー形式、コードとHTTPステータスの対応関係、およびリトライの処理方法について解説します。

> Markdown version of https://kanorio.com/ja/developers/basics/errors. Append `.md` to any developer docs URL for this format. Index: https://kanorio.com/llms.txt · MCP: https://app.kanorio.com/api/mcp
>
> Translated from the English original: https://kanorio.com/en/developers/basics/errors.md

Management API、Content Delivery API、Customer APIは、すべて同じ形式でエラーを返します。各コードはすべてのAPIで常に同じHTTPステータスに対応しているため、1つのエラーハンドラーですべてのAPIに対応可能です。

```json
{
  "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ステータス

すべてのコードは1つのステータスに対応しています。後から追加されたコードも同じルールに従うため、未確認のコードであってもステータスに基づいて処理できます。

| ステータス | 意味 | 例 |
|---|---|---|
| `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` はドットを使用してネストを表現します。

```json
{
  "error": {
    "code": "VALIDATION",
    "message": "Input does not match the capability schema.",
    "details": {
      "issues": [
        { "path": "title", "message": "Required", "code": "invalid_type" }
      ]
    }
  }
}
```

Content Delivery APIでのフォーム送信において無効な回答があった場合も同様の方法で報告され、`path` には質問IDが使用されます。

## リトライ

- `429`、`502`、`503` はバックオフを使用してリトライしてください。レスポンスに `Retry-After` ヘッダーまたは `details.retryAfter` が含まれている場合は、指定された秒数以上待機してください。
- 他の `4xx` レスポンスは、修正せずにリトライしないでください。まずリクエストを修正してください。
- 書き込み時の `409 CONFLICT` は、読み取り後に誰かがリソースを変更したことを意味します。再度読み取りを行い、マージしてから新しいタイムスタンプで書き込みリクエストを送信してください。
- 作成リクエストは、[冪等性キー](https://kanorio.com/ja/developers/basics/idempotency)を使用して安全にリトライできるようにしてください。

## 権限エラー

`403` レスポンスの `details` には不足している情報が説明されています。例えば、トークンに不足している `requiredScope` や、サービスアカウントがアカウントレベルの操作を呼び出した際の `reason: "principal_not_allowed"` などが含まれます。リトライするのではなく、ユーザーに何を修正すべきかを表示してください。

## リクエストID

Content Delivery APIおよびCustomer APIのレスポンスには `X-Request-Id` ヘッダーが含まれています。特定の操作についてサポートに問い合わせる際は、このIDを提示してください。

## エラーコード

以下の表は、OpenAPIドキュメントから生成された、各APIが現在返す可能性のあるすべてのコードの一覧です。

### 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 |
