---
title: エラー
description: 2 つの拒否の形、各ステータスコードの意味、再試行の価値がある拒否、そして検証の失敗がほとんど何も語らない理由を説明します。
---

拒否は JSON です。形は 2 つあります。

ほとんどはメッセージのみを持ち、これは人向けではなくログ向けです。

```json
{ "error": "Invalid request" }
```

ドメインの拒否は、機械が読める理由も持ちます。

```json
{
  "code": "conflict",
  "error": "Settings changed; reload before saving",
  "reason": "settings_stale"
}
```

**まずステータスで分岐し、`code` と `reason` があればそれで分岐してください。`error` では行わないでください。** 最初の形の拒否はどちらも持たないため、`reason` を無条件に読むコードはそこで壊れます。メッセージは文章であり書き換えられることがあります。`code` は `invalid_input`、`not_found`、`conflict`、`forbidden` のいずれかで、`reason` は安定したスラッグです。拒否によっては、何が失敗したかをより詳しく示す `detail` オブジェクトを持ちます。

## 各ステータスの意味

| ステータス | 意味 | 再試行 |
| --- | --- | --- |
| `400` | ボディ、クエリ、またはパラメータが拒否された | リクエストを変えるまでは不可 |
| `401` | トークンが欠落、無効、期限切れ、または失効 | 可。更新して送り直す（1 回） |
| `403` | モジュールが無効、またはスコープか役割がそのアクションを許可しない | 不可 |
| `404` | 該当するレコードがない、または読めるものがない | 不可 |
| `409` | リビジョンの競合、冪等性キーの再利用、または操作を禁じる状態 | 読み直してリクエストを変えた後のみ |
| `413` | ボディが制限を超えた | 不可 |
| `500` | 予期しない障害 | 可。バックオフを入れて |

`403` はステータスだけでは「役割が許可しない」と「モジュールが無効」を区別しません。`reason` を読んでください。`external_api_disabled` はワークスペースの `api` モジュールが無効であることを、`permission_required` はスコープか役割が問題であることを意味します。

`404` と `403` は、同じ状況を別の角度から見たものである場合があります。読む権限のないレコードは、存在を認めるのではなく `404` を返します。

## 検証の失敗が多くを語らない理由

拒否されたボディは、項目名を示さずに `400 {"error":"Invalid request"}` を返します。これは意図的です。この API はリクエストをそのまま返さず、実行した内部検証の一覧も示しません。そのエンドポイントのスキーマについてはリファレンスと照合してください。

## 安全な再試行

`Idempotency-Key` を取るエンドポイントは、タイムアウトや `500` の後の再試行が安全です。**同じ**キーを再利用すれば、サーバーは処理を行うか、すでに返した応答を再生します。再試行のために新しいキーを生成することが、重複を生む原因です。

キーを取らないエンドポイント — 価格プレビュー、ダウンロードリンク、`POST /api/v1/bootstrap` — では、再試行はリクエストをそのまま繰り返します。この 4 つはいずれも 2 回目の呼び出しで何かを作成することはありませんが、処理が二度行われることを妨げるものもありません。
