メインコンテンツへスキップ
すべてのエラーは共通の形状を持ちます。
{
  "error": { "code": "not_found", "message": "Video not found" },
  "meta": { "request_id": "req_xxxxx" }
}
error.code は安定した機械判読用の文字列です。error.message は人間向けの説明で、バージョン間で変わる可能性があります。原則として code でパースし、message はログに残してください。

エラーコード一覧

コードHTTP発生条件推奨対応
unauthorized401Authorization ヘッダーが欠落・形式違反・無効Bearer lymo_... 形式を確認。失効している場合は Web アプリで再発行
invalid_key_metadata401キーの署名は有効だが、Lymo 固有メタデータが欠落Web アプリのキー発行フローから再発行してください
forbidden403キーがスコープ不足、または組織が非アクティブキーのスコープを確認。組織が有効なはずならサポートに連絡
not_found404リソース不在、または別組織に属する下記「クロステナント 404」を参照
bad_request400ヘッダー形式違反(例: Idempotency-Key が 256 文字超過)ヘッダーを修正して再試行
validation_failed422クエリ・ボディがスキーマ検証で失敗message で該当フィールドのパスを確認し、修正して再試行
invalid_webhook_url422POST /v1/webhooks の配信先 URL が組織のホスト名許可リストに含まれていないWebhook → ホスト名の許可リスト を参照
rate_limited429キーあたりのリクエスト数超過(下記の通り、現時点では適用されないキーもある)Retry-After(秒)に従い、以降は指数バックオフで調整
service_unavailable503キー検証サービスが一時的に利用不可バックオフ付きで再試行。1 分以上続く場合はエスカレーション
internal_error500予期せぬサーバエラー1 度だけ再試行。継続するなら request_id を添えて報告

クロステナント 404

別組織に属するリソースは 403 forbidden ではなく 404 not_found を返します。これは意図的な挙動です。403 を返すと ID の存在が漏洩するため、「存在しない」と区別のつかない 404 を返すことで ID 列挙攻撃を防いでいます。この挙動は動画だけでなく、すべてのリソースパスに適用されます。 具体例として、組織 A のキーで組織 B の動画 ID に対して GET /v1/videos/{id} を呼ぶと、以下が返ります。
{
  "error": { "code": "not_found", "message": "Video not found" },
  "meta": { "request_id": "req_xxxxx" }
}
存在するはずのリソースが 404 を返す場合、まずキーのスコープ先組織を疑ってください。想定と違う組織に発行されていることがよくあります。
curl "$LYMO_BASE/v1/members/me" -H "Authorization: Bearer $LYMO_KEY"
返されたメンバーが所属する組織が、このキーからアクセスできる唯一の組織です。

キーの自己失効

キーが漏洩した場合、Web UI にアクセスせずともキーの保持者自身で失効できます。
curl -X DELETE "$LYMO_BASE/v1/keys/me" -H "Authorization: Bearer $LYMO_KEY"
# → { "data": { "revoked": true }, "meta": {...} }
このエンドポイントはスコープ不要です。どのキーも自身を失効させることができます。失効後、同じキーを使ったリクエストはすべて 401 unauthorized を返します。

request_id の使い方

すべてのレスポンス(成功・失敗にかかわらず)に meta.request_id が含まれます。問題を報告する際に添えていただくと、サーバ側で該当リクエストの正確なタイミング・入力・処理バックエンドを追跡できます。
{
  "error": { "code": "internal_error", "message": "An unexpected error occurred" },
  "meta": { "request_id": "req_fa29e58a3cfb4c0fbab0a75f82c4c7a3" }
}
形式は req_ + 32 文字の小文字 16 進数(ハイフンを除いた UUID)です。同じ ID は X-Request-Id レスポンスヘッダーにも入るので、ログとの突き合わせが容易です。

レート制限

レート制限は API キー単位で強制されます。超過時は 429 rate_limited が返り、Retry-After ヘッダーに待機秒数が入ります。
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{ "error": { "code": "rate_limited", "message": "Rate limit exceeded" }, "meta": {...} }
現時点ではすべての発行済みキーにレート制限が適用されているわけではありません。将来のリリースでスコープごとの標準値が適用される予定です。Retry-After を常に尊重する設計にしておけば、制限適用への切り替え時にクライアント側の変更は不要になります。固定間隔をハードコードしないでください。

バリデーションエラー

validation_failed(422)は開発中に最も多く遭遇するエラーです。message にはフィールドパスが入ります。
{
  "error": {
    "code": "validation_failed",
    "message": "limit: Number must be less than or equal to 100"
  },
  "meta": { "request_id": "req_..." }
}
よくある原因:
  • limit1–100 の範囲外(デフォルトは 25)
  • created_after / created_before が ISO 8601 として不正
  • status フィルタが許容 enum 外 — リソース別のステータス値は APIリファレンス タブを参照
  • POST /v1/webhooks のボディで必須フィールドが欠落