Guide

API の規約と実装パターン

CRISIS API を利用するすべてのクライアントに共通する実装パターン — ページネーション、エラーハンドリング、更新セマンティクス、非同期操作 — を解説します。

ベース URL

https://api.crisis.jp/v1

すべてのエンドポイントは /v1 の下にあり、組織スコープのエンドポイントは /organizations/{organizationId}/ 以下に配置されています。

ページネーション

一覧を返すすべての API は、カーソルベースのページネーションを採用しています。 オフセットベース(page=2 のような方式)ではないため、途中のページにジャンプすることはできませんが、 データの追加・削除による重複や欠落が発生しない安定したページングが可能です。

レスポンスに含まれるフィールド

data — リソースの配列
limit — 1 ページあたりの最大取得件数
next_cursor — 次ページの開始位置。null の場合、最終ページ
total — 条件に一致する総件数

リクエストパラメータ

limit(オプション)— 取得件数の上限を指定
cursor(オプション)— 前回レスポンスの next_cursor を指定

実装例

async function fetchAllIncidents(orgId, token) {
  let cursor = null;
  const allItems = [];

  do {
    const params = new URLSearchParams({ limit: '50' });
    if (cursor) params.set('cursor', cursor);

    const res = await fetch(
      `https://api.crisis.jp/v1/organizations/${orgId}/incidents?${params}`,
      { headers: { Authorization: `Bearer ${token}` } }
    );

    if (!res.ok) throw new Error(`API error: ${res.status}`);

    const body = await res.json();
    allItems.push(...body.data);
    cursor = body.next_cursor;
  } while (cursor !== null);

  return allItems;
}

バッチ処理のヒント

  • 大量データを取得する場合は cursor を永続化し、中断時に再開できるようにしてください
  • total を事前に確認し、処理件数の見積もりに活用してください
  • レート制限に注意し、リクエスト間に適切な間隔を設けてください

エラーレスポンス

すべてのエラーは、構造化された JSON レスポンスで返されます。 ErrorCode でエラーの種類を特定し、TraceID でサポートへの問い合わせに使用できます。

{
  "ErrorCode":  "IAM-001",
  "HTTPStatus": 403,
  "MessageJa":  "権限が不足しています",
  "MessageEn":  "Forbidden",
  "DetailJa":   "リソースへのアクセス権限がありません",
  "DetailEn":   "You do not have permission to access this resource",
  "TraceID":    "CRS-A1B2-C3D4E5F6"
}

フィールド

ErrorCode — ドメインプレフィックス + 連番(例: IAM-001, ERR-400
HTTPStatus — HTTP ステータスコード
MessageJa / MessageEn — エラーカテゴリの汎用メッセージ(日本語 / 英語)
DetailJa / DetailEn — 具体的な状況説明(日本語 / 英語)
TraceIDCRS-XXXX-YYYYYYYY 形式の追跡コード。サポート問い合わせ時に提示

エラーハンドリングの実装例

async function callCrisisApi(url, options, token) {
  const res = await fetch(url, {
    ...options,
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
      ...options?.headers,
    },
  });

  if (!res.ok) {
    const error = await res.json();

    if (res.status >= 500) {
      // 5XX: サーバー側の問題 → 指数バックオフでリトライ
      console.error(`[${error.TraceID}] Server error: ${error.ErrorCode}`);
      throw new RetryableError(error);
    }

    // 4XX: クライアント側の問題 → 修正が必要
    console.error(`[${error.TraceID}] Client error: ${error.ErrorCode}`);
    throw new CrisisApiError(error);
  }

  return res.json();
}

エラーコード体系

ErrorCode のプレフィックスは、エラーが発生したドメインを示します。

ERR-4xx/5xx — 汎用 HTTP エラー

AUT-xxx — 認証・OAuth

IAM-xxx — ID・アクセス管理

USR-xxx — ユーザー管理

GRP-xxx — グループ管理

INC-xxx — インシデント

WFL-xxx — ワークフロー

AST-xxx — アセット管理

BIL-xxx — 課金・請求

SYS-xxx — システム共通

よくある HTTP ステータスコード

400 Bad Request — リクエストの形式が不正。バリデーションエラーの詳細を DetailJa で確認
401 Unauthorized — トークンが無効、期限切れ、または未指定
403 Forbidden — 認証は成功したが、権限が不足。IAM の設定を確認
404 Not Found — リソースが存在しない、または CRN の範囲外
409 Conflict — リソースが使用中、または重複する操作
422 Unprocessable Entity — 構文は正しいが、処理できない内容
429 Too Many Requests — レート制限超過。リトライ間隔を空けてください
500 Internal Server Error — サーバー内部エラー。TraceID を添えてサポートに連絡

PUT と PATCH の使い分け

PUT — 全量置換

リソースのすべてのフィールドを送信値で置換します。

  • 省略したフィールドは Go のゼロ値(空文字、0、false)で上書きされます
  • 安全のため、まず GET で取得したオブジェクトを修正して送信してください

PATCH — 部分更新

送信したフィールドのみ更新し、省略したフィールドは変更しません。

  • nullable フィールドに null を送信するとクリアされます
  • nullable フィールドを省略すると変更されません

PUT の安全な使い方

// 1. まず GET で現在のリソースを取得
const incident = await fetch(
  `https://api.crisis.jp/v1/organizations/${orgId}/incidents/${incidentId}`,
  { headers: { Authorization: `Bearer ${token}` } }
).then(r => r.json());

// 2. 必要な部分だけ変更
incident.name = '更新されたインシデント名';
incident.status = 'CLOSED';

// 3. 変更したオブジェクト全体を PUT で送信
await fetch(
  `https://api.crisis.jp/v1/organizations/${orgId}/incidents/${incidentId}`,
  {
    method: 'PUT',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(incident),
  }
);

⚠ PUT 使用時の注意

namestatus のような値型フィールドを省略すると、空文字や false で上書きされます。 意図しないデータ消失を防ぐため、GET → 修正 → PUT のパターンを必ず守ってください。

非同期操作

一部の操作は 202 Accepted を返します。 レスポンスは即時に返りますが、実際の処理はバックグラウンドで実行されます。

202 Accepted を返す操作の例

POST …/revisions/{id}/remind — フォームの未回答者へのリマインド通知送信

非同期操作の注意点

  • 202 を返す操作は冪等ではありません。リトライにより重複送信が発生する可能性があります
  • 実際の処理の完了はレスポンスでは確認できません
  • メール送信やプッシュ通知など、副作用のある操作はリトライ方針を慎重に設計してください

ステータス列挙

リソースの状態を表す主なステータス列挙値です。

リソースステータス(STATUS)

ユーザー、グループ、サービスアカウントなど、多くのリソースで使用されます。

ACTIVE — 有効

INACTIVE — 無効

インシデントステータス

ACTIVE — 対応中

CLOSED — クローズ済み

ARCHIVED — アーカイブ済み

インシデントモード

ワークフローパブリッシュの status と同じ値がインシデントの mode にも使用されます。

ACTUAL — 実災害

DRILL — 訓練

TEST — テスト

次のステップ