{
  "openapi": "3.0.3",
  "info": {
    "title": "ProofSnap API",
    "version": "2.0.0",
    "license": {
      "name": "Proprietary",
      "url": "https://getproofsnap.com/terms.html"
    },
    "description": "ProofSnap APIは、サーバー側のChromiumブラウザでWebページを読み込み、証拠パッケージ（ZIP）を返します。\n\n各キャプチャのパッケージには、スクリーンショット、ページのHTML、抽出したページテキスト、metadata.json、forensic_log.json、chain_of_custody.json、evidence.pdfに加え、全ファイルのハッシュ（SHA-256）を列挙したmanifest.jsonが含まれます。manifest.jsonは、そのキャプチャ用に生成されたRSA-4096鍵で署名されます（公開鍵はpublickey.pemとして同梱され、秘密鍵は破棄されます）。また、manifest.jsonのハッシュ（SHA-256）はBitcoinアンカー（manifest.json.ots）のためにOpenTimestampsカレンダーへ送信されます。カレンダーへのリクエストが失敗した場合、パッケージはこの証明なしで提供され、manifest.jsonにも記載されないため、オフラインスクリプトと検証ツールは「欠落」ではなく「存在しない」と報告します。本番キーで`include_eidas`を指定すると、同じハッシュにeIDAS適格タイムスタンプ（RFC 3161、manifest.json.tsr）も付与されます。JPEGスクリーンショットには、ベストエフォートでC2PA Content Credentialsの署名が付与され、署名に失敗した場合はそれなしでキャプチャが完了します。verification/フォルダーには、パッケージをオフラインで検証するスクリプトが含まれます。すべてのmanifest.jsonには`ots_listed_only_when_present: true`（manifest.json.otsはパッケージに含まれる場合にのみ記載されます）と`eidas_marker_version: 1`が記載されます。`eidas_requested: true`が記録されるのは、パッケージが適格タイムスタンプ付きで提供される場合に限られます。トークンを取得できなかった場合、マニフェストはトークンなしで封印し直されます。したがって、`eidas_requested: true`を記録しているのにmanifest.json.tsrがないパッケージのトークンが失われていることになり、オフラインスクリプトはFAILを報告します。chain_of_custody.jsonには`bitcoin_ots_included`が記録され、`page_modifications.items[]`にはキャプチャ前にページへ加えられたすべての変更が列挙されます。manifest.jsonには、sealed_at（すべてのファイルのハッシュ計算後にマニフェストを構築した時刻）と、SNTPで測定したキャプチャサーバーの時刻オフセットが記載されます。chain_of_custody.jsonには、キャプチャの各ステップが実行順に、それぞれの完了時刻とともに列挙され、最後のステップは「custody_record_written」です（ハッシュ計算、署名、タイムスタンプはその後に行われ、manifest.jsonと各証明によって裏付けられます）。\n\nmetadata.jsonには次の内容が記録されます。\n\n- `browser_identity`：実際に送信されたユーザーエージェントとClient Hints。\n- `dns`：ブラウザが接続したアドレスの独立したDNSチェック。dns.googleとcloudflare-dns.comの回答、および結果を含みます。結果はconfirmed、not_confirmed、resolvers_unavailable、connected_ip_unknown、skipped_ip_literal（URLがIPアドレスを指定しており、照会するホスト名がない場合）、skipped_internal_host（内部ホスト名で、公開リゾルバーには一切送信されない場合）のいずれかです。\n- `url_at_load`と`url_at_screenshot`：ページの読み込み直後と画像の取得時のアドレス（ページは自身のアドレスを変更することがあり、多くの場合は#以降の部分です）。\n- `redirect_chain`：メインドキュメントのリダイレクト。古い順に、それぞれのHTTPステータスとともに記録されます。リクエストされたアドレスと最終アドレスは完全な形で記録され、その間の各ホップではクエリの値が[redacted]に置き換えられます（`query_values_redacted`）。\n- `tls.source`：各TLSフィールドの取得元。`browser_connection`または`browser_connection_and_separate_handshake`のいずれかで、後者の場合は、ページの読み込み後に、certificate_chain.pemを取得した別個のハンドシェイクの`at`、`ip`、`port`も記録されます。\n\nリクエストされたステップが実行されなかった場合（eIDASタイムスタンプ、C2PA署名、アーカイブリクエスト、WHOIS、2回目の時刻読み取り、時間制限により切り詰められたWARC、時間制限によりスキップされた待機やコンテンツ展開）、evidence.pdfにはその旨が短い理由とともに記載され、来歴証明書にも1行で明記されます。\n\nキャプチャは非同期で処理されます。POST /capturesは「202」と「capture_id」を返します。GET /captures/{capture_id}をポーリングするか、`options.webhook_url`を指定してください。完了したキャプチャは、最大24時間有効な署名付きの「package_url」を返します（「package_url_expires_at」を参照）。新しいリンクが必要な場合は、キャプチャを再度読み取ってください。\n\n以下のパスはサーバーURLからの相対パスで、サーバーURLにはすでに/v1ステージが含まれています。APIが返す`poll_path`の値には/v1が含まれます。",
    "contact": {
      "email": "support@getproofsnap.com"
    }
  },
  "servers": [
    {
      "url": "https://api.getproofsnap.com/v1",
      "description": "ProofSnap API（EU）"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "キャプチャ",
      "description": "キャプチャの作成、一覧表示、読み取り、削除、検証を行います。\n\n**レート制限** `POST /captures`、`POST /captures/batch`、`POST /compare`、`POST /captures/{capture_id}/redact`、`POST /certify-hash`には、アカウント単位で60秒の固定ウィンドウによるレート制限が適用されます。アカウントのすべてのAPIキーとそのダッシュボードセッションは1つのウィンドウを共有します（キーを追加しても制限は増えません）。バッチまたは複数ハッシュの証明では、URLまたはハッシュごとに1ユニットを使用します。プラン別のウィンドウあたりのデフォルト制限は次のとおりです。\n\n| プラン | 60秒あたりのリクエスト数 |\n| --- | --- |\n| sandbox | 10 |\n| developer | 60 |\n| startup | 120 |\n| growth | 300 |\n| custom | 1200 |\n| legal_solo | 60 |\n| legal_seats | 120 |\n| website_archive | 60 |\n| archive_only | 30 |\n| その他のプラン | 30 |\n\n次のリクエストも同じウィンドウのユニットを消費します。特記のない限り、1リクエストにつき1ユニットです：`POST /captures/{capture_id}/verify`、actionが「legal_hold」の`PATCH /captures/{capture_id}`、`GET /captures/hosts`（一覧が再計算される場合のみで、キャッシュされた結果を返す場合は消費しません）、`POST /legal-holds`（10キャプチャごとに1ユニット）、`POST /captures/export-jobs`、および`POST /imports`、`POST /imports/{import_id}/complete`、`GET /imports/{import_id}?upload=true`。\n\n制限を超えると、APIは「429 RATE_LIMITED」を、`Retry-After`、`X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`ヘッダーおよび`error.details.retry_after_seconds`とともに返します。1つのウィンドウの上限を超えるユニットを必要とするリクエスト（ウィンドウあたりの制限を超える複数ハッシュの証明）は決して成功せず、「400 RATE_LIMIT_COST_TOO_HIGH」を`error.details` `{ max_per_window, window_seconds, requested }`とともに返します。より小さなリクエストに分割してください。拒否されたリクエストはユニットを消費せず、ヘッダーには実際の残り枠が示されます。\n\n**月間上限** 本番キーでのキャプチャ、比較、墨消し、証明は、アカウントごとの月間上限（UTCの暦月）に算入されます。リクエストが受理された場合のレスポンスには`X-Quota-*`ヘッダーが付きます。上限に達すると、「402 QUOTA_EXCEEDED」が`error.details` `{ reason, used, limit, max_limit, cap, org_member }`とともに返されます。`cap`は`plan_max`、`customer`、`member_owner`、`org`のいずれかです。本番のサブスクリプションが支払い期限超過または未払いの間、課金対象のリクエストは「402 PAYMENT_REQUIRED」を返します。このようなアカウントでは、テストキーを含むキーの環境にかかわらず、キャプチャ（単一およびバッチ）がこのエラーで拒否されます。\n\n**実行中のキャプチャとテストモード** 各アカウントで同時に実行できるキャプチャ数には上限があります（developer 10、startup 25、growth 100、legal_solo・legal_seats 25、custom 200、website_archive 25、sandbox 5）。上限を超えると、APIは「429 CONCURRENT_CAPTURE_LIMIT」を返します。バッチの場合は、枠に収まるURLを開始し、残りを`not_admitted`に列挙します（それぞれに`code`（CONCURRENT_CAPTURE_LIMIT）と`in_flight_limit`が付きます）ので、後で再送してください。テストモードの処理（テストキー、または請求先が登録されていないセッション）には、アカウントごとにUTCの1日あたりのユニット数の上限（200）があり（429 TEST_MODE_DAILY_LIMIT、`X-Test-Daily-*`ヘッダー）、テストモードのキャプチャがInternet Archiveに送信されることはありません（`external_archive.skip_reason` \"test_mode\"）。"
    },
    {
      "name": "比較と墨消し",
      "description": "既存のキャプチャから新しい封印済みパッケージを派生させます。2つのキャプチャの比較、または1つのキャプチャの墨消しコピーを作成できます。"
    },
    {
      "name": "ハッシュ証明",
      "description": "お手元のファイルのハッシュ（SHA-256）を証明します。送信されるのはハッシュのみで、ファイルがProofSnapに届くことはありません。"
    },
    {
      "name": "スケジュールキャプチャ",
      "description": "スケジュールキャプチャ（間隔またはcron）と変更検知（on_change）。キャプチャを行う実行はいずれも通常のキャプチャであり、計測の対象となって月間上限に算入されます。"
    },
    {
      "name": "案件",
      "description": "ハッシュチェーン化された証拠管理ログを備えた法務案件のワークスペースです。Legalプラン（legal_solo、legal_seats）で利用できます。その他のプランでは「403 MATTERS_NOT_ENABLED」が返されますが、例外が2つあります。サブスクリプションが終了した会社のオーナーは、その会社のデータ削除日（data_delete_after）まで、その会社の案件を一覧表示、閲覧、エクスポートできます。このアクセスは読み取り専用とエクスポートに限られ、その場合GET /mattersには「read_only: true」が追加されます。Archive onlyプランのアカウントは、自身の案件を一覧表示、閲覧、エクスポートできます。案件の名前変更、アーカイブ、メンバー管理、封印、共有、エクスポートを行えるのは案件のオーナーのみです。案件のオーナーは案件の作成者です。会社の案件では、作成者が会社を離れた後に限り、会社のオーナーが案件のオーナーになります。メンバーとして追加された会社のオーナーは、メンバーの権限のみを持ちます。メンバーがこれらの操作を行うと「403 FORBIDDEN」が返されます。案件へのすべての書き込み（作成、PATCH、キャプチャの割り当て、共有とその取り消し、封印、エクスポート）には確認済みのメールアドレスが必要です（ダッシュボードセッションの場合も、アドレスが未確認のアカウントのAPIキーの場合も「403 EMAIL_NOT_VERIFIED」が返されます）。また、本番の呼び出し元（本番のAPIキー、または請求先が登録されたセッション）の場合、サブスクリプション（または会社のサブスクリプション）が支払い期限超過または未払いの間は「402 PAYMENT_REQUIRED」で拒否されます。アーカイブされた案件は、再開されるまで名前変更、新規メンバー、新規キャプチャ、共有、エクスポートを拒否します（409 MATTER_ARCHIVED）。再開できない呼び出し元（終了した会社のオーナー、Archive onlyアカウント）は、引き続きエクスポートできます。"
    },
    {
      "name": "Webhook",
      "description": "ProofSnapは、キャプチャ、証明、墨消し、スケジュールのリクエストで指定された`webhook_url`へJSONイベントをPOSTします。URLはhttpsを使用する必要があり、認証情報を含めることはできず（`user:password@`、400 INVALID_URL）、プライベート、ループバック、リンクローカル、キャリアグレードNAT、マルチキャスト、予約済み、クラウドメタデータの各アドレス（これらのIPv4アドレスを埋め込んだIPv6形式を含む）を指すこともできません。この確認はリクエストの受理時（422 SSRF_BLOCKED）に行われ、配信のたびにも再度行われます。ホスト名を解決してすべてのアドレスを確認し、確認を通過したアドレスにのみ接続するため、後からブロック対象のアドレスに解決されるようになったホストには接続しません。ホスト名を解決できない場合、配信は送信されません。すべてのルートで、空または空白のみの「webhook_url」はWebhookなしとして扱われます。/compareはWebhookを送信しません。\n\n**アカウントのWebhookサブスクリプション** リクエストごとの「webhook_url」の代わりに（または併せて）、`POST /webhook-subscriptions`でエンドポイントをアカウントのイベントに登録できます。どのキー、スケジュール、ダッシュボードセッションが発生させたかにかかわらず、条件に一致するアカウントのイベントがすべて送信されます。各Webhookサブスクリプションには固有のシークレットがあり（作成時に1回だけ返されます）、受信するイベントタイプを列挙し、`host`または`schedule_id`で絞り込むことができます。本番のWebhookサブスクリプションは本番キャプチャのイベントのみを受信し、テストのWebhookサブスクリプションはテストキャプチャのイベントのみを受信します。APIキーで一覧表示、変更できるのは、そのキーの環境のWebhookサブスクリプションのみです。ダッシュボードセッションではすべて表示されます。配信にはトップレベルに`subscription_id`が付き、署名付きリンクは含まれません（package_url、package_url_expires_at、upgraded_proof_url、「compare.package_url」は除去され、「monitor.change_detected」には「compare.compare_id」が付きます）。パッケージはGET /captures/{capture_id}で取得してください。キャプチャイベントには、トップレベルに`capture_id`も付きます。Webhookサブスクリプションの配信の「webhook-id」は、Webhookサブスクリプション、キャプチャ（またはスケジュール）、イベントから導出されます。以下の配信ルールと再試行が適用されます。加えて、「410」レスポンスを受けるとWebhookサブスクリプションは直ちに無効化され（disabled_reason gone）、成功なしで5日間配信が失敗し続ける（かつ失敗した試行が少なくとも1回の再試行サイクル全体に及ぶ）と無効化され（failing）、作成元のAPIキーを失効させると無効化されます（key_revoked）。PATCHでstatus \"active\"を指定すると再び有効になります。すべてのイベントは`GET /events`にも30日間保持されます。\n\n**ヘッダー**\n\nすべての配信は、次の仕様に従って署名されます：[Standard Webhooks](https://www.standardwebhooks.com/)。そのため、公式のStandard Webhooksライブラリであれば検証できます。\n\n| ヘッダー | 値 |\n| --- | --- |\n| `Content-Type` | `application/json` |\n| `webhook-id` | `msg_<delivery id>`：同じキャプチャの同じイベントでは同一であるため、重複した配信には同じIDが付きます。重複排除に使用し、各webhook-idを1回だけ処理してください。`GET /webhook-events/{capture_id}`は、`msg_`プレフィックスを除いた同じIDを`delivery_id`として返します |\n| `webhook-timestamp` | 配信が送信された時刻のUnix時間（秒）。署名の対象に含まれます |\n| `webhook-signature` | `v1,<base64>`：`<webhook-id>.<webhook-timestamp>.<raw body>`に対するHMAC-SHA256。Webhook署名シークレットのローテーション中は、スペースで区切られた2つのエントリ`v1,<new> v1,<previous>`が含まれます。いずれかのエントリが一致すれば配信を受け入れてください |\n| `User-Agent` | `ProofSnap-Webhook/2.0` |\n\n**配信の検証** パースする前に、受信したバイト列そのものに対して検証してください。「webhook-timestamp」が自サーバーの時刻と5分を超えてずれている配信は拒否し（公式ライブラリはこれを行います）、webhook-idで重複排除してください。署名鍵は、シークレットの`whsec_`より後の部分をbase64デコードしたものです。`webhook_secret`は`whsec_`に標準のbase64が続く形式で、公式ライブラリが想定する形式であるため、そのまま渡してください。\n\n```js\n// npm install standardwebhooks\nimport { Webhook } from \"standardwebhooks\";\nconst wh = new Webhook(process.env.PROOFSNAP_WEBHOOK_SECRET); // whsec_... (webhook_secret)\n// rawBody: the request body as received (string or Buffer), headers: the request headers\nconst event = wh.verify(rawBody, headers); // throws on a bad signature or a timestamp outside 5 minutes\n```\n\nライブラリを使用しない場合（Node）：\n\n```js\nconst key = Buffer.from(secret.slice(\"whsec_\".length), \"base64\");\nconst signed = `${headers[\"webhook-id\"]}.${headers[\"webhook-timestamp\"]}.${rawBody}`;\nconst expected = crypto.createHmac(\"sha256\", key).update(signed).digest(\"base64\");\nconst ok = headers[\"webhook-signature\"].split(\" \").some((part) => {\n  const [version, sig] = part.split(\",\");\n  return version === \"v1\" && sig && sig.length === expected.length\n    && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));\n});\n// and: Math.abs(Date.now() / 1000 - Number(headers[\"webhook-timestamp\"])) <= 300\n```\n\n**Webhook署名シークレット** APIキーごとに固有のシークレット（`whsec_...`）があります。ダッシュボードの「開発者向け」でキーを作成するときに1回だけ表示されます（キーを作成するレスポンスの`webhook_secret`フィールド）。後から読み出すことはできず、キーの一覧でも返されません。紛失した場合や漏えいした可能性がある場合は、ダッシュボードの「開発者向け」で新しいシークレットを生成してください（キーの「新しい Webhook シークレット」）。新しいシークレットも1回だけ表示されます。**ローテーションの重複期間：** ローテーション後24時間（ローテーションのレスポンスの`previous_secret_expires_at`まで）は、すべての配信が新旧両方のシークレットで署名される（webhook-signatureに2つの`v1,`エントリが含まれる）ため、配信を取りこぼすことなくエンドポイントを新しいシークレットに切り替えられます。この重複期間中の2回目のローテーションは、「409 WEBHOOK_SECRET_ROTATION_PENDING」と`error.details.previous_secret_expires_at`（再度ローテーションできる時刻）とともに拒否されます。そのため、同時に有効なシークレットが2つを超えることはなく、受信側がまだ依存している可能性のあるシークレットが早期に廃止されることもありません。シークレットが漏えいした場合は、キーを失効させて新しいキーを作成してください。キーを失効させると両方のシークレットが削除されます。配信には送信時点のキーのシークレットが使用され、ローテーション前に開始された処理の配信も同様です。ログイン済みのダッシュボードセッションからのリクエストにはAPIキーがなく、したがってWebhook署名シークレットもないため、`webhook_url`を指定すると「400 `WEBHOOK_REQUIRES_API_KEY`」で拒否されます（キャプチャ、バッチ、墨消し、ハッシュ証明、スケジュールキャプチャの作成または編集）。スケジュールの実行には、そのスケジュールを作成したキーのシークレットが使用されます。キーが失効している場合、または配信時にシークレットを読み取れない場合、イベントは送信されず、試行は理由とともに記録されます（`GET /webhook-events/{capture_id}`で確認できます）。\n\n**配信** 各試行のタイムアウトは10秒です。リダイレクトには従いません。3xxレスポンスは、2xx以外のレスポンスやタイムアウトと同様に失敗として扱われます。レスポンス本文は読み取りません。**再試行：** タイムアウトした配信、接続できなかった配信、2xx以外のレスポンスを受けた配信（410 Goneを除く）は、約5分後、30分後、2時間後、8時間後、24時間後に再送されます（試行2から6まで、合計約35時間）。再送のたびに`webhook-id`は同じで、`webhook-timestamp`は新しくなります。その後、配信は打ち切られます。再試行の配信は同じペイロードを含みますが、24時間有効なダウンロードリンク（`package_url`、`package_url_expires_at`）は含まれません。パッケージはGET /captures/{capture_id}で取得してください。その間に消去されたキャプチャの配信は破棄されます。当社側で署名シークレットの読み取りが一時的に失敗した場合も、同様に再試行されます。「410 Gone」、リダイレクト、ブロック対象のアドレス、キーの欠落または失効については再試行されません。再試行の本文は初回の試行と異なる場合がある（ダウンロードリンクがない）ため、本文のハッシュではなくwebhook-idで重複排除してください。2xxを速やかに返してください。試行ログには、一般的なエラー分類（connection_failed、timeout、blocked_address、redirect_not_followed、http_<status>）が記録され、ネットワークエラーの生データは記録されません。certify.completedとredaction.completedは、レスポンスが返された直後に非同期で送信されます。すべての試行は記録されます。ログは`GET /webhook-events/{capture_id}`で確認できます。\n\n**イベント**\n\n`capture.completed`：キャプチャ（単一、バッチの項目、または間隔・cronスケジュールの実行）が完了しました。アカウントのWebhookサブスクリプションは、「on_change」スケジュールのベースラインキャプチャと変更キャプチャについてもこのイベントを受信します（これらについて、スケジュール自体の「webhook_url」が受信するのは「monitor.change_detected」です）。`capture`は、完了した`GET /captures/{capture_id}`と同じフィールドに加え、適格タイムスタンプが追加された場合の`timestamps.eidas`、`schedule_id`（スケジュール以外ではnull）、`test_mode`、`completed_at`を持ちます。\n\n```json\n{ \"event\": \"capture.completed\",\n  \"capture\": { \"capture_id\": \"cap_...\", \"status\": \"completed\", \"url\": \"https://example.com\", \"schedule_id\": null, \"test_mode\": false, \"captured_at\": \"...\", \"completed_at\": \"...\",\n    \"package_url\": \"https://...\", \"package_url_expires_at\": \"...\", \"verification_url\": \"https://...\",\n    \"manifest_hash\": \"sha256:...\", \"timestamps\": { \"bitcoin_ots\": { \"status\": \"pending_confirmation\", \"block_height\": null } },\n    \"c2pa\": { \"included\": true, \"signed_screenshot_sha256\": \"sha256:...\" }, \"file_count\": 21, \"size_bytes\": 1234567, \"metadata\": {} } }\n```\n\n`capture.failed`：キャプチャを完了できませんでした。`error.message`は公開用の短い理由です（予期しない失敗の場合は\"The capture could not be completed.\"）。内部エラーの詳細は送信されません。クラッシュまたはタイムアウトした実行も含まれます。そのような実行は、開始から約30分後に定期処理によって失敗とマークされ、その時点でcapture.failedが送信されます（メッセージは\"Capture did not finish (timed out).\"）。同じ定期処理は、完了しなかったハッシュ証明または墨消しについてcertify.failedまたはredaction.failedを送信します。失敗と報告された後に完了した実行は課金されず、capture.completedも送信されません。\n\n```json\n{ \"event\": \"capture.failed\",\n  \"capture\": { \"capture_id\": \"cap_...\", \"status\": \"failed\", \"url\": \"https://example.com\", \"schedule_id\": null, \"test_mode\": false, \"failed_at\": \"...\",\n    \"error\": { \"code\": \"CAPTURE_FAILED\", \"message\": \"...\" }, \"metadata\": {} } }\n```\n\n`certify.completed`：ハッシュ証明が完了しました。`certificate`は、同期の`POST /certify-hash`レスポンスと同じフィールドを持ちます。レスポンスが返された直後に非同期で配信されます。\n\n`certify.failed`：ハッシュ証明を完了できませんでした。\n\n```json\n{ \"event\": \"certify.failed\",\n  \"certificate\": { \"certify_id\": \"cert_...\", \"status\": \"failed\", \"failed_at\": \"...\",\n    \"error\": { \"code\": \"CERTIFY_FAILED\", \"message\": \"The certification could not be completed. Retry the request.\" } } }\n```\n\n`redaction.completed`：墨消しが完了しました。`redaction`は、`POST /captures/{capture_id}/redact`レスポンスと同じフィールドを持ちます。\n\n`redaction.failed`：墨消しを完了できませんでした。`error.code`は、リクエストが返すはずだったコードで（例：REDACTION_LEAK_DETECTED）、該当する場合は`details`も付きます。定期処理によって失敗とマークされた墨消しには「REDACTION_FAILED」が付きます。\n\n```json\n{ \"event\": \"redaction.failed\",\n  \"redaction\": { \"redaction_id\": \"red_...\", \"status\": \"failed\", \"redacted_from\": \"cap_...\", \"failed_at\": \"...\",\n    \"error\": { \"code\": \"REDACTION_LEAK_DETECTED\", \"message\": \"...\", \"details\": { \"files\": [\"page.html\"], \"rule_indexes\": [0], \"metadata_fields\": [], \"in_capture_url\": false } } } }\n```\n\n`monitor.change_detected`：`on_change`スケジュールがページテキストの変更を検知し、新しいキャプチャを実行しました。\n\n```json\n{ \"event\": \"monitor.change_detected\", \"schedule_id\": \"sch_...\",\n  \"before_capture_id\": \"cap_...\", \"after_capture_id\": \"cap_...\", \"url\": \"https://example.com\",\n  \"compare\": { \"package_url\": \"https://...\", \"diff_summary\": { } },\n  \"diff_status\": \"ok\", \"verdict\": \"changed\", \"text_verdict\": \"changed\", \"images_verdict\": \"unchanged\", \"metadata_verdict\": \"unchanged\",\n  \"detected_at\": \"...\", \"test_mode\": false }\n```\n\n`verdict`、`text_verdict`、`images_verdict`、`metadata_verdict`（2026-10-14以降）は、「compare.diff_summary」にある比較のカテゴリ別結果を反映します（比較がない場合はnull）。`alert_on: \"text\"`のスケジュールは、「text_verdict」がchangedの場合（または比較結果がない場合）にのみ「monitor.change_detected」を送信します。\n\n`capture.anchor_confirmed`（WebhookサブスクリプションとGET /eventsのみ）：パッケージのOpenTimestamps証明のBitcoinアンカーが確認されました。通常はキャプチャの数時間後です。\n\n```json\n{ \"event\": \"capture.anchor_confirmed\", \"capture_id\": \"cap_...\", \"schedule_id\": null, \"url\": \"https://example.com\",\n  \"confirmed_at\": \"...\", \"bitcoin_block_height\": 968549, \"upgraded_proof_available\": true, \"test_mode\": false }\n```\n\n`schedule.paused`（WebhookサブスクリプションとGET /eventsのみ）：ProofSnapがスケジュールを一時停止しました。`reason`は`no_billing`（APIアクセスなし）、`plan_downgrade`（プランで許可されるスケジュールが減った、「on_change」が使えない、または新しい処理が許可されない）、`failures`（実行が5回連続で失敗）、`key_revoked`、`invalid_cron`のいずれかです。ご自身で行った一時停止はイベントになりません。\n\n```json\n{ \"event\": \"schedule.paused\", \"schedule_id\": \"sch_...\", \"url\": \"https://example.com\", \"reason\": \"failures\",\n  \"paused_at\": \"...\", \"test_mode\": false }\n```\n\n`diff_status`は`ok`（compareに比較結果が含まれる）、`no_baseline`（比較対象となる以前のキャプチャがない）、`failed`（比較に失敗し、compareはnull）のいずれかです。"
    },
    {
      "name": "公開",
      "description": "APIキーが不要な操作です。"
    },
    {
      "name": "パッケージのインポート",
      "description": "既存のProofSnap証拠パッケージ（ProofSnap拡張機能で作成されたZIPファイル：Webキャプチャ、マルチタブセッション、単一および結合のファイル証明、またはこのAPIで作成されたZIPファイル：キャプチャ、証明、比較、墨消し）をアカウントにインポートします。インポートしたパッケージはAPIキャプチャと同様に扱われ、10年間保存され、リーガルホールド、案件、エクスポートで利用できます。\n\nすべての有料プラン（developer、startup、growth、custom、legal_solo、legal_seats、website_archive）で、本番のAPIキーまたは請求先が登録されたダッシュボードセッションから利用できます（テストキー、請求のないセッション、サンドボックス、「archive_only」には「403 IMPORT_NOT_ALLOWED」が返されます）。「website_archive」ではAPIキーは読み取り専用（403 PLAN_API_READ_ONLY）のため、ダッシュボードからインポートしてください。`matter_id`にはLegalプランが必要です（403 MATTERS_NOT_ENABLED）。メールアドレスが未確認の場合は「403 EMAIL_NOT_VERIFIED」、サブスクリプションが支払い期限超過の場合は「402 PAYMENT_REQUIRED」が返されます。インポートはキャプチャではないため、月間上限に算入されず、インポートごとの料金もかかりません。\n\n**手順** 1. ファイル名と正確なサイズ（バイト単位、最大2 GiB）を指定して`POST /imports`を実行します。レスポンスには、32 MiBのパートごとに1つの署名付きURL（最後のパートはこれより小さくなります）が含まれ、有効期間は1時間です。2. 各パートのバイト列をそれぞれのURLへPUTし、各レスポンスの`ETag`ヘッダーを保持します。3. すべてのパート番号とそのETagを指定して`POST /imports/{import_id}/complete`を実行します。4. ステータスが最終状態になるまで`GET /imports/{import_id}`をポーリングします。\n\n**ステータス** `uploading`（パートのアップロードとcomplete呼び出しを待機中。24時間以内に完了しなかったアップロードは`expired`になります）、`verifying`（パッケージを確認中）、`accepted`（検証に成功。`capture_id`が新しいキャプチャで、インポートと同じIDです）、`rejected`（検証に失敗。`reasons`にコードが列挙され、インポートの記録以外は保持されません）、`duplicate`（同じマニフェストのキャプチャがアカウントにすでに存在します：`duplicate_of`）、`expired`。\n\n**検証** 検証は厳格です。manifest.jsonに対するRSA署名、記載されたすべてのファイルが記載どおりのSHA-256（および記載がある場合はSHA-512、サイズ）で存在すること、マニフェストに記載のないファイルがないこと（.DS_StoreなどOSが追加するファイルと、マニフェストから派生した証明を除く）、ハッシュ済みファイルが少なくとも1つあること、証拠IDが一貫していること、フォレンジックログのハッシュチェーンの再計算、マニフェストに対するOpenTimestamps証明（オフライン）、固定されたDisigルートとパッケージ内の検証データによるeIDAS適格タイムスタンプを確認します。ZIP構造は、内容を読み取る前に確認されます（暗号化なし、ZIP64なし、リンクなし、安全な名前、重複名なし、各エントリのサイズとCRC-32）。APIのテストパッケージ（透かし入り）は拒否されます。evidence.pdfがハッシュ化される前に封印されたAPIパッケージは受け入れられ、そのファイルは`verification.checks.files.unhashed`に記載されます。\n\n**レベル**（`summary`）：`integrity`（verifiedまたはfailed）、`time_anchor`（eidas_qualified、eidas_qualified_revocation_unknown、ots_bitcoin_attested_unconfirmed、ots_pending、none）、および`provenance`です。来歴はAPIパッケージでは`issued_by_proofsnap`（マニフェストがAPIの発行台帳にあります）または`unverified`、拡張機能パッケージでは`registered_by_extension_account`（ログイン済みの拡張機能ユーザーが作成時にそのマニフェストを登録しました）または`not_registered`、照会できなかった場合は`unknown`となります。来歴を理由にインポートが失敗することはありません。\n\n**キャプチャ** 受け入れられたインポートは、`source`が\"import\"のキャプチャになります。ダウンロード（アップロードされたZIPをバイト単位でそのまま）と検証（POST /captures/{capture_id}/verifyが同じチェックを再度実行します）が可能で、リーガルホールドの設定、ゴミ箱への移動、消去ができ、案件（`matter_id`を指定してインポートした場合、案件の証拠管理ログに`package.imported`が記録されます）とエクスポートに含まれ、インポートから10年間保存されます。`captured_at`はパッケージ自体が示す時刻（`import.captured_at_basis` \"package_claim\"）であり、ProofSnapが観測した時刻ではありません。`created_at`はアップロードが作成された時刻です。インポートしたパッケージの比較と墨消しは拒否されます（422 IMPORT_NOT_SUPPORTED）。\n\n**制限** 進行中（uploadingまたはverifying）のインポートはアカウントあたり最大3件（409 IMPORT_LIMIT）、作成できるインポートはアカウントおよびUTCの1日あたり50件（429 RATE_LIMITED、`details.action` \"import_create\"。後で拒否されるものを含め、すべての作成リクエストが算入されます）で、createとcompleteにはプランの1分あたりのレート制限が適用されます。インポート量：申告されたパッケージサイズの合計は、アカウントあたりUTCの1日に最大5 GiB、UTCの1か月に最大20 GiB（developerではUTCの1か月に2 GiB）で、作成時（古いアップロードの場合はcomplete時）に算入されます。超過すると「429 IMPORT_DAILY_BYTES_LIMIT」または「IMPORT_MONTHLY_BYTES_LIMIT」が`Retry-After`とともに返されます（プラン独自の制限が適用される場合は`details.plan`にプランが示されます）。キャンセルされたアップロードは算入されません。"
    }
  ],
  "paths": {
    "/captures": {
      "post": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "createCapture",
        "summary": "URLをキャプチャ",
        "description": "キャプチャを受理して直ちに「202」を返し、キャプチャはバックグラウンドで実行されます。`GET /captures/{capture_id}`をポーリングするか、`options.webhook_url`を指定してください。URLのホスト名は、キャプチャの受理前に解決され、確認されます。\n\nアカウント単位で60秒のウィンドウによるレート制限が適用されます（アカウントのすべてのAPIキーとそのダッシュボードセッションは1つのウィンドウを共有します）。リミッターの実行後、このルートのレスポンスには`RateLimit-Policy`と`RateLimit`ヘッダー（IETF draft-ietf-httpapi-ratelimit-headersに基づく）に加え、従来の`X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`が含まれます。「429」の場合は`Retry-After`が追加されます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaptureRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "受理されました。同じIdempotency-Keyによる以前のリクエストのべき等リプレイも、`Idempotent-Replay: true`と元の本文を伴う「202」を返します。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              },
              "X-Quota-Limit": {
                "$ref": "#/components/headers/QuotaLimit"
              },
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/QuotaRemaining"
              },
              "X-Quota-Used": {
                "$ref": "#/components/headers/QuotaUsed"
              },
              "X-Quota-Cap": {
                "$ref": "#/components/headers/QuotaCap"
              },
              "X-Quota-Org-Limit": {
                "$ref": "#/components/headers/QuotaOrgLimit"
              },
              "X-Quota-Org-Used": {
                "$ref": "#/components/headers/QuotaOrgUsed"
              },
              "X-Sandbox-Limit": {
                "$ref": "#/components/headers/SandboxLimit"
              },
              "X-Sandbox-Remaining": {
                "$ref": "#/components/headers/SandboxRemaining"
              },
              "X-Sandbox-Used": {
                "$ref": "#/components/headers/SandboxUsed"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaptureAccepted"
                },
                "example": {
                  "capture_id": "cap_a1B2c3D4e5F6g7H8",
                  "status": "processing",
                  "url": "https://example.com",
                  "poll_path": "/v1/captures/cap_a1B2c3D4e5F6g7H8",
                  "message": "Capture accepted. Poll GET /v1/captures/{capture_id} (or use webhook_url) for completion.",
                  "metadata": {}
                }
              }
            }
          },
          "400": {
            "description": "次のいずれかです：MALFORMED_REQUEST、MISSING_FIELD、INVALID_URL、INVALID_TIMESTAMP_TYPE、INVALID_VIEWPORT、METADATA_TOO_LARGE、INVALID_EVIDENCE_PACK_OPTIONS。WEBHOOK_REQUIRES_API_KEY：ダッシュボードセッションから「webhook_url」が送信されました（WebhookにはAPIキーが必要です）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "「QUOTA_EXCEEDED」（月間上限またはサンドボックスの利用枠に到達。X-Quota-*またはX-Sandbox-*ヘッダーが付きます）または「PAYMENT_REQUIRED」。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "EIDAS_REQUIRES_LIVE_KEY：テストキーで「include_eidas」が指定されました（請求アカウントが連携されていないアカウントの「ps_live_」キーはテストキーとして動作します）。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッションです。PLAN_ARCHIVE_ONLY：このプランはアーカイブの保持のみで、新しい処理を作成しません。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。PLAN_API_READ_ONLY、details.reason \"session_outside_dashboard\"：Website Archiveアカウントのダッシュボードセッションで、リクエストにOriginヘッダーがないか、ProofSnapダッシュボードのアドレスではありません（このプランの新しい処理はダッシュボードでのみ作成されます。ソフトゲートであり、セキュリティ境界ではありません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_IN_PROGRESS。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "422": {
            "description": "次のいずれかです：SSRF_BLOCKED、TARGET_UNREACHABLE、IDEMPOTENCY_KEY_REUSED。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：現在の60秒ウィンドウ内のリクエストが多すぎます。`error.details.retry_after_seconds`はRetry-Afterと同じ値です。RateLimitはr=0とウィンドウがリセットされるまでの秒数を示します。Website Archiveのダッシュボードセッションでも「RATE_LIMITED」が返されます。これは、単一およびバッチのキャプチャ（URLごとに1ユニット）、compare、redact、certify-hash（リクエストごとに1ユニット）で共有される、UTCの1日あたりのユニット数の上限（100）によるものです。枠に収まらないリクエストは全体が拒否されます（details.daily_limit、details.remaining、details.action \"wa_session_captures\"。Retry-Afterと「details.retry_after_seconds」は翌UTC日までの秒数を示し、1分あたりのRateLimitとX-RateLimit-*ヘッダーは省略されます）。「details.retry_after_seconds」とRetry-After: 1のみの短い拒否は、カウンターの同時更新を意味するため、再試行してください。呼び出し元に起因しない拒否ではユニットは返還されます。「202」で受理された後に失敗した処理のユニットは返還されません。ソフトゲートであり、セキュリティ境界ではありません。Idempotency-Keyが保存済みの結果から返される単一キャプチャ（リプレイ、409、422）は、1日の上限より前に処理され、ユニットを消費しません。\n\nCONCURRENT_CAPTURE_LIMIT：アカウントで同時に実行中のキャプチャが多すぎます（developer 10、startup 25、growth 100、legal_solo・legal_seats 25、custom 200、website_archive 25、sandbox 5）。`details.limit`、`details.in_flight`、`details.requested`、Retry-Afterが再試行のタイミングを示します。\n\nTEST_MODE_DAILY_LIMIT：テストモードの処理（テストキー、または請求先が登録されていないセッション）には、アカウントおよびUTCの1日あたりのユニット数の上限（200）があります。`details.used`、`details.limit`、`details.reset_at`、`X-Test-Daily-*`ヘッダー、Retry-Afterが付きます。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many requests. See Retry-After header.",
                    "details": {
                      "retry_after_seconds": 42
                    }
                  },
                  "request_id": "..."
                }
              }
            }
          },
          "500": {
            "description": "「CAPTURE_FAILED」（キャプチャを開始できませんでした。details.capture_id）または「INTERNAL_ERROR」。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/EidasOrAuthUnavailable"
          }
        }
      },
      "get": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "listCaptures",
        "summary": "キャプチャの一覧を取得",
        "description": "自身が作成した行を、新しい順にすべてのステータスで返します（削除済み、つまりゴミ箱の行も含みます。statusで絞り込めます）。各行にはsource、redacted_from、label、comparedが含まれるため、再度読み取らなくても種類を表示できます。会社のために作成されたキャプチャは、それに対して操作できる間（その会社のシートを保有しているか、オーナーである間）のみ一覧に表示されます。そのため、1ページの行数がlimitより少なくなることがあり、「next_cursor」は最後に読み取った行の次から続行します。証明書、比較、墨消しも含まれます。\n\n検索（自身の一覧のみ）：url、host、「schedule_id」をfrom / toおよびstatusと組み合わせると、特定の日のページの記録を見つけられます。不正なフィルター、「url / host / schedule_id」のうち2つの指定、fromがtoより前でない場合は「400 MALFORMED_REQUEST」となります。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "ページサイズ。1〜200（デフォルト50）。範囲外の値は「400 MALFORMED_REQUEST」となります。",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "前のページの「next_cursor」（形式は「created_at|capture_id」、「order=completed_at」の場合は「completed_at|capture_id」）。変更せずに渡してください。",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "このステータスの行のみ：processing、completed、failed、deleted（ゴミ箱）。その他の値は「400 MALFORMED_REQUEST」となります。",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "url",
            "in": "query",
            "required": false,
            "description": "キャプチャされたときのこのURL（httpまたはhttps）と完全に一致するキャプチャのみ。「url」「host」「schedule_id」のうち指定できるのは1つまでです。",
            "schema": {
              "type": "string",
              "maxLength": 2048
            }
          },
          {
            "name": "host",
            "in": "query",
            "required": false,
            "description": "URLがこのホスト名にあるキャプチャのみ（大文字と小文字を区別しません。例：www.example.com。サブドメインは別のホストです）。「url」「host」「schedule_id」のうち指定できるのは1つまでです。2026-10-05より前に作成された行には、バックフィルの実行後にhostが付きます。",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "schedule_id",
            "in": "query",
            "required": false,
            "description": "このスケジュールで作成されたキャプチャのみ。「url」「host」「schedule_id」のうち指定できるのは1つまでです。",
            "schema": {
              "type": "string",
              "pattern": "^sch_[A-Za-z0-9]{8,32}$"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "この時点以降に作成されたもの：日付（YYYY-MM-DD、UTCの午前0時）またはISO 8601タイムスタンプ。",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "この時点より前に作成されたもの（この時点を含みません）：日付（YYYY-MM-DD、UTCの午前0時）またはISO 8601タイムスタンプ。fromより後である必要があります。「schedule_id」またはurlと併用すると、ある時点より前で最も新しい行が、その時点で最新だったバージョンになります。",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "description": "「created_at」（デフォルト：作成が新しい順）または「completed_at」（完了が新しい順。status=completedの場合のみ使用でき、それ以外は「400 MALFORMED_REQUEST」となります）。「completed_at」の場合、fromとtoは「completed_at」の範囲を指定し、「next_cursor」の形式は「completed_at|capture_id」になります。url、host、「schedule_id」と併用できます。",
            "schema": {
              "type": "string",
              "enum": [
                "created_at",
                "completed_at"
              ],
              "default": "created_at"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "キャプチャの1ページ分。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "captures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "capture_id": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "nullable": true
                          },
                          "status": {
                            "type": "string",
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string",
                            "nullable": true
                          },
                          "completed_at": {
                            "type": "string",
                            "nullable": true,
                            "description": "キャプチャが完了した時刻（処理中または失敗後はnull）。"
                          },
                          "batch_id": {
                            "type": "string",
                            "nullable": true
                          },
                          "schedule_id": {
                            "type": "string",
                            "nullable": true
                          },
                          "test_mode": {
                            "type": "boolean",
                            "nullable": true
                          },
                          "external_archive": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/ExternalArchive"
                              }
                            ],
                            "description": "完了した行のみ。GET /captures/{capture_id}の「external_archive」と同じです。"
                          },
                          "label": {
                            "type": "string",
                            "nullable": true,
                            "description": "行のラベル（証明書：指定されたラベル、墨消し：墨消しの対象となるキャプチャ）。"
                          },
                          "compared": {
                            "type": "array",
                            "nullable": true,
                            "items": {
                              "type": "string"
                            },
                            "description": "比較のみ：比較元の2つのキャプチャID。"
                          },
                          "source": {
                            "type": "string",
                            "nullable": true,
                            "description": "行の作成方法：api（Webキャプチャ）、schedule、certify-hash（証明書）、compare（比較）、redact（墨消し）。このフィールドより古い行ではnullです。"
                          },
                          "redacted_from": {
                            "type": "string",
                            "nullable": true,
                            "description": "墨消しのみ：墨消しの作成元のキャプチャ。"
                          },
                          "captured_at": {
                            "type": "string",
                            "nullable": true,
                            "format": "date-time",
                            "description": "ページがキャプチャされた時刻（完了した行）。墨消しの場合は、作成元キャプチャのキャプチャ時刻です（「redacted_at」は墨消しが作成された時刻です）。"
                          },
                          "redacted_at": {
                            "type": "string",
                            "format": "date-time",
                            "description": "墨消しのみ：墨消しが作成された時刻。墨消しの「captured_at」は、作成元キャプチャのキャプチャ時刻です。"
                          },
                          "compared_at": {
                            "type": "string",
                            "nullable": true,
                            "format": "date-time",
                            "description": "比較のみ：比較が作成された時刻。「captured_at」にも同じ値が入っています（古いクライアント向けに維持）。「compared_at」を使用してください。"
                          },
                          "manifest_hash": {
                            "type": "string",
                            "nullable": true,
                            "description": "パッケージのmanifest.jsonのsha256:<hex>（完了した行）。"
                          },
                          "private_note": {
                            "type": "string",
                            "nullable": true,
                            "description": "キャプチャに関する非公開のメモ（PrivateNoteを参照）。証拠パッケージには含まれません。"
                          },
                          "legal_hold": {
                            "type": "boolean",
                            "description": "キャプチャにリーガルホールドが設定されています（trueの間は削除されません。サブスクリプションが終了して30日が経過すると自動的に解除されます）。PATCH /captures/{capture_id}を参照してください。"
                          }
                        }
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "description": "このページの行数がlimitより少ない場合はnullです。",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：次のいずれかが無効です。カーソル、status（processing、completed、failed、deletedのいずれか）、limit（1〜200）、検索フィルター（url、host、schedule_id、from、to。「url / host / schedule_id」のうち指定できるのは1つまで。fromはtoより前）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/captures/batch": {
      "post": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "createBatch",
        "summary": "複数のURLをキャプチャ",
        "description": "同じオプションで、URLごとに1つのキャプチャを開始します。各キャプチャは独立しています。それぞれの「capture_id」をポーリングするか、キャプチャごとに1つのWebhookを受信してください。URLごとにレート制限1ユニットと月間上限1ユニットを使用します。1つのレート制限ウィンドウで許容されるより多くのURLを含むバッチは決して成功しないため、「429」ではなく「400 RATE_LIMIT_COST_TOO_HIGH」で拒否されます。より小さなリクエストに分割してください。完了したバッチのリプレイ（同じIdempotency-Keyと本文）は、レート制限の適用前に処理され、レート制限のユニットを消費しません。\n\nアカウント単位で60秒のウィンドウによるレート制限が適用されます（アカウントのすべてのAPIキーとそのダッシュボードセッションは1つのウィンドウを共有します）。リミッターの実行後、このルートのレスポンスには`RateLimit-Policy`と`RateLimit`ヘッダー（IETF draft-ietf-httpapi-ratelimit-headersに基づく）に加え、従来の`X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`が含まれます。「429」の場合は`Retry-After`が追加されます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              },
              "example": {
                "urls": [
                  "https://example.com/a",
                  "https://example.com/b"
                ],
                "options": {
                  "case_reference": "Smith v. Jones"
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "受理されました。同じIdempotency-Keyと本文による完了済みバッチのべき等リプレイも、`Idempotent-Replay: true`を伴う「202」を返します。これはレート制限の適用前に処理されるため、レート制限のユニットを消費しません。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              },
              "X-Quota-Limit": {
                "$ref": "#/components/headers/QuotaLimit"
              },
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/QuotaRemaining"
              },
              "X-Quota-Used": {
                "$ref": "#/components/headers/QuotaUsed"
              },
              "X-Quota-Cap": {
                "$ref": "#/components/headers/QuotaCap"
              },
              "X-Quota-Org-Limit": {
                "$ref": "#/components/headers/QuotaOrgLimit"
              },
              "X-Quota-Org-Used": {
                "$ref": "#/components/headers/QuotaOrgUsed"
              },
              "X-Sandbox-Limit": {
                "$ref": "#/components/headers/SandboxLimit"
              },
              "X-Sandbox-Remaining": {
                "$ref": "#/components/headers/SandboxRemaining"
              },
              "X-Sandbox-Used": {
                "$ref": "#/components/headers/SandboxUsed"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                }
              }
            }
          },
          "400": {
            "description": "「INVALID_BATCH」（details：reasonとreceived、または無効なURLについてのindex、url、ネストされたreasonオブジェクト）、「MALFORMED_REQUEST」、またはオプションのエラー。WEBHOOK_REQUIRES_API_KEY：ダッシュボードセッションから「webhook_url」が送信されました（WebhookにはAPIキーが必要です）。RATE_LIMIT_COST_TOO_HIGH：1つのレート制限ウィンドウで許容されるより多くのURLが指定されました。details { reason, max_per_window, window_seconds, requested }。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "「QUOTA_EXCEEDED」または「PAYMENT_REQUIRED」。月間の使用量をその時点で読み取れない場合も、バッチは「QUOTA_EXCEEDED」で拒否されます。再試行してください。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "EIDAS_REQUIRES_LIVE_KEY：テストキーで「include_eidas」が指定されました。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッションです。PLAN_ARCHIVE_ONLY：このプランはアーカイブの保持のみで、新しい処理を作成しません。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。PLAN_API_READ_ONLY、details.reason \"session_outside_dashboard\"：Website Archiveアカウントのダッシュボードセッションで、リクエストにOriginヘッダーがないか、ProofSnapダッシュボードのアドレスではありません（このプランの新しい処理はダッシュボードでのみ作成されます。ソフトゲートであり、セキュリティ境界ではありません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_IN_PROGRESS。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "422": {
            "description": "エラーコード：IDEMPOTENCY_KEY_REUSED。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：現在の60秒ウィンドウ内のリクエストが多すぎます。`error.details.retry_after_seconds`はRetry-Afterと同じ値です。RateLimitはr=0とウィンドウがリセットされるまでの秒数を示します。Website Archiveのダッシュボードセッションでも「RATE_LIMITED」が返されます。これは、単一およびバッチのキャプチャ（URLごとに1ユニット）、compare、redact、certify-hash（リクエストごとに1ユニット）で共有される、UTCの1日あたりのユニット数の上限（100）によるものです。枠に収まらないリクエストは全体が拒否されます（details.daily_limit、details.remaining、details.action \"wa_session_captures\"。Retry-Afterと「details.retry_after_seconds」は翌UTC日までの秒数を示し、1分あたりのRateLimitとX-RateLimit-*ヘッダーは省略されます）。「details.retry_after_seconds」とRetry-After: 1のみの短い拒否は、カウンターの同時更新を意味するため、再試行してください。呼び出し元に起因しない拒否ではユニットは返還されます。「202」で受理された後に失敗した処理のユニットは返還されません。ソフトゲートであり、セキュリティ境界ではありません。\n\nCONCURRENT_CAPTURE_LIMIT：アカウントで実行中のキャプチャがすでに上限に達しているため（developer 10、startup 25、growth 100、legal_solo・legal_seats 25、custom 200、website_archive 25、sandbox 5）、バッチのURLを1つも開始できませんでした。`details.limit`、`details.in_flight`、`details.requested`、Retry-Afterが付きます。一部のみ枠に収まる場合は、バッチは「202」で受理され、残りが`not_admitted`に列挙されます。\n\nTEST_MODE_DAILY_LIMIT：テストモードの処理（テストキー、または請求先が登録されていないセッション）には、アカウントおよびUTCの1日あたりのユニット数の上限（200）があり、URLごとに1ユニットです。`details.used`、`details.limit`、`details.reset_at`、`X-Test-Daily-*`ヘッダー、Retry-Afterが付きます。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many requests. See Retry-After header.",
                    "details": {
                      "retry_after_seconds": 42
                    }
                  },
                  "request_id": "..."
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/EidasOrAuthUnavailable"
          }
        }
      }
    },
    "/captures/hosts": {
      "get": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "listCaptureHosts",
        "summary": "キャプチャしたホスト名の一覧を取得",
        "description": "自身のキャプチャ一覧にあるすべてのホスト名を、ホストごとのキャプチャ数と最新のキャプチャ時刻とともに返します。ドメインフィルターに使用できます。hostをGET /captures?host=に渡してください。countは、GET /captures?host=<host>がstatusなしで返す行数です（読み取られたキャプチャの範囲内）。テストキャプチャと本番キャプチャの両方、およびゴミ箱内（status deleted）を含むすべてのステータスの行が一覧と同様に算入されます。消去されたキャプチャとページURLのない行（証明書）は除外されます。キャプチャは、保存されたホスト名を持った時点で算入されます（2026-10-05より前に作成されたキャプチャには、バックフィルの実行後に付きます）。会社のキャプチャは、それに対して操作できる間（その会社のシートを保有しているか、オーナーである間）のみ算入されます。hostは小文字です。countの降順、次にhostの昇順（AからZ）で並びます。最大1000ホストです。読み取られるのは最新の5000キャプチャで、1000を超えるホストがある場合、またはこの5000より古いキャプチャがある場合はtruncatedがtrueとなり、それより前にのみキャプチャされたホストは含まれないことがあります。一覧の計算はアカウントごとに30秒に最大1回で、最大30秒古い場合があります（同じアカウントの別のリクエストが計算している間は、さらに少し古くなります）。計算には1分あたりのレート制限を1ユニット消費しますが、キャッシュから返されるレスポンスでは消費しません。すべてのプランで、APIキーとダッシュボードセッションから利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "ホスト名。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "hosts",
                    "truncated"
                  ],
                  "properties": {
                    "hosts": {
                      "type": "array",
                      "maxItems": 1000,
                      "items": {
                        "type": "object",
                        "required": [
                          "host",
                          "count",
                          "last_captured_at"
                        ],
                        "properties": {
                          "host": {
                            "type": "string",
                            "example": "www.example.com",
                            "description": "小文字のホスト名。GET /captures?host=が受け取る値です。"
                          },
                          "count": {
                            "type": "integer",
                            "minimum": 1,
                            "example": 12,
                            "description": "読み取られたキャプチャのうち、このホストのキャプチャ数。GET /captures?host=がstatusなしで返す行で、ゴミ箱内の行も含みます。"
                          },
                          "last_captured_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "example": "2026-10-05T07:48:38Z",
                            "description": "このホストの最新のキャプチャ時刻（ページがキャプチャされた時刻、それがない場合はキャプチャがリクエストされた時刻）。UTC、秒単位です。"
                          }
                        }
                      }
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "一覧が不完全な可能性がある場合にtrueとなります：1000を超えるホストがある場合、または読み取られた最新の5000より多くのキャプチャがある場合です。"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：scopeはサポートされていません（自身のキャプチャのみ）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "description": "RATE_LIMITED：1分あたりのレート制限を使い切りました（一覧の計算には1ユニットかかります）。または、アカウントの一覧を別のリクエストが計算中で、以前の結果が保存されていません。Retry-Afterの秒数の後に再試行してください。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many requests. See Retry-After header.",
                    "details": {
                      "retry_after_seconds": 42
                    }
                  },
                  "request_id": "..."
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/captures/{capture_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/CaptureId"
        }
      ],
      "get": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "getCapture",
        "summary": "キャプチャを取得",
        "description": "ステータスと、完了後は最大24時間有効な新しい「package_url」を返します（ProofSnap MCPサーバー経由でリクエストした場合は15分。「package_url_expires_at」を参照）。キャプチャ、証明書、比較、墨消しのIDで使用できます。読み取りができるのは、作成したアカウント、それが属する案件のメンバー、それが作成された会社のオーナーです（会社のサブスクリプションが終了している場合は、ダウンロード期間が終了するまで）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "event",
            "in": "query",
            "required": false,
            "description": "パッケージをダウンロードするときはdownloadを送信してください。案件内のキャプチャの場合、案件のアクセスログにcapture.downloadedが記録されます。単なるステータスのポーリングでは省略してください。",
            "schema": {
              "type": "string",
              "enum": [
                "download"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "キャプチャ。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaptureResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "FORBIDDEN：自身のキャプチャではありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CAPTURE_NOT_FOUND：IDが不明または不正である、キャプチャが削除済みである、またはパッケージファイルが見つかりませんでした。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "delete": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "deleteCapture",
        "summary": "キャプチャを削除",
        "description": "デフォルトでは、キャプチャをゴミ箱に移動します。restorable_until（30日）まではPATCHで復元でき、その後は完全に消去されます。permanent=trueを指定すると、保存されているパッケージは直ちに消去され、記録はトゥームストーンのみになります。この操作は元に戻せません。いずれの場合も、ダウンロード済みのパッケージやOpenTimestamps証明は削除されません。オープンまたはアーカイブ済みの案件内のキャプチャは、呼び出し元がその案件を開ける場合、まず案件から除外されます（案件の証拠管理ログに記録されます）。開けない呼び出し元（案件から除外された後の作成者）は、案件のオーナーが案件から除外するまで、ゴミ箱への移動でもpermanent=trueでも「409 MATTER_LINKED」で拒否されます。封印済みの案件内のキャプチャは削除できません。処理中のキャプチャは削除できません（409 CAPTURE_PROCESSING）。完了または失敗した後に削除してください。完了しなかったキャプチャを削除すると、その月間の利用枠は戻されます。\n\nリーガルホールド解除後の猶予：リーガルホールドの解除後14日間（GETの`deletion_blocked_until`）は、人による操作でも、ゴミ箱の消去や保存期間によっても、キャプチャは完全に削除されません（`details.until`を伴う「409 CAPTURE_HOLD_GRACE」。サブスクリプション終了後のアカウントおよび会社の削除はこれを待ちません）。ゴミ箱への移動は可能ですが、その消去は猶予期間の終了を待ちます。完全に削除する場合は、まず保存オブジェクトに残っているS3 Object Lockのリーガルホールドを解除します。ストレージがこれを拒否した場合、リクエストは「409 CAPTURE_LEGAL_HOLD」（\"still locked in storage\"、後で再試行）を返し、何も削除されません。ゴミ箱への移動、復元、完全に削除する操作はすべて、アカウントのキャプチャイベントチェーン（GET /captures/events）に記録されます。ソースキャプチャにリーガルホールドが設定されている墨消しまたは比較は、ゴミ箱への移動または削除の際に`source_under_legal_hold: true`を返します。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "permanent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "true"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "削除されました。ゴミ箱：{ capture_id, status: \"deleted\", restorable: true, restorable_until }。完全に削除：{ capture_id, status: \"deleted\", permanent: true }。すでにゴミ箱内：{ capture_id, status }。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "capture_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "restorable": {
                      "type": "boolean"
                    },
                    "restorable_until": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "permanent": {
                      "type": "boolean"
                    },
                    "source_under_legal_hold": {
                      "type": "boolean",
                      "description": "リーガルホールドが設定されたキャプチャから作成された墨消しまたは比較の場合にのみ存在します（true）。"
                    },
                    "deletion_blocked_until": {
                      "type": "string",
                      "format": "date-time",
                      "description": "解除後の猶予期間中のゴミ箱移動：ゴミ箱の消去はこの時刻まで待機します。"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "FORBIDDEN：自身のキャプチャではありません。キャプチャが未封印の案件に属し、呼び出し元（シートのキャプチャを操作する会社のオーナーで、その作成者ではない場合）がその案件を開けない場合も「FORBIDDEN」となります。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "エラーコード：CAPTURE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "MATTER_SEALED：キャプチャは封印済みの案件の証拠書類です。MATTER_LINKED：キャプチャは呼び出し元がすでに所属していない案件の証拠書類です。先に案件のオーナーが除外します。CAPTURE_PROCESSING：キャプチャは処理中です（error.details.status）。CAPTURE_PROCESSING、error.details.reason \"signed_document_order\"：キャプチャは、支払い済みまたは進行中の署名文書注文、もしくはチェックアウト期間内（プラス5分）の未払いの注文に含まれています。CAPTURE_LEGAL_HOLD：キャプチャにリーガルホールドが設定されており、誰であっても削除（ゴミ箱への移動または消去）できません。CAPTURE_HOLD_GRACE：キャプチャのリーガルホールド解除後の猶予期間内に完全に削除しようとしました（LEGAL_HOLD_RELEASE_GRACE_DAYS、14日）。「error.details.until」が可能になる時刻を示します。猶予期間中もゴミ箱への移動は可能です。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR：保存されたパッケージを消去できませんでした。何も削除されていません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "patch": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "restoreCapture",
        "summary": "削除したキャプチャの復元、プライベートメモの設定、リーガルホールドの設定または解除",
        "description": "キャプチャをゴミ箱から復元します。削除時に案件から除外されていた場合、その案件がまだオープンで、呼び出し元がまだ開ける場合には案件に戻されます。レスポンスに「matter_id」と「matter_relinked」が含まれるのはこの場合のみです（再リンクが行われなかった場合、「matter_id」はnullです）。その案件を開けなくなった呼び出し元には、案件なしでキャプチャが戻され、案件の証拠管理ログには何も書き込まれず、レスポンスでも案件には言及されません。ゴミ箱にないキャプチャは、変更されずに返されます。\n\nプライベートメモ：`private_note`（文字列で文字数の上限：200、消去する場合はnull）を含む本文は、キャプチャのプライベートメモのみを設定し、他の処理は行いません。`action`とは併用できません。メモはキャプチャの記録にのみ保存され、封印された証拠パッケージの外にあるため、変更しても証拠やそのハッシュが変わることはありません。設定できるのはキャプチャの作成者のみで（会社のオーナーと案件のメンバーには「403」が返されます）、完全に削除されたキャプチャ（404）を除き、どの状態のキャプチャにも設定できます。レスポンスは{ capture_id, status, private_note }です。\n\nリーガルホールド：本文`{ \"action\": \"legal_hold\", \"enabled\": true|false, \"reason\"?: string }`は、キャプチャのリーガルホールドを設定（true）または解除（false）し、他の処理は行いません。リーガルホールドが設定されたキャプチャは削除されません。DELETE（ゴミ箱への移動または完全に削除）は誰に対しても「409 CAPTURE_LEGAL_HOLD」を返し、ゴミ箱の消去も保存期間による削除も適用されません。GETでは`storage.retention.earliest_deletion_at`がnullと表示されます。リーガルホールドが維持されるのは、アカウントにデータを保持するプランがある間のみです（Archive onlyを含むすべての有料プラン。会社のキャプチャの場合は、会社が有効であるか、会社アーカイブとして保持されている間）。サブスクリプションが終了すると、キャプチャは30日間利用可能なままです。それまでにそのようなプランを購入しないと、アカウント（または会社）のすべてのリーガルホールドはその日に自動的に解除され（actorはsystem、reasonは「subscription_ended」。他の解除と同様に記録されますが、解除後の猶予はありません）、キャプチャは他のものとともに削除されます。リーガルホールド中のキャプチャを保持するには、その日より前にArchive onlyに切り替える（または会社アーカイブを購入する）か、ダウンロードしてください。この30日間は新しいリーガルホールドを設定できません（アカウントに有料プランがないため）が、既存のリーガルホールドは引き続き解除できます。リーガルホールドはキャプチャの記録にのみ保存され、封印された証拠パッケージの外にあります。`reason`は任意のプレーンテキストです（文字数の上限：200、制御文字、不可視文字、テキスト方向文字は使用不可、空白は1つにまとめられ、空欄はなしとして扱われます）。リーガルホールドとともに保持され、解除時に消去されます。\n\n権限：リーガルホールドを設定できるのは、キャプチャに対して操作できるすべての人です（作成者。会社のキャプチャの場合はその会社のシートを保有している間のみ。および会社のオーナー。サブスクリプションが終了した会社でも、保存期間内または会社アーカイブとして保持されている間は可能ですが、アーカイブの場合はダッシュボードセッションからのみ）。解除できるのは、個人のキャプチャではその作成者、会社のキャプチャでは会社のオーナーのみです（シート保有者には「403 LEGAL_HOLD_OWNER_ONLY」が返されます）。リーガルホールドの設定には有料プラン（Archive onlyを含むすべての有料プラン）が必要です。無料のサンドボックスおよびサブスクリプションが終了したアカウントには、details.reason \"plan\"を伴う「403 LEGAL_HOLD_NOT_AVAILABLE」が返されます（有効な会社アーカイブは、オーナーのダッシュボードセッションを通じて、その会社のキャプチャについて有料として扱われます）。テストモードのキャプチャ（透かし入り、テストキーまたは請求の連携なしで作成）には、details.reason \"test_capture\"を伴う「403 LEGAL_HOLD_NOT_AVAILABLE」が返されます。リーガルホールドの解除は、サブスクリプションの終了後も含め、すべてのプランで可能です。Website ArchiveではAPIキーは読み取り専用（403 PLAN_API_READ_ONLY）ですが、ダッシュボードセッションでは可能です。支払い期限超過または未払いのサブスクリプションでも妨げられません。メールアドレスが未確認のダッシュボードセッションまたはキーには「403 EMAIL_NOT_VERIFIED」が返されます。\n\nゴミ箱内のキャプチャ（409 CAPTURE_IN_TRASH：先に復元してください）または処理中のキャプチャ（409 CAPTURE_PROCESSING）では拒否されます。完全に削除されたキャプチャ、または完全に削除する処理の実行中のキャプチャでは「404」となります。リーガルホールドのリクエストごとに、アカウントの1分あたりのレート制限を1ユニット消費します（使い切ると「429 RATE_LIMITED」とRetry-After）。キャプチャがすでに持つ状態を送信しても何も変わらず、保存されたフィールドと`changed: false`を伴う「200」が返されます。各変更は「capture.legal_hold」として監査ログに記録され（会社のキャプチャの場合は会社のテナント内）、キャプチャのアクセス履歴に記録され（`legal_hold_on` / `legal_hold_off`、後でキャプチャが消去されても保持されます）、キャプチャが案件に属する場合は、キャプチャIDを対象として「capture.legal_hold_placed」または「capture.legal_hold_released」として案件の証拠管理ログに書き込まれます（理由は案件のアクセスログに記録され、ハッシュチェーンには含まれません。封印済みの案件のチェーンは変更されません）。レスポンスは{ capture_id, legal_hold, legal_hold_set_at, legal_hold_reason, changed }です。\n\nリーガルホールドv2：リーガルホールドを設定または解除すると、保存されたパッケージ、そのアップグレード済みOpenTimestamps証明、別途保存された複製のすべてのバージョンについて、S3 Object Lockのリーガルホールドも設定または解除されます（GETの`s3_legal_hold`。ストレージが拒否した場合やObject Lock構成がない場合でも、キャプチャの記録上のリーガルホールドは引き続き適用され、失敗した試行はサーバーが再試行します）。解除すると14日間の猶予が始まり、その間キャプチャは完全に削除されません（サブスクリプション終了後は該当せず、終了後の30日間がこれに代わります）。案件のリーガルホールドによって設定されたもの（`legal_hold_source` \"matter:<id>\"）は、そのリーガルホールドが有効な間は案件側で解除します。ここで解除しようとすると「409 LEGAL_HOLD_MATTER」となります（案件を閲覧できる人にはerror.details.matter_id）。各変更は、アカウントのキャプチャイベントチェーン（GET /captures/events）に記録されます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "description": "restore（「private_note」のない本文のデフォルト）または「legal_hold」（enabledと任意のreasonを指定）。",
                    "enum": [
                      "restore",
                      "legal_hold"
                    ]
                  },
                  "private_note": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/PrivateNote"
                      }
                    ],
                    "description": "プライベートメモを設定（文字列）または消去（nullまたは空文字列）します。actionとは併用できません。"
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "actionが「legal_hold」の場合（その場合は必須）：trueでリーガルホールドを設定し、falseで解除します。"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 200,
                    "description": "actionが「legal_hold」の場合、任意：キャプチャを保持する理由。プレーンテキストです（文字数の上限：200）。リーガルホールドとともに証拠パッケージの外に保存されます。解除時には無視されます（その場合は監査ログにのみ記録されます）。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "復元済み（{ capture_id, status, restored: true, matter_id?, matter_relinked? }）、変更なし（{ capture_id, status }）、プライベートメモの設定済み（{ capture_id, status, private_note }）、またはリーガルホールドの設定済み（{ capture_id, legal_hold, legal_hold_set_at, legal_hold_reason, changed }）。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "capture_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "restored": {
                      "type": "boolean"
                    },
                    "matter_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "matter_relinked": {
                      "type": "boolean"
                    },
                    "private_note": {
                      "type": "string",
                      "nullable": true
                    },
                    "legal_hold": {
                      "type": "boolean",
                      "description": "リーガルホールドのアクション：リクエスト後のキャプチャのリーガルホールドの状態。"
                    },
                    "legal_hold_set_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "リーガルホールドのアクション：現在のリーガルホールドが設定された時刻（ない場合はnull）。"
                    },
                    "legal_hold_reason": {
                      "type": "string",
                      "nullable": true,
                      "description": "リーガルホールドのアクション：現在のリーガルホールドとともに保存された理由、またはnull。"
                    },
                    "changed": {
                      "type": "boolean",
                      "description": "リーガルホールドのアクション：キャプチャがすでにリクエストされた状態だった場合はfalse（何も変更も記録もされていません）。"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：JSONが無効、本文がオブジェクトではない、actionがrestoreまたは「legal_hold」以外である、「private_note」がactionと併用されている、または「private_note」が文字列でもnullでもない、文字数が「200」を超える、制御文字、不可視文字、テキスト方向文字を含む、のいずれかです。「legal_hold」の場合：enabledがない、またはブール値ではない、reasonが文字列ではない、文字数が「200」を超える、またはプレーンテキストではない、不明なフィールドがある、のいずれかです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "FORBIDDEN：自身のキャプチャではありません。キャプチャが未封印の案件に属し、呼び出し元（シートのキャプチャを操作する会社のオーナーで、その作成者ではない場合）がその案件を開けない場合も「FORBIDDEN」となります。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。「private_note」の場合：キャプチャの作成者（引き続き操作を許可されている必要があります）以外には「FORBIDDEN」となります。「legal_hold」の場合：呼び出し元がキャプチャに対して操作できないときは「FORBIDDEN」、シート保有者（会社のオーナーではない）が会社のキャプチャのリーガルホールドを解除するときは「LEGAL_HOLD_OWNER_ONLY」、有料プランなしでリーガルホールドを設定するとき（details.reason plan）またはテストモードのキャプチャに設定するとき（details.reason test_capture）は「LEGAL_HOLD_NOT_AVAILABLE」、メールアドレスが未確認のときは「EMAIL_NOT_VERIFIED」となります。上記の案件に関するルールは、リーガルホールドには適用されません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "「CAPTURE_NOT_FOUND」。完全に削除されたキャプチャも含みます。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "リーガルホールドのみ。CAPTURE_IN_TRASH：キャプチャはゴミ箱内にあります。先に復元してください。CAPTURE_PROCESSING：キャプチャは処理中です（error.details.status）。LEGAL_HOLD_MATTER：キャプチャのリーガルホールドは案件のリーガルホールドによって設定されており、まだ有効です。案件側で解除してください。LEGAL_HOLD_SOURCE：墨消しまたは比較のリーガルホールドは、作成元のキャプチャ（比較の場合は比較対象のいずれかのキャプチャ）に従っており、そのキャプチャにはまだリーガルホールドが設定されています（そのキャプチャに直接、またはその案件を通じて設定）。パッケージは、そのリーガルホールドが解除されるまで保持されます（`details.source_capture_id`）。比較は、比較対象のいずれかのキャプチャがリーガルホールド中であれば保持され、どちらもリーガルホールド中でなくなった場合にのみ解除されます（`legal_hold_source` \"derived:<capture id>\"が保持中のキャプチャを示します）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "リーガルホールドのみ。RATE_LIMITED：アカウントの1分あたりのレート制限を使い切りました。`error.details.retry_after_seconds`はRetry-Afterと同じ値です。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/captures/{capture_id}/verify": {
      "parameters": [
        {
          "$ref": "#/components/parameters/CaptureId"
        }
      ],
      "post": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "verifyCapture",
        "summary": "保存されたパッケージを検証",
        "description": "保存されたパッケージを読み取り、manifest.jsonのRSA署名と、そこに記載された各ファイルのハッシュ（SHA-256）を確認します。容量の上限（256 MiB）を超えるパッケージでは「413 VERIFY_PACKAGE_TOO_LARGE」が返されます。これらは同梱のスクリプトでオフラインで検証してください。各リクエストは、アカウントの1分あたりのレート制限を1ユニット消費します（429 RATE_LIMITED）。パッケージにmanifest.json.tsrが含まれる場合、eIDASタイムスタンプトークンもProofSnapが確認します（checks.eidas）。確認内容は、トークンの署名と署名付き属性、manifest.jsonのハッシュ（SHA-256）を含むこと、TSA証明書のextendedKeyUsage、トークンの時刻（genTime）時点での固定されたルートCA Disig QCA4までの証明書チェーン、および発行時に「eidas_validation.json」に記録されたOCSPレスポンスまたはCRLによるTSA証明書のステータス（署名によって検証し、ライブでは取得しません）です。この確認で新しいタイムスタンプをリクエストすることはありません。また、manifest.json.otsの有無と、マニフェストハッシュがProofSnapの発行台帳にあるかどうかも報告します。判定は、マニフェストの署名と記載されたファイルのみに基づきます。確認に失敗したトークンは、checks.eidasとwarningsで報告され（EIDAS_TOKEN_FAILED）、判定には反映されません。適格タイムスタンプ付きで発行されたパッケージは、署名付きのmanifest.jsonに「eidas_requested: true」を記録します。このようなパッケージにmanifest.json.tsrがなくなっている場合、checks.eidasと「checks.eidas_disig」は欠落として報告され、警告「EIDAS_TOKEN_MISSING」が付きます（同梱の検証スクリプトは同じパッケージに対してFAILを報告します）。キャプチャのオーナー、その案件のメンバー、それが作成された会社のオーナーが実行できます。タイムスタンプを独立して確認するには、パッケージのverification/フォルダー内のスクリプトを実行してください。\n\nインポートされたパッケージ（source import）：保存されたZIPをインポート時のチェックで再確認します（署名、すべてのファイル、証拠管理、フォレンジックチェーン、タイムスタンプ。来歴は、APIパッケージではAPIの発行台帳で再度照会し、拡張機能パッケージではインポート記録から取得します）。レスポンスは{ capture_id, source, type: \"import\", package_kind, verifier: \"package-verify\", verdict (match, modified, invalid), rechecked: true, manifest_sha256, zip_sha256, zip_matches_import, kind, summary, levels, checks, reasons, provenance }です。容量の上限（512 MiB）を超えるパッケージ、または約20秒以内に完了しない確認では、rechecked: falseと理由（too_large_for_synchronous_check、time_budget、storage_error）、verdict: null、「stored_verification」（インポート時に記録されたレポート）が返されます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "検証結果。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyResult"
                },
                "example": {
                  "verdict": "match",
                  "capture_id": "cap_a1B2c3D4e5F6g7H8",
                  "source": "s3",
                  "checks": {
                    "manifest_signature": {
                      "status": "valid",
                      "algorithm": "RSA-4096"
                    },
                    "declared_files": {
                      "status": "all_match"
                    },
                    "bitcoin_ots": {
                      "status": "present"
                    },
                    "eidas_disig": null,
                    "proofsnap_issuance": {
                      "status": "issued_by_proofsnap",
                      "manifest_sha256": "3f2a...",
                      "issued_at": "2026-09-01T10:00:00.000Z",
                      "type": "capture"
                    },
                    "eidas": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "FORBIDDEN。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CAPTURE_NOT_FOUND：不明、削除済み、または保存されたパッケージがありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "VERIFY_PACKAGE_TOO_LARGE：保存されたパッケージが上限（256 MiB）を超えています。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：アカウントの1分あたりのレート制限を使い切りました。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "CONFIGURATION_ERROR：保存されたパッケージを読み取れませんでした。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/captures/{capture_id}/redact": {
      "parameters": [
        {
          "$ref": "#/components/parameters/CaptureId"
        }
      ],
      "post": {
        "tags": [
          "比較と墨消し"
        ],
        "operationId": "redactCapture",
        "summary": "墨消しコピーを作成",
        "description": "完了したキャプチャから、選択した内容を除去した新しいパッケージを構築し、再署名（新しいRSA-4096鍵）して、OpenTimestampsアンカーのために送信します。元のパッケージは変更されません。同期処理で、パッケージの準備ができると「201」を返します。1キャプチャとして計測されます。\n\n- ボックス墨消しは、スクリーンショットの領域を黒く塗りつぶします。キャプチャが書き込む形式（シーケンシャル、グレースケールまたはYCbCr）のJPEGスクリーンショットは、ピクセルにデコードせずに墨消しされます。ボックスが触れる圧縮ブロック（MCU、一辺8〜32ピクセル）を黒いブロックに置き換え、他のブロックはすべて変更せずに維持するため、画像の残りの部分は再圧縮されません（`screenshot_method` `jpeg_dct_blocks`、上限：150 MP）。塗りつぶされる領域は、各ボックスをブロック単位に切り上げたもの（`painted_rects`）で、常にボックスを含みます。PNGスクリーンショットまたは他の種類のJPEGは、デコードして塗りつぶし、screenshot.jpegとして再エンコードした後、新しいファイルでボックスが触れる8 x 8ブロックを黒く塗りつぶします（`screenshot_method` `decode_repaint_jpeg`、上限：60 MP）。上限を超えるスクリーンショットや画像データを読み取れないスクリーンショットは、課金前に「422 REDACTION_SCREENSHOT_UNREADABLE」で拒否されます。ヘッダーは読み取れるものの画像データを読み取れない場合、このエラーは月間ユニットの予約後に検出され、そのユニットは解放されます。テキストとメタデータの墨消しは、ボックスがなくても機能します。redaction_manifest.json（`screenshot_boxes`）には、方式、`painted_rects`、ブロックグリッド、フォレンジック鑑定人向けの説明が記録されます。\n- テキスト墨消しは、一致箇所をpage.htmlとdomtextcontent.txtから、metadata.jsonのすべての自由記述値（ページタイトルとメタ値、WHOIS / RDAPレコード、TLSサブジェクト、HTTPレスポンスヘッダーの値）から、さらに、forensic_log.json、chain_of_custody.jsonのすべての自由記述値（case_reference、case_id、case_note、指定したメタデータ値、挿入されたコードとそのエラー、閉じたポップアップのラベル、legal_context.note）から除去します。これらの記録内の識別子、ハッシュ、時刻、URLは変更されません。エンコードされた出現箇所も除去されます。HTML文字参照（名前付き、10進数、16進数。例：M&uuml;ller、jan&#64;firma.cz）、パーセントエンコーディング（mailto:jan%40firma.cz）、JavaScriptエスケープ（\\u0040、\\x40）が対象で、2階層までのネストされたエンコーディングも含みます。マーカーはエンコードされた文字そのものを置き換えます。墨消し後の残存チェックは、JSONファイルを値ごとに読み取り、すべてのテキストを記述どおりの形とデコードした形の両方で検索するため、これらのいずれかの形で一致があれば失敗します。テキスト墨消しは、ソースキャプチャの「text_layout.json」が出現箇所を特定している位置のスクリーンショットも黒く塗りつぶします（`text_rule_rects`）。一致を含むテキストブロックの推定行が塗りつぶされ、推定が不確かな場合にのみブロック全体が塗りつぶされます（redaction_manifest.jsonの`screenshot_boxes.from_text_rules.rects_whole_block`に計上されます）。特定できなかった出現箇所は`text_occurrences_not_located`に計上されます。`case_insensitive`を指定しない限り、ルールは大文字と小文字を区別して一致します。\n- メタデータ墨消しは、metadata.jsonからフィールドを除去します。2つの名前は適用範囲がより広くなります。`ip_dns`（`ip`、`dns`、`resolved_ips`も可）は、対象サイトのIPアドレスとDNS回答をmetadata.json、forensic_log.json、chain_of_custody.jsonから除去し（キャプチャマシン自体のアドレスは残ります）、さらに自動テキストルールとして、page.html、domtextcontent.txt、スクリーンショットからも完全なアドレスのみを除去します（「source ip_dns」のみが記録され、アドレスやそのハッシュは記録されず、「text_redactions」の上限には算入されません）。`cookie_names`（`cookie`、`cookies`、`http_headers.cookie`も可）は、これらの記録からCookieおよびSet-Cookieヘッダーとcookie名のすべてのリストを除去します。件数は維持されます。cookieの値は、すべてのキャプチャですでに墨消しされています。\n\nボックスが覆うのはピクセルのみです。ボックスの下のテキストは、テキスト墨消しも追加しない限りpage.html、domtextcontent.txt、metadata.jsonに残ります。また、ボックスの下の画像は、page.htmlで引き続き参照または埋め込まれている場合があります（img srcまたはsrcset、CSS url()、data: URI）。そのアドレスに一致するテキスト墨消しを行えば、その参照は除去されます。墨消しされたパッケージには、元のパッケージのscreenshot.jpeg（またはボックスで置き換えられなかった場合はscreenshot.png）、page.html、domtextcontent.txt、metadata.json、forensic_log.jsonと、新たに書き込まれるファイル（evidence.pdf、chain_of_custody.json、redaction_manifest.json、検証ファイル、マニフェストファイル）のみが含まれます。元のパッケージのその他のファイル（images/、image_inventory.json、text_layout.json、page.mhtml、network.har、capture.warcなど）は除外され、redaction_manifest.jsonの「dropped_for_leak_protection」に記載されます。画像のコピーはそのURLにちなんで命名されるため、テキスト墨消しはこれらのファイル名にも適用されます。chain_of_custody.jsonは、これらのファイルに関する元のイベントを保持し、「artifact_removed_in_redaction」とマークして、墨消しされたパッケージに含まれないファイルのハッシュを除きます。元のパッケージの「rule_902_certification.pdf」も、元のファイルとハッシュを記載しているため除去されます。この除去は、redaction_manifest.json（removed_as_stale）、chain_of_custody.jsonに記載されます。キャプチャURLは署名付きマニフェストの一部であるため、墨消しされることはありません。テキストがキャプチャURLまたは最終URLにも含まれるテキスト墨消しは、それ以外のすべての箇所に適用され、そのURL内のテキストは残り、ルールは`rules_in_capture_url`、redaction_manifest.json（leakage_check.capture_url）に記載されます。墨消しできるのはWebページのキャプチャのみです（比較、証明、墨消しは「422 REDACTION_SOURCE_UNSUPPORTED」で拒否されます）。\n\nテストキャプチャ（テストキー、サンドボックス、または請求アカウントが連携されていないアカウントで作成）の墨消しは、どのキーでリクエストしてもテストパッケージになります。透かしが入り、manifest.jsonに`test_mode: true`が記録され、テスト行（key_env test）となって計測されず、月間ユニットも使用しません。このような墨消しで「include_eidas」を指定すると「403 EIDAS_REQUIRES_LIVE_KEY」（details.reason）で拒否されます。\n\n墨消しレポート（evidence.pdf）は、本文、表紙、テストバナーを含めて`language`（デフォルト：ソースキャプチャの言語）で生成されます。\n\n墨消しの前に、墨消しで読み取るまたは含めるファイル（スクリーンショット、page.html、domtextcontent.txt、metadata.json、forensic_log.json、chain_of_custody.json、text_layout.json）のうち、ソースのマニフェストにハッシュ（SHA-256）が記載されているものはすべて再計算されます（redaction_manifest.json derived_from.source_files_rehashed）。不一致またはファイルの欠落があると「422 REDACTION_SOURCE_INTEGRITY_FAILED」が返されて何も発行されないため、破損または改変されたソースが新しい署名で再封印されることはありません。墨消しされたパッケージから除外されるファイルは読み取られません。ソースの読み取りに時間がかかりすぎた同期の墨消しは、何も予約される前に「500 CAPTURE_TIME_BUDGET_EXCEEDED」で停止します。\n\nリーガルホールドが設定されたキャプチャの墨消しにもリーガルホールドが設定され（legal_hold_source \"derived:<capture id>\"）、キャプチャにリーガルホールドが設定されたときは、そのキャプチャのすべての墨消しにも同様に設定されます。キャプチャのリーガルホールドを解除するとこれらも解除され、キャプチャがリーガルホールド中の間は単独で解除できません（409 LEGAL_HOLD_SOURCE）。墨消しの行の「captured_at」は、そのソースのキャプチャ時刻です。「redacted_at」は墨消しが作成された時刻です。\n\n墨消しはフェイルクローズで動作します。墨消し後のチェックで、キャプチャURLと最終URL以外のパッケージ内のいずれかの箇所に墨消し対象の語句がまだ見つかった場合、パッケージは発行されず、リクエストは「422 REDACTION_LEAK_DETECTED」を返します（`error.details` `{ files, rule_indexes, metadata_fields, in_capture_url }`。語句自体が返されることはありません）。redaction_manifest.jsonには`leakage_check.fail_closed: true`が記録されます。\n\n値は文字の境界で切り詰められます（文字が分割されることはありません）。上限（文字数）は、テキストの一致文字列：2000、理由：200、reason_summary：500、custodianフィールド：200。理由、「reason_summary」、custodianフィールドは墨消し証明書に印字されるため、プレーンテキストである必要があります。制御文字、不可視文字、テキスト方向文字は「400」で拒否されます。\n\n制限時間と再試行：リクエストはAPI Gatewayの29秒の制限内に返されます。封印はリクエストから数えた制限時間内で実行されます。適格タイムスタンプ（include_eidas）が予算内に収まらない場合はリクエストされず、パッケージはOpenTimestampsアンカーのみで提供されます（timestamps.eidas status not_obtained、reason time_budget、課金なし）。収まらないOpenTimestampsリクエストは省略されます（chain_of_custody.jsonに、reasonが「time_budget」の「ots_skipped」が記録されます）。再試行（たとえばゲートウェイからの「504」やネットワークエラーの後）で2つ目の墨消しの作成と課金が発生せず、同じ墨消しが返されるように、Idempotency-Keyを送信してください。最初のリクエストの実行中に再試行すると、`error.details.capture_id`に墨消しIDを含む「409 IDEMPOTENCY_IN_PROGRESS」が返されます（そのIDでGET /captures/{capture_id}をポーリングしてください）。その後の再試行では、元の本文と`Idempotent-Replay: true`を伴う「201」が返されます。失敗した墨消しはキーを解放するため、同じキーでの再試行は再度実行されます。\n\nアカウント単位で60秒のウィンドウによるレート制限が適用されます（アカウントのすべてのAPIキーとそのダッシュボードセッションは1つのウィンドウを共有します）。リミッターの実行後、このルートのレスポンスには`RateLimit-Policy`と`RateLimit`ヘッダー（IETF draft-ietf-httpapi-ratelimit-headersに基づく）に加え、従来の`X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`が含まれます。「429」の場合は`Retry-After`が追加されます。\n\nインポートされた証拠パッケージ（source import、IDのプレフィックスは`imp_`）は墨消しできません：422 IMPORT_NOT_SUPPORTED。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "boxes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "x": {
                          "type": "number",
                          "minimum": 0
                        },
                        "y": {
                          "type": "number",
                          "minimum": 0
                        },
                        "w": {
                          "type": "number",
                          "minimum": 0
                        },
                        "h": {
                          "type": "number",
                          "minimum": 0
                        },
                        "reason": {
                          "type": "string",
                          "maxLength": 200
                        }
                      },
                      "required": [
                        "x",
                        "y",
                        "w",
                        "h"
                      ]
                    },
                    "maxItems": 200,
                    "description": "ソースキャプチャのスクリーンショットのピクセル単位の矩形（xとyは左上隅からの位置、wとhは幅と高さ）。ボックスの4つの値がすべて0から1の間にある場合は、スクリーンショットの幅と高さに対する割合として解釈されます。スクリーンショットの完全に外側にあるボックスは何も塗りつぶさず、「ignored_boxes」に列挙されます。端を越えるボックスは端で切り取られ、「clipped_boxes」に列挙されます。すべてのボックスが外側にあり、テキストまたはメタデータの墨消しでも何も変更されない場合、リクエストは課金前に「400 REDACTION_NO_OPS」で拒否されます。"
                  },
                  "text_redactions": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "match": {
                          "oneOf": [
                            {
                              "type": "string",
                              "description": "リテラルテキスト。",
                              "minLength": 1
                            },
                            {
                              "type": "object",
                              "properties": {
                                "pattern": {
                                  "type": "string",
                                  "description": "正規表現（文字数：1〜500）。(a+)+のようなネストされた量指定子を含むパターンは「400」で拒否されます。",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "flags": {
                                  "type": "string",
                                  "description": "g、i、m、s、uのいずれか（各1回まで）。y（sticky）は「400」で拒否されます。1つの位置でのみ一致し、他の出現箇所が残るためです。",
                                  "pattern": "^[gimsu]*$"
                                }
                              },
                              "required": [
                                "pattern"
                              ]
                            }
                          ]
                        },
                        "case_insensitive": {
                          "type": "boolean",
                          "default": false,
                          "description": "大文字と小文字を区別せずにリテラル文字列に一致させます（正規表現の場合はiフラグを使用してください）。"
                        },
                        "reason": {
                          "type": "string",
                          "maxLength": 200,
                          "description": "プレーンテキスト。墨消し証明書に印字されます。"
                        }
                      },
                      "required": [
                        "match"
                      ]
                    },
                    "maxItems": 200
                  },
                  "metadata_fields": {
                    "type": "array",
                    "description": "metadata.jsonのフィールドパス（`*`セグメントは配列のすべての項目に一致します）、または名前`ip_dns`、`cookie_names`、`authorization`（上記を参照）。",
                    "items": {
                      "oneOf": [
                        {
                          "type": "string",
                          "description": "metadata.jsonのフィールドパス。"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "field": {
                              "type": "string"
                            },
                            "reason": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "field"
                          ]
                        }
                      ]
                    },
                    "maxItems": 100
                  },
                  "reason_summary": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "プレーンテキスト。墨消し証明書に印字されます。"
                  },
                  "custodian": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      }
                    },
                    "description": "墨消しレポートに印字されます。nameとtitleはプレーンテキストのルールに従います（PlainTextを参照）。"
                  },
                  "language": {
                    "type": "string",
                    "description": "人が読むためのPDFの言語。次のいずれかです：en、de、it、fr、es、pt_BR、cs、el、hi、hu、id、ja、ko、nl、pl、ro、ru、sv、tr、vi、zh_CN、zh_TW、ar、he、da、fi、nb、sk、uk。大文字と小文字、ハイフン、地域の違いは許容されます（\"DE\"、\"fr-FR\"、\"PT-BR\"は受け付けられます）。単独の\"pt\"と\"zh\"は拒否されます。サポートされていない値は「400 MALFORMED_REQUEST」を返します。任意：指定しない場合（または空欄の場合）、レポートはソースキャプチャの言語になります。"
                  },
                  "include_eidas": {
                    "type": "boolean",
                    "description": "「CaptureOptions.include_eidas」と同じです。",
                    "default": false
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "redaction.completedを受信するhttps URL。「201」レスポンスの直後に送信され、それより前には送信されません。URLはhttpsである必要があり、プライベート、ループバック、リンクローカル、キャリアグレードNAT、クラウドメタデータの各アドレスを指すことはできません（キャプチャURLと同じルール。違反した場合：422 SSRF_BLOCKED）。空または空白のみの値はWebhookなしを意味します。APIキーが必要です。WebhookはキーのWebhook署名シークレットで署名されるため、ダッシュボードセッションから送信すると「400 WEBHOOK_REQUIRES_API_KEY」で拒否されます。",
                    "format": "uri"
                  },
                  "rule_commitment_salt": {
                    "type": "string",
                    "description": "任意。ルールコミットメント（redaction_manifest.json rule_commitments）用の独自の32バイトのソルト。64桁の16進数またはbase64 / base64urlで指定します。同じバイトの繰り返しのソルトは拒否されます（400）。呼び出し前にソルトを保持するために送信してください。指定しない場合はサーバーが生成し、「201」レスポンスでのみ返します。そのため、タイムアウトでレスポンスが失われると（墨消しは完了したもののゲートウェイから「504」が返された場合）ソルトも失われ、Idempotency-Keyのリプレイにも含まれません。ProofSnapはソルトを保持しません。"
                  }
                },
                "description": "「boxes」「text_redactions」「metadata_fields」のうち少なくとも1つ。"
              },
              "example": {
                "text_redactions": [
                  {
                    "match": "jane.doe@example.com",
                    "reason": "personal data"
                  }
                ],
                "reason_summary": "Personal data of a third party"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "墨消しされたパッケージの準備ができました。同じIdempotency-Keyによる以前の墨消しのべき等リプレイも、`Idempotent-Replay: true`を伴う「201」を返します。元の本文に、現在のステータスと新たに署名された「package_url」が付きます（パッケージに署名できない場合は省略されます。GET /captures/{capture_id}で読み取ってください）。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Idempotent-Replay": {
                "$ref": "#/components/headers/IdempotentReplay"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "redaction_id": {
                      "type": "string",
                      "example": "red_a1B2c3D4e5F6g7H8"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "completed"
                      ]
                    },
                    "redacted_from": {
                      "type": "string"
                    },
                    "redaction_count": {
                      "type": "integer",
                      "description": "適用された墨消し操作の数。"
                    },
                    "original_signature_verified": {
                      "type": "boolean",
                      "description": "墨消しの前に元のマニフェスト署名が検証されたかどうか。"
                    },
                    "leakage_warnings": {
                      "type": "integer",
                      "description": "常に0です。墨消し後のチェックで残存する語句が見つかった墨消しは、発行されずに「422 REDACTION_LEAK_DETECTED」で拒否されます。互換性のために維持されています。"
                    },
                    "package_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "package_url_expires_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "verify_url": {
                      "type": "string",
                      "description": "公開のProofSnap検証ツールへのリンク。",
                      "format": "uri"
                    },
                    "ignored_boxes": {
                      "type": "array",
                      "items": {
                        "type": "integer",
                        "minimum": 0
                      },
                      "description": "スクリーンショットの完全に外側にあり、何も塗りつぶさなかったボックスの、リクエストのboxesにおける0始まりのインデックス。また、redaction_manifest.json（screenshot_boxes）にも記録されます。"
                    },
                    "clipped_boxes": {
                      "type": "array",
                      "items": {
                        "type": "integer",
                        "minimum": 0
                      },
                      "description": "スクリーンショットの端を越え、端で切り取られたボックスの、リクエストのboxesにおける0始まりのインデックス。また、redaction_manifest.json（screenshot_boxes）にも記録されます。"
                    },
                    "screenshot_method": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "jpeg_dct_blocks",
                        "decode_repaint_jpeg",
                        null
                      ],
                      "description": "ボックスの塗りつぶし方法：jpeg_dct_blocks（各ボックスの下にあるJPEGの圧縮ブロックを黒いブロックに置き換え、他のブロックはすべて変更なし）または「decode_repaint_jpeg」（スクリーンショットをデコードして塗りつぶし、再エンコード）。どのボックスも何も塗りつぶさなかった場合はnullです。また、redaction_manifest.json（screenshot_boxes.method）にも記録されます。"
                    },
                    "painted_rects": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "x": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "y": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "w": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "h": {
                            "type": "integer",
                            "minimum": 0
                          }
                        },
                        "required": [
                          "x",
                          "y",
                          "w",
                          "h"
                        ]
                      },
                      "description": "実際に黒く塗りつぶされた領域（スクリーンショットのピクセル単位）。適用されたボックスごとに1つ、無視されたものを除くリクエストのboxesの順に並びます。「jpeg_dct_blocks」では、各領域はボックスをブロック単位に切り上げたもので、ボックスを含みます。「decode_repaint_jpeg」では、ボックスをスクリーンショットの範囲に収め、新しいファイルの8 x 8ブロック単位に切り上げたものです。これらのブロックは再エンコード後に黒く塗りつぶされるため、圧縮によって隣接する色がボックス内に入り込むことはありません。また、redaction_manifest.json（screenshot_boxes.painted_rects）にも記録されます。"
                    },
                    "text_rule_rects": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "テキスト墨消しのみのために黒く塗りつぶされたスクリーンショットの個別の領域で、ボックスを含む領域は除きます（2つのルールが一致する領域は1回だけ数えます）。ソースの「text_layout.json」のテキストブロックのうち、ルールが一致するテキストを持つものについて、一致を含む推定行、または推定が不確かな場合はブロック全体です。redaction_manifest.json（screenshot_boxes.from_text_rules）に記載されます。"
                    },
                    "text_occurrences_not_located": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "ページテキスト内のテキスト墨消しの出現箇所のうち、スクリーンショット上で特定できず、そこで黒く塗りつぶされなかったもの（ソースの「text_layout.json」に記載のないテキスト、たとえば画像内のテキスト、1つの語句のために塗りつぶすには大きすぎるブロック、1回の墨消しの上限を超えた領域、塗りつぶせなかったスクリーンショット）。スクリーンショットの完全に外側のブロック内の出現箇所（塗りつぶす対象がありません）はここには数えられません。redaction_manifest.jsonはそれらを「occurrences_not_on_screenshot」として記載します。ページテキスト内の出現数を超えることはありません。スクリーンショットを確認し、ボックスを追加してください。redaction_manifest.json（leakage_check.screenshot_text_advisory）にルールごとの件数があります。"
                    },
                    "text_variants_remaining": {
                      "type": "object",
                      "description": "参考情報であり、失敗にはなりません。リテラルテキストのルールごとに、このパッケージのdomtextcontent.txtとpage.htmlのテキストに残っている出現箇所のうち、ルールには一致しなかったものの大文字と小文字および発音区別符号を無視すると一致するもの（例：大文字と小文字を区別するルール\"Boskovic\"に対する\"boskovické\"）と、語句がキャプチャURLまたは最終URL（墨消しされることはありません）にあるかどうかを示します。`total`は、ルールごとに2つの件数のうち大きい方を合計します（両方のファイルは同じページテキストを持ちます）。件数のみで、テキストは含みません。正規表現のルールは数えられません。また、redaction_manifest.json（leakage_check.text_variants_advisory）にも記載されます。リクエストにテキスト墨消しがある場合に存在します。",
                      "properties": {
                        "total": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "per_rule": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "rule_index": {
                                "type": "integer",
                                "minimum": 0
                              },
                              "in_domtextcontent": {
                                "type": "integer",
                                "minimum": 0
                              },
                              "in_page_html_text": {
                                "type": "integer",
                                "minimum": 0
                              },
                              "in_capture_url": {
                                "type": "boolean"
                              }
                            }
                          }
                        }
                      }
                    },
                    "rules_in_capture_url": {
                      "type": "array",
                      "items": {
                        "type": "integer",
                        "minimum": 0
                      },
                      "description": "リクエストにテキスト墨消しがある場合に存在します。テキストがキャプチャURLまたは最終URLにも含まれるテキストルールの0始まりのインデックス。これらのURLが変更されることはなく、テキストは他のすべての箇所から除去され、そこでは表示されたままです。どのルールも一致しない場合は空です。また、redaction_manifest.json（leakage_check.capture_url、ルールごとに`remains_in_capture_url: true`）および墨消しレポートにも記載されます。"
                    },
                    "rule_commitment_salt": {
                      "type": "string",
                      "pattern": "^[0-9a-f]{64}$",
                      "description": "リクエストにテキスト墨消しがある場合に存在します。「redaction_manifest.json rule_commitments」の32バイトのソルト（16進数。送信された場合はリクエストの「rule_commitment_salt」）です。コミットメントは、テキストルールごとに、ルールのソルトの後にルールの正規JSON {\"match\": <text, or {\"pattern\", \"flags\"}>, \"case_insensitive\": <bool>}のUTF-8バイトを続けたもののハッシュ（SHA-256）です。ルールのソルトは、このソルトを鍵としてUTF-8テキスト\"rule:<rule_index>\"に対して計算したHMAC-SHA256です（したがって、1つのルールは、他のルールを開示せずに自身のソルトを開示することで示せます）。ルールは保存されず、ソルトはこのレスポンスでのみ返されます。Idempotency-Keyのリプレイ、Webhook、イベントログ、GET /captures/{capture_id}には含まれず、ProofSnapも保持しません。記録とともに保管してください。これにより、墨消しが適用したルールを示すことができます。"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "「MALFORMED_REQUEST」（details.reason。例：プレーンテキストではないreason、正規表現フラグy）、「REDACTION_NO_OPS」（何も指定されていない、または何も一致しなかった）、「INVALID_URL」（「webhook_url」がhttpsではない）のいずれか。WEBHOOK_REQUIRES_API_KEY：ダッシュボードセッションから「webhook_url」が送信されました（WebhookにはAPIキーが必要です）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "「QUOTA_EXCEEDED」または「PAYMENT_REQUIRED」。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "FORBIDDEN：自身のキャプチャではありません。EIDAS_REQUIRES_LIVE_KEY：テストキーで「include_eidas」が指定されたか、テストキャプチャの墨消しです（この場合はdetails.reasonが付きます）。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッションです。PLAN_ARCHIVE_ONLY：このプランはアーカイブの保持のみで、新しい処理を作成しません。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。PLAN_API_READ_ONLY、details.reason \"session_outside_dashboard\"：Website Archiveアカウントのダッシュボードセッションで、リクエストにOriginヘッダーがないか、ProofSnapダッシュボードのアドレスではありません（このプランの新しい処理はダッシュボードでのみ作成されます。ソフトゲートであり、セキュリティ境界ではありません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "404": {
            "description": "エラーコード：CAPTURE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "409": {
            "description": "REDACTION_NOT_READY：ソースキャプチャが完了していません。IDEMPOTENCY_IN_PROGRESS：同じIdempotency-Keyのリクエストがまだ実行中です（「details.capture_id」はGET /captures/{capture_id}でポーリングする墨消しIDです）。COMPANY_READ_ONLY：ソースは会社アーカイブとして保持されている会社に属しています。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "422": {
            "description": "REDACTION_SCREENSHOT_UNREADABLE：スクリーンショットの画像データを読み取れないか、スクリーンショットがボックス墨消しの上限（キャプチャが書き込む形式のJPEG：150 MP、PNGまたは他のJPEG：60 MP）を超えています。テキストとメタデータの墨消しは、ボックスがなくても機能します。REDACTION_LEAK_DETECTED：墨消し対象の語句がキャプチャURL以外に残っていました（details { files, rule_indexes, metadata_fields, in_capture_url }。拒否されたルールのテキストがキャプチャURLまたは最終URLにもある場合、「in_capture_url」はtrueとなり、これらのURL内の出現箇所は数えられません）。REDACTION_SOURCE_UNSUPPORTED：ソースがWebページのキャプチャではありません（details { source }または{ manifest_type }）。SSRF_BLOCKED：「webhook_url」がブロック対象のアドレスを指しています。REDACTION_SOURCE_INTEGRITY_FAILED：ソースパッケージのファイルが署名付きマニフェストに記載されたハッシュ（SHA-256）と一致しないか、記載されたファイルが欠落しています（details { mismatched, missing }、ファイル名のみ）。墨消しも課金も行われていません。IDEMPOTENCY_KEY_REUSED：Idempotency-Keyがすでに異なるリクエスト本文で（または別のキー環境から）使用されています。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：現在の60秒ウィンドウ内のリクエストが多すぎます。`error.details.retry_after_seconds`はRetry-Afterと同じ値です。RateLimitはr=0とウィンドウがリセットされるまでの秒数を示します。Website Archiveのダッシュボードセッションでも「RATE_LIMITED」が返されます。これは、単一およびバッチのキャプチャ（URLごとに1ユニット）、compare、redact、certify-hash（リクエストごとに1ユニット）で共有される、UTCの1日あたりのユニット数の上限（100）によるものです。枠に収まらないリクエストは全体が拒否されます（details.daily_limit、details.remaining、details.action \"wa_session_captures\"。Retry-Afterと「details.retry_after_seconds」は翌UTC日までの秒数を示し、1分あたりのRateLimitとX-RateLimit-*ヘッダーは省略されます）。「details.retry_after_seconds」とRetry-After: 1のみの短い拒否は、カウンターの同時更新を意味するため、再試行してください。呼び出し元に起因しない拒否ではユニットは返還されます。「202」で受理された後に失敗した処理のユニットは返還されません。ソフトゲートであり、セキュリティ境界ではありません。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many requests. See Retry-After header.",
                    "details": {
                      "retry_after_seconds": 42
                    }
                  },
                  "request_id": "..."
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR：予期しないサーバーエラーです。指数バックオフで再試行してください。CAPTURE_TIME_BUDGET_EXCEEDED：同期の墨消しが制限時間を使い切り、パッケージの発行前に停止しました。課金は行われていません。`details.reason`が`source_read`の場合は、ソースパッケージの読み取りに予算の大部分を費やしました。パッケージが大きすぎて現在は墨消しできないため、後でもう一度お試しください。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/EidasOrAuthUnavailable"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/compare": {
      "post": {
        "tags": [
          "比較と墨消し"
        ],
        "operationId": "compareCaptures",
        "summary": "2つのキャプチャを比較",
        "description": "完了した自身のキャプチャ2つを比較し（ページテキスト、ページに表示された画像、メタデータ）、署名付きの比較パッケージを生成します。「202」を返します。GET /captures/{compare_id}をポーリングすると、type、compared、「diff_summary」が含まれます。画像は、各ソースキャプチャが封印した画像インベントリ（image_inventory.json：表示された各画像のアドレスとそのバイト列のSHA-256）から比較され、ピクセル単位では比較されません。結果は「image_changes.json」と「diff_summary.image_changes」にあります。キャプチャが画像インベントリを記録するようになる前にキャプチャされたソースも比較されますが、画像の比較は行われません（diff_summary.image_changes.status not_run）。1キャプチャとして計測されます。同条件の比較（2026-10-14）：異なるデバイスプロファイルまたは異なるキャプチャ設定でレンダリングされた2つのキャプチャは、「allow_profile_mismatch」がtrueでない限り「422 COMPARE_PROFILE_MISMATCH」で拒否されます（details.differing、details.before、details.after：異なるフィールドのみで、挿入されたCSSとJavaScriptについてはSHA-256）。異なるページの2つのキャプチャは、「allow_url_mismatch」がtrueでない限り「422 COMPARE_URL_MISMATCH」で拒否されます（details.beforeとdetails.after：url、final_url（originとpath））。このチェックは、まず2つのキャプチャの行に対して（何かを読み取ったり予約したりする前に）実行され、次に以下のソースチェックの中で両パッケージの封印済みのmetadata.json、forensic_log.jsonに対して実行されます。比較の実行によってのみ不一致が見つかった場合、比較はそのコードで失敗し、月間ユニットは戻されます。テキストは決定論的な行差分（タイムアウトなし）で行ごとに比較されます。「diff_summary」は行を数えます（text_unit line）。比較できるのはWebキャプチャ（APIまたはスケジュールで作成）のみです。ハッシュ証明、比較、墨消しされたパッケージは、パッケージの読み取りと予約の前に「422 COMPARE_SOURCE_UNSUPPORTED」（`details.capture_id`、`details.source`）で拒否されます。比較または予約の前に、各ソースパッケージのmanifest.jsonにハッシュ（SHA-256）付きで記載されたすべてのファイルについて、ハッシュ（SHA-256）を再計算します。ファイルが改変または欠落しているソース、あるいはハッシュ（SHA-256）付きのファイルを1つも記載していないマニフェストは、「422 COMPARE_SOURCE_INTEGRITY_FAILED」で拒否されます（比較なし、行なし、月間ユニットなし）。比較されるのは記載されたファイルのみです。ソースパッケージ内のファイルで、マニフェストにハッシュ（SHA-256）付きで記載されていないもの（たとえば追加された「text_layout.json」、image_inventory.json、page.html、domtextcontent.txt）は、存在しないものとして扱われます。両方のソースパッケージが50 MB以下で、チェックが約10秒以内に完了する場合、チェックはリクエスト時に実行されます。それ以外の場合、リクエストは受理されて比較の実行時にチェックが繰り返され、ソースが不合格であれば比較は失敗し（GET /captures/{compare_id}はstatus failed、「error.code COMPARE_SOURCE_INTEGRITY_FAILED」を示します）、月間ユニットは戻されます。完了した比較では、このチェックがcompare.json `sources[].source_files_reverified`、および「comparison_method.json」`source_verification`に記録されます。/compareはWebhookを送信しないため、本文の「webhook_url」は無視されます。GET /captures/{compare_id}をポーリングしてください。\n\nテストキャプチャ（テストキー、サンドボックス、または請求アカウントが連携されていないアカウントで作成）を含む比較は、どのキーでリクエストしてもテストパッケージになります。透かしが入り、manifest.jsonに`test_mode: true`、compare.json `sources[]`のそのソースに`test_mode: true`が記録され、テスト行（key_env test）となって計測されず、月間ユニットも使用しません。テストソースで「include_eidas」を指定すると「403 EIDAS_REQUIRES_LIVE_KEY」（details.reason）で拒否されます。\n\nアカウント単位で60秒のウィンドウによるレート制限が適用されます（アカウントのすべてのAPIキーとそのダッシュボードセッションは1つのウィンドウを共有します）。リミッターの実行後、このルートのレスポンスには`RateLimit-Policy`と`RateLimit`ヘッダー（IETF draft-ietf-httpapi-ratelimit-headersに基づく）に加え、従来の`X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`が含まれます。「429」の場合は`Retry-After`が追加されます。\n\n再試行（たとえば「504」の後）で2回目の課金対象の実行が発生せず、最初のレスポンスが返されるように、Idempotency-Keyを送信してください（24時間、POST /capturesと同じルール）。キーはソースチェックの前に確保されるため、最初のリクエストの実行中に再試行すると「409 IDEMPOTENCY_IN_PROGRESS」が返されます。ソースチェックまたは利用枠によって拒否されたリクエストはキーを解放するため、同じキーでの再試行は再度チェックされます。\n\nインポートされた証拠パッケージ（source import、IDのプレフィックスは`imp_`）は比較できません：422 IMPORT_NOT_SUPPORTED（details.capture_id）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "capture_id_1": {
                    "type": "string",
                    "description": "先のキャプチャ。"
                  },
                  "capture_id_2": {
                    "type": "string",
                    "description": "後のキャプチャ。「capture_id_1」と異なる必要があります。"
                  },
                  "language": {
                    "type": "string",
                    "description": "比較PDFの言語。完全一致のコードのみ指定できます。その他の値は通知なしで英語にフォールバックします。",
                    "enum": [
                      "en",
                      "de",
                      "it",
                      "fr",
                      "es",
                      "pt_BR",
                      "cs",
                      "el",
                      "hi",
                      "hu",
                      "id",
                      "ja",
                      "ko",
                      "nl",
                      "pl",
                      "ro",
                      "ru",
                      "sv",
                      "tr",
                      "vi",
                      "zh_CN",
                      "zh_TW",
                      "ar",
                      "he",
                      "da",
                      "fi",
                      "nb",
                      "sk",
                      "uk"
                    ]
                  },
                  "include_eidas": {
                    "type": "boolean",
                    "description": "「CaptureOptions.include_eidas」と同じです。",
                    "default": false
                  },
                  "include_rule_902": {
                    "type": "boolean",
                    "description": "比較について、署名なしの証明テンプレート（rule_902_certification.pdf、「CaptureOptions.include_rule_902」を参照）を追加します。異なる方法でレンダリングされたキャプチャでは利用できません。「allow_profile_mismatch」がtrueで、プロファイルまたは設定の不一致がある場合は「422 RULE902_NOT_AVAILABLE_FOR_MISMATCH」となります。",
                    "default": false
                  },
                  "allow_profile_mismatch": {
                    "type": "boolean",
                    "default": false,
                    "description": "異なるデバイスプロファイル（options.viewport mobileまたはdesktop、viewport_width、viewport_height、device_scale_factor。封印される項目：ビューポートサイズ、デバイススケール係数、モバイルエミュレーション、バージョン番号を除くユーザーエージェント）またはページのレンダリング方法を変更する異なるキャプチャ設定（dark_mode、block_ads、block_resources、inject_css、inject_js（SHA-256）、expand_collapsed、dismiss_consent、dismiss_popups、full page）で作成された場合でも、2つのキャプチャを比較します。指定しない場合、そのような組み合わせは「422 COMPARE_PROFILE_MISMATCH」で拒否されます。指定した場合、「diff_summary.text_verdict」と「images_verdict」はundeterminedとなり、changedはコンテンツメタデータのフィールドが異なる場合を除いてnullとなり、「include_rule_902」は拒否されます。"
                  },
                  "allow_url_mismatch": {
                    "type": "boolean",
                    "default": false,
                    "description": "異なるページの2つのキャプチャを比較します。一方のアドレス（リクエストされたurl、そのmetadata.jsonが記録するurl、final_url）が、正規化（ホストを小文字化し、httpとhttpsを同一視し、デフォルトポート、フラグメント、末尾のスラッシュ、変動するクエリパラメータを除去）の後に他方のアドレスのいずれかと一致する場合、2つのキャプチャは同じページとみなされます。指定しない場合、異なるページは「422 COMPARE_URL_MISMATCH」で拒否されます。"
                  }
                },
                "required": [
                  "capture_id_1",
                  "capture_id_2"
                ]
              },
              "example": {
                "capture_id_1": "cap_a1B2c3D4e5F6g7H8",
                "capture_id_2": "cap_h8G7f6E5d4C3b2A1"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "受理されました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "X-Quota-Limit": {
                "$ref": "#/components/headers/QuotaLimit"
              },
              "X-Quota-Remaining": {
                "$ref": "#/components/headers/QuotaRemaining"
              },
              "X-Quota-Used": {
                "$ref": "#/components/headers/QuotaUsed"
              },
              "X-Quota-Cap": {
                "$ref": "#/components/headers/QuotaCap"
              },
              "X-Quota-Org-Limit": {
                "$ref": "#/components/headers/QuotaOrgLimit"
              },
              "X-Quota-Org-Used": {
                "$ref": "#/components/headers/QuotaOrgUsed"
              },
              "X-Sandbox-Limit": {
                "$ref": "#/components/headers/SandboxLimit"
              },
              "X-Sandbox-Remaining": {
                "$ref": "#/components/headers/SandboxRemaining"
              },
              "X-Sandbox-Used": {
                "$ref": "#/components/headers/SandboxUsed"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "compare_id": {
                      "type": "string",
                      "example": "cmp_a1B2c3D4e5F6g7H8"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing"
                      ]
                    },
                    "poll_path": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "warnings": {
                      "$ref": "#/components/schemas/Rule902DisabledWarnings"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：JSONが無効、IDが欠落している、同じIDが2回指定されている、または「allow_profile_mismatch / allow_url_mismatch」がブール値ではありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "「QUOTA_EXCEEDED」または「PAYMENT_REQUIRED」。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "FORBIDDEN：キャプチャが自身のものではありません。EIDAS_REQUIRES_LIVE_KEY：テストキーまたはテストソースキャプチャで「include_eidas」が指定されました（後者の場合はdetails.reasonが付きます）。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッションです。PLAN_ARCHIVE_ONLY：このプランはアーカイブの保持のみで、新しい処理を作成しません。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。PLAN_API_READ_ONLY、details.reason \"session_outside_dashboard\"：Website Archiveアカウントのダッシュボードセッションで、リクエストにOriginヘッダーがないか、ProofSnapダッシュボードのアドレスではありません（このプランの新しい処理はダッシュボードでのみ作成されます。ソフトゲートであり、セキュリティ境界ではありません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "404": {
            "description": "エラーコード：CAPTURE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "409": {
            "description": "COMPARE_NOT_READY：両方のキャプチャが完了している必要があります。COMPANY_READ_ONLY：ソースが会社アーカイブとして保持されている会社に属しています（そこから新しいものは作成されません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "422": {
            "description": "COMPARE_SOURCE_INTEGRITY_FAILED：ソースキャプチャのファイルが署名付きマニフェストに記載されたハッシュ（SHA-256）と一致しないか、欠落しています。比較も課金も行われていません。`details.capture_id`、`details.mismatched`、`details.missing`は最初に不合格となったソースを示します。`details.reason`は、ソースのマニフェスト自体を使用できない場合に存在します（例：\"the source manifest lists no file with a SHA-256\"、\"the source manifest lists no files\"）。`details.sources[]`は、不合格となったすべてのソースを同じフィールドで列挙します。ソースキャプチャを検証してください（POST /captures/{capture_id}/verify）。COMPARE_SOURCE_UNSUPPORTED：ソースがWebキャプチャではありません（ハッシュ証明、比較、または墨消しされたパッケージ）。読み取り、比較、課金は行われていません。`details.capture_id`はそのソースを示し、行に種類が記録されている場合は`details.source`がその種類を示します。代わりに元のWebキャプチャを比較してください。COMPARE_PROFILE_MISMATCH：2つのキャプチャは異なるデバイスプロファイルまたは異なるキャプチャ設定で作成されています。`details.differing`はフィールド名を列挙し（行レベル：viewport、viewport_width、viewport_height、device_scale_factor、dark_mode、block_ads、block_resources、inject_css、inject_js、expand_collapsed、dismiss_consent、dismiss_popups、full_page。封印レベル：viewport_width、viewport_height、device_scale_factor、is_mobile、user_agent、および同じ設定）、`details.before`と`details.after`はその値を示します。それでも比較する場合は「allow_profile_mismatch: true」を送信してください。COMPARE_URL_MISMATCH：2つのキャプチャは異なるページのものです。`details.before`と`details.after`は、url、final_url（originとpath）を示します。それでも比較する場合は「allow_url_mismatch: true」を送信してください。RULE902_NOT_AVAILABLE_FOR_MISMATCH：異なる方法でレンダリングされたキャプチャに対して、「allow_profile_mismatch」とともに「include_rule_902」が指定されました。`details.differing`が付きます。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：現在の60秒ウィンドウ内のリクエストが多すぎます。`error.details.retry_after_seconds`はRetry-Afterと同じ値です。RateLimitはr=0とウィンドウがリセットされるまでの秒数を示します。Website Archiveのダッシュボードセッションでも「RATE_LIMITED」が返されます。これは、単一およびバッチのキャプチャ（URLごとに1ユニット）、compare、redact、certify-hash（リクエストごとに1ユニット）で共有される、UTCの1日あたりのユニット数の上限（100）によるものです。枠に収まらないリクエストは全体が拒否されます（details.daily_limit、details.remaining、details.action \"wa_session_captures\"。Retry-Afterと「details.retry_after_seconds」は翌UTC日までの秒数を示し、1分あたりのRateLimitとX-RateLimit-*ヘッダーは省略されます）。「details.retry_after_seconds」とRetry-After: 1のみの短い拒否は、カウンターの同時更新を意味するため、再試行してください。呼び出し元に起因しない拒否ではユニットは返還されます。「202」で受理された後に失敗した処理のユニットは返還されません。ソフトゲートであり、セキュリティ境界ではありません。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many requests. See Retry-After header.",
                    "details": {
                      "retry_after_seconds": 42
                    }
                  },
                  "request_id": "..."
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/EidasOrAuthUnavailable"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/certify-hash": {
      "post": {
        "tags": [
          "ハッシュ証明"
        ],
        "operationId": "certifyHash",
        "summary": "ファイルハッシュを証明",
        "description": "ハッシュ（SHA-256）を1つ（hash）、または複数（hashes、最大：100）送信します。パッケージには、manifest.json（送信したハッシュを含む）、manifest.sig、publickey.pem、evidence.pdf、verification/スクリプト、および利用可能な場合はmanifest.json.otsが含まれます。\n\n- ハッシュが1つの場合：同期処理で、完成した証明書とともに「200」を返します。\n- 複数のハッシュとcombined: trueの場合：すべてのハッシュを記載した1つの証明書を作成します。同期処理で、「200」を返します。\n- combinedなしの複数のハッシュの場合：ハッシュごとに独立した証明書をバックグラウンドで開始し、「certify_ids」とともに「202」を返します。GET /captures/{certify_id}をポーリングしてください。「webhook_url」を指定すると、それぞれがcertify.completedを送信します。\n\n各証明書は、計測、月間上限、レート制限において1キャプチャとして算入されます（combinedなしのNハッシュはNとして算入され、Nがウィンドウあたりの制限を超える場合は「400 RATE_LIMIT_COST_TOO_HIGH」となります）。`label`は証明書に印字されます。文字数の上限（200）で切り詰められ、プレーンテキストである必要があります（制御文字、不可視文字、テキスト方向文字は不可で、違反すると「400」となります）。バッチでは、1つの項目に関するエラーは`error.details.index`でその項目を示します。\n\nアカウント単位で60秒のウィンドウによるレート制限が適用されます（アカウントのすべてのAPIキーとそのダッシュボードセッションは1つのウィンドウを共有します）。リミッターの実行後、このルートのレスポンスには`RateLimit-Policy`と`RateLimit`ヘッダー（IETF draft-ietf-httpapi-ratelimit-headersに基づく）に加え、従来の`X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`が含まれます。「429」の場合は`Retry-After`が追加されます。\n\n再試行（たとえば「504」の後）で2回目の課金対象の実行が発生せず、最初のレスポンスが返されるように、Idempotency-Keyを送信してください（24時間、POST /capturesと同じルール）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "hash": {
                    "type": "string",
                    "description": "SHA-256（64文字の16進数、大文字と小文字を区別しません）。hashまたはhashesを使用してください。"
                  },
                  "label": {
                    "type": "string",
                    "description": "ファイルの表示名。長い値は文字数の上限（200）まで短縮されます。"
                  },
                  "hashes": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "string",
                          "description": "SHA-256（16進数）。"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "hash": {
                              "type": "string"
                            },
                            "label": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "hash"
                          ]
                        }
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 100
                  },
                  "combined": {
                    "type": "boolean",
                    "description": "すべてのハッシュを1つの証明書で証明します。",
                    "default": false
                  },
                  "algorithm": {
                    "type": "string",
                    "enum": [
                      "sha256"
                    ],
                    "default": "sha256"
                  },
                  "language": {
                    "type": "string",
                    "description": "人が読むためのPDFの言語。次のいずれかです：en、de、it、fr、es、pt_BR、cs、el、hi、hu、id、ja、ko、nl、pl、ro、ru、sv、tr、vi、zh_CN、zh_TW、ar、he、da、fi、nb、sk、uk。大文字と小文字、ハイフン、地域の違いは許容されます（\"DE\"、\"fr-FR\"、\"PT-BR\"は受け付けられます）。単独の\"pt\"と\"zh\"は拒否されます。サポートされていない値は「400 MALFORMED_REQUEST」を返します。"
                  },
                  "case_reference": {
                    "type": "string",
                    "description": "証明書に印字されます。プレーンテキストのルールに従います（PlainTextを参照）。文字数の上限：200。",
                    "maxLength": 200
                  },
                  "include_eidas": {
                    "type": "boolean",
                    "description": "「CaptureOptions.include_eidas」と同じです。",
                    "default": false
                  },
                  "include_rule_902": {
                    "type": "boolean",
                    "description": "署名なしの証明テンプレート（rule_902_certification.pdf、「CaptureOptions.include_rule_902」を参照）を追加します。",
                    "default": false
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "certify.completedを受信するhttps URL。URLはhttpsである必要があり、プライベート、ループバック、リンクローカル、キャリアグレードNAT、クラウドメタデータの各アドレスを指すことはできません（キャプチャURLと同じルール。違反した場合：422 SSRF_BLOCKED）。空または空白のみの値はWebhookなしを意味します。APIキーが必要です。WebhookはキーのWebhook署名シークレットで署名されるため、ダッシュボードセッションから送信すると「400 WEBHOOK_REQUIRES_API_KEY」で拒否されます。",
                    "format": "uri"
                  }
                }
              },
              "example": {
                "hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                "label": "contract.pdf"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "証明書の準備ができました（1つのハッシュ、またはcombined）。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CertifyResult"
                }
              }
            }
          },
          "202": {
            "description": "複数の独立した証明書が開始されました。実行時に月間上限またはサンドボックスの利用枠によって拒否された証明書は失敗します。その行（GET /captures/{certify_id}）のステータスはfailedで、「error.code QUOTA_EXCEEDED」となります。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "batch_id": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "certify_ids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "作成された証明書のID（開始に失敗したものを含みます）。"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing"
                      ]
                    },
                    "certificates": {
                      "type": "array",
                      "description": "送信されたハッシュごとに1つのエントリが順に並びます。status failed：その証明書を開始できませんでした（行が作成されている場合は失敗とマークされます）。他の証明書は引き続き実行されます。",
                      "items": {
                        "type": "object",
                        "properties": {
                          "certify_id": {
                            "type": "string",
                            "nullable": true
                          },
                          "hash_sha256": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "processing",
                              "failed"
                            ]
                          }
                        }
                      }
                    },
                    "failed_count": {
                      "type": "integer",
                      "description": "certificatesのエントリのうち開始に失敗した数。すべて失敗した場合は、代わりにレスポンスが「500 CONFIGURATION_ERROR」となります。"
                    },
                    "warnings": {
                      "$ref": "#/components/schemas/Rule902DisabledWarnings"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "「MALFORMED_REQUEST」（details.reasonはフィールドを示します。例：\"label must be a string\"。details.indexはバッチの項目を示します）、「INVALID_HASH」（バッチではdetails.index）、「INVALID_URL」（「webhook_url」がhttpsではない、または認証情報を含む）のいずれか。WEBHOOK_REQUIRES_API_KEY：ダッシュボードセッションから「webhook_url」が送信されました（WebhookにはAPIキーが必要です）。RATE_LIMIT_COST_TOO_HIGH：1つのレート制限ウィンドウで許容されるより多くのハッシュ（combinedなし）が指定されました。details { max_per_window, window_seconds, requested }。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "「PAYMENT_REQUIRED」、または同期パスでは「QUOTA_EXCEEDED」。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "403": {
            "description": "「EIDAS_REQUIRES_LIVE_KEY」（請求アカウントが連携されていないため本番キーまたはセッションがテストとして動作する場合はdetails.reason \"no_billing_account\"）。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。PLAN_ARCHIVE_ONLY：このプランはアーカイブの保持のみで、新しい処理を作成しません。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。PLAN_API_READ_ONLY、details.reason \"session_outside_dashboard\"：Website Archiveアカウントのダッシュボードセッションで、リクエストにOriginヘッダーがないか、ProofSnapダッシュボードのアドレスではありません（このプランの新しい処理はダッシュボードでのみ作成されます。ソフトゲートであり、セキュリティ境界ではありません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "422": {
            "description": "SSRF_BLOCKED：「webhook_url」がプライベート、ループバック、リンクローカル、またはその他のブロック対象のアドレスを指しています。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：現在の60秒ウィンドウ内のリクエストが多すぎます。`error.details.retry_after_seconds`はRetry-Afterと同じ値です。RateLimitはr=0とウィンドウがリセットされるまでの秒数を示します。Website Archiveのダッシュボードセッションでも「RATE_LIMITED」が返されます。これは、単一およびバッチのキャプチャ（URLごとに1ユニット）、compare、redact、certify-hash（リクエストごとに1ユニット）で共有される、UTCの1日あたりのユニット数の上限（100）によるものです。枠に収まらないリクエストは全体が拒否されます（details.daily_limit、details.remaining、details.action \"wa_session_captures\"。Retry-Afterと「details.retry_after_seconds」は翌UTC日までの秒数を示し、1分あたりのRateLimitとX-RateLimit-*ヘッダーは省略されます）。「details.retry_after_seconds」とRetry-After: 1のみの短い拒否は、カウンターの同時更新を意味するため、再試行してください。呼び出し元に起因しない拒否ではユニットは返還されます。「202」で受理された後に失敗した処理のユニットは返還されません。ソフトゲートであり、セキュリティ境界ではありません。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many requests. See Retry-After header.",
                    "details": {
                      "retry_after_seconds": 42
                    }
                  },
                  "request_id": "..."
                }
              }
            }
          },
          "500": {
            "description": "CONFIGURATION_ERROR：証明に失敗しました（details.reason）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          },
          "504": {
            "description": "UPSTREAM_TIMEOUT：同期の証明（1つのハッシュ、またはcombined）が約25秒以内に完了しませんでした。まだ完了する可能性があります。「details.certify_id」と「details.poll_path」が、GET /captures/{capture_id}でポーリングする行を示します。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/webhook-events/{capture_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/CaptureId"
        }
      ],
      "get": {
        "tags": [
          "Webhook"
        ],
        "operationId": "listWebhookEvents",
        "summary": "Webhook配信ログ",
        "description": "1つのキャプチャ、証明書、または墨消しに対するすべての配信試行を、古い順に返します。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "配信ログ。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "capture_id": {
                      "type": "string"
                    },
                    "webhook_url": {
                      "type": "string",
                      "description": "行のWebhook URL（キャプチャの「options.webhook_url」、または証明書や墨消しとともに指定されたURL。ない場合はnull）。キャプチャが作成された会社のオーナーがシートのログを読み取る場合は、スキーム、ホスト、ポート、パスのみです（クエリとフラグメントはトークンを含む可能性があるため除去されます）。この読み取りはキャプチャのアクセス履歴に記録されます（action webhook_events）。",
                      "nullable": true
                    },
                    "attempts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "attempt_number": {
                            "type": "integer"
                          },
                          "attempted_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "status_code": {
                            "type": "integer",
                            "nullable": true
                          },
                          "latency_ms": {
                            "type": "integer",
                            "nullable": true
                          },
                          "success": {
                            "type": "boolean"
                          },
                          "error": {
                            "type": "string",
                            "nullable": true,
                            "description": "配信された場合はnull。それ以外の場合は一般的な分類で、ネットワークエラーの生データは含みません：connection_failed、timeout、blocked_address（配信時にホストがプライベートまたはその他のブロック対象のアドレスに解決された）、redirect_not_followed（エンドポイントが3xxを返した。リダイレクトには従いません）、http_<status>（2xx以外のレスポンス）、またはイベントが送信されなかった理由を示す文（APIキーなし、キーの失効または未検出、Webhook署名シークレットなし、シークレットの検索に失敗）。"
                          },
                          "delivery_id": {
                            "type": "string",
                            "description": "この配信の「webhook-id」ヘッダーから`msg_`プレフィックスを除いたもの。"
                          }
                        }
                      }
                    },
                    "attempt_count": {
                      "type": "integer"
                    },
                    "last_success": {
                      "type": "string",
                      "description": "最後に成功した試行の「attempted_at」。",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "FORBIDDEN：自身のキャプチャではありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "エラーコード：CAPTURE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/scheduled-captures": {
      "post": {
        "tags": [
          "スケジュールキャプチャ"
        ],
        "operationId": "createSchedule",
        "summary": "スケジュールを作成",
        "description": "intervalとcron：各実行でキャプチャを行い、「webhook_url」を指定すると、capture.completedまたはcapture.failedを送信します。\n\non_change：各実行では、まずページを取得し（プレーンHTTP、または「js_render」によるブラウザレンダリング）、正規化されたテキストをハッシュ化します。このチェックはキャプチャではなく、課金されません。初回の実行でベースラインキャプチャを作成します。ハッシュが変わると、新しいキャプチャを実行して前回のキャプチャと比較し、「monitor.change_detected」を「webhook_url」に送信します。エラーを返すページやテキストがほとんどないページは、変更なしとして扱われます。\n\n実行が5回連続で失敗すると、スケジュールは自動的に一時停止します。月間上限に達した場合またはサブスクリプションが支払い期限超過の場合、実行はスキップされ、スケジュールはアクティブのままです。\n\nプラン別の制限：\n\n| プラン | アクティブなスケジュール | 最小間隔 | on_change |\n| --- | --- | --- | --- |\n| sandbox | 0 | 利用不可 | いいえ |\n| developer | 3 | 300 s | はい |\n| startup | 25 | 300 s | はい |\n| growth | 200 | 300 s | はい |\n| custom | 無制限 | 300 s | はい |\n| legal_solo | 3 | 300 s | はい |\n| legal_seats | 3 | 300 s | はい |\n| website_archive | 30 | 86400 s | はい |\n| archive_only | 0 | 利用不可 | いいえ |\n\nIdempotency-Key：同じキーと本文による24時間以内の再試行では、2つ目のスケジュールは作成されず、最初の「201」が返されます（ヘッダーIdempotent-Replay: true）。同じキーを別の本文で使用すると「422 IDEMPOTENCY_KEY_REUSED」となります。接続されたAIアプリ（MCP OAuth接続）が作成するスケジュールは、実行が最大で1時間に1回（min_interval_seconds 3600）となり、「webhook_url」と「include_eidas」は使用できません（違反した場合：400）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "作成されました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST、INVALID_URL、INVALID_CRON、INTERVAL_TOO_SHORT（details.min_interval_seconds）、またはキャプチャオプションのエラー。WEBHOOK_REQUIRES_API_KEY：ダッシュボードセッションから「webhook_url」が送信されました（WebhookにはAPIキーが必要です）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "「SCHEDULE_LIMIT_REACHED」（details.max_active、details.active）または「ON_CHANGE_REQUIRES_PLAN」。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッションです。PLAN_ARCHIVE_ONLY：このプランはアーカイブの保持のみで、新しい処理を作成しません。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。PLAN_API_READ_ONLY、details.reason \"session_outside_dashboard\"：Website Archiveアカウントのダッシュボードセッションで、リクエストにOriginヘッダーがないか、ProofSnapダッシュボードのアドレスではありません（このプランの新しい処理はダッシュボードでのみ作成されます。ソフトゲートであり、セキュリティ境界ではありません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "SSRF_BLOCKED：urlまたは「webhook_url」がプライベート、ループバック、リンクローカル、またはその他のブロック対象のアドレスを指しています。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      },
      "get": {
        "tags": [
          "スケジュールキャプチャ"
        ],
        "operationId": "listSchedules",
        "summary": "スケジュールの一覧を取得",
        "description": "自身のスケジュール（最大：100）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "スケジュール。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "schedules": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Schedule"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/scheduled-captures/{schedule_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ScheduleId"
        }
      ],
      "get": {
        "tags": [
          "スケジュールキャプチャ"
        ],
        "operationId": "getSchedule",
        "summary": "スケジュールを取得",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "スケジュール。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "エラーコード：SCHEDULE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "patch": {
        "tags": [
          "スケジュールキャプチャ"
        ],
        "operationId": "updateSchedule",
        "summary": "スケジュールの一時停止、再開、編集",
        "description": "一時停止または再開するにはstatusを送信し、編集するにはScheduleRequestの任意のフィールドを送信します（両方も可）。送信したトップレベルのフィールドは、明示的なnullを含めて保存値を置き換えます（webhook_url、timezone、「js_render」はこの方法で消去されます）。送信しないフィールドは保存値を維持します。結果は全体として再度検証されます。`options`はフィールド単位の編集の例外です。キーごとにマージされず、マップ全体として置き換えられるため、必要なオプションをすべて送信してください（先にGETで読み取ってください）。マップから省略したオプションは削除されます。再開すると、アクティブなスケジュールの上限を確認し、失敗回数を消去して、現時点から次回の実行を計算します。\n\nダッシュボードセッションからは「webhook_url」を設定できません（400 WEBHOOK_REQUIRES_API_KEY）。nullまたは空文字列を送信すると消去されます。ダッシュボードセッションから作成されたスケジュールには署名に使用するAPIキーがないため、編集すると以前に保存された「webhook_url」も削除され、APIキーで追加することもできません（400 WEBHOOK_REQUIRES_API_KEY）。スケジューラーは、スケジュールのWebhookを、そのスケジュールの作成に使用されたキーのWebhook署名シークレットで署名します。Webhookを受信するには、APIキーでスケジュールを作成してください。\n\n「on_change」スケジュールのurl、mode、「js_render」を変更する（またはスケジュールを「on_change」に切り替える、もしくはそこから切り替える）と、ベースライン（保存されたプローブハッシュと最後のキャプチャ）が消去されます。そのため、次回の実行では新しい対象を古い対象と比較するのではなく、新しいベースラインキャプチャを作成します。リクエスト本文はJSONオブジェクトである必要があります（違反した場合：400 MALFORMED_REQUEST）。接続されたAIアプリ（MCP OAuth接続）が変更できるのはstatusのみです（違反した場合：403）。「pause_reason key_revoked」で一時停止されたスケジュール（キーまたは接続されたアプリが失効）は、ダッシュボードでのみ再開できます。再開後はアカウントのもとで（キーなしで）実行され、「webhook_url」は失われます。キーで再開しようとすると「403」となります。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "paused"
                    ]
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "interval",
                      "cron",
                      "on_change"
                    ]
                  },
                  "interval_seconds": {
                    "type": "integer"
                  },
                  "cron_expr": {
                    "type": "string"
                  },
                  "timezone": {
                    "type": "string",
                    "nullable": true,
                    "description": "cronのIANAタイムゾーン。nullまたは空文字列を指定するとUTCに戻ります。"
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "削除するにはnullまたは空文字列を送信してください。URLはhttpsである必要があり、プライベート、ループバック、リンクローカル、キャリアグレードNAT、クラウドメタデータの各アドレスを指すことはできません（キャプチャURLと同じルール。違反した場合：422 SSRF_BLOCKED）。両方の側でAPIキーが必要です。Webhookはスケジュールの作成に使用されたキーのWebhook署名シークレットで署名されるため、ダッシュボードセッションから送信した場合、またはダッシュボードで作成されたスケジュールに対してAPIキーで送信した場合は「400 WEBHOOK_REQUIRES_API_KEY」で拒否されます。",
                    "nullable": true
                  },
                  "js_render": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "nullはfalseを意味します。"
                  },
                  "options": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/CaptureOptions"
                      }
                    ],
                    "description": "保存されたオプションを全体として置き換えます（キーごとにマージされません）。完全なマップを送信してください。省略したオプションは削除されます。nullを指定するとオプションはデフォルトに戻ります。「options.webhook_url」が保存されることはありません（「webhook_url」を参照）。"
                  },
                  "max_capture_age_seconds": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 86400,
                    "maximum": 34560000,
                    "description": "「on_change」のみ：変更がなくても少なくともN秒ごとに完全なキャプチャを実行します（日数：1〜400、「interval_seconds」より長い値）。nullを指定すると削除されます。モードをintervalまたはcronに切り替えると破棄されます。"
                  },
                  "alert_on": {
                    "type": "string",
                    "enum": [
                      "any",
                      "text"
                    ],
                    "nullable": true,
                    "description": "「on_change」のみ：どの検知された変更でアラートを出すか（作成リクエストを参照）。モードをintervalまたはcronに切り替えると破棄されます。"
                  },
                  "email_on_change": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "「on_change」のみ：変更のアラート時にアカウントへメールを送信します（作成リクエストを参照）。単独で送信でき、その場合スケジュールの他の項目は変更されません。falseまたはnullはどのモードでも受け付けられます。trueには「on_change」が必要です。モードをintervalまたはcronに切り替えるとオフになります。接続されたAIアプリでは変更できません。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新されたスケジュール。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "400": {
            "description": "「MALFORMED_REQUEST」（更新する内容がない場合を含む）、INVALID_URL、INVALID_CRON、「INTERVAL_TOO_SHORT」のいずれかです。WEBHOOK_REQUIRES_API_KEY：ダッシュボードセッションから「webhook_url」が送信された、またはダッシュボードで作成されたスケジュールに対してAPIキーで送信されました（Webhookに署名できるWebhook署名シークレットを持つキーがありません）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "「SCHEDULE_LIMIT_REACHED」または「ON_CHANGE_REQUIRES_PLAN」。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッションです（一時停止中のスケジュールの再開時。一時停止と編集は引き続き可能です）。PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです。すべてのPATCHが対象です（一時停止と編集を含みます）。PLAN_API_READ_ONLY、details.reason \"session_outside_dashboard\"：Website Archiveアカウントのダッシュボードセッションで、リクエストにOriginヘッダーがないか、ProofSnapダッシュボードのアドレスではありません（このプランの新しい処理はダッシュボードでのみ作成されます。ソフトゲートであり、セキュリティ境界ではありません）。PLAN_ARCHIVE_ONLY：Archive onlyプランでスケジュールを再開しようとしました。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "エラーコード：SCHEDULE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "SSRF_BLOCKED：urlまたは「webhook_url」がプライベート、ループバック、リンクローカル、またはその他のブロック対象のアドレスを指しています。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "delete": {
        "tags": [
          "スケジュールキャプチャ"
        ],
        "operationId": "deleteSchedule",
        "summary": "スケジュールを削除",
        "description": "今後の実行を停止します。すでに取得したキャプチャは保持されます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "削除されました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "schedule_id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "PLAN_API_READ_ONLY：Website ArchiveアカウントのAPIキーです（キーは読み取り専用のため、ダッシュボードを使用してください）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "エラーコード：SCHEDULE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/scheduled-captures/{schedule_id}/runs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ScheduleId"
        }
      ],
      "get": {
        "tags": [
          "スケジュールキャプチャ"
        ],
        "operationId": "listScheduleRuns",
        "summary": "スケジュールの実行の一覧を取得",
        "description": "このスケジュールで取得された最新の50キャプチャ（変更が見つからなかった「on_change」チェックは含まれません）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "実行。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "schedule_id": {
                      "type": "string"
                    },
                    "runs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "capture_id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "captured_at": {
                            "type": "string",
                            "nullable": true
                          },
                          "file_count": {
                            "type": "integer",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "エラーコード：SCHEDULE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/matters": {
      "get": {
        "tags": [
          "案件"
        ],
        "operationId": "listMatters",
        "summary": "案件の一覧を取得",
        "description": "自身がメンバーである案件（最大：200）。離脱した会社の案件は含まれません。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "案件。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matters": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Matter"
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED：このプランはLegalプランではありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "post": {
        "tags": [
          "案件"
        ],
        "operationId": "createMatter",
        "summary": "案件を作成",
        "description": "作成者が案件のオーナーになります。証拠管理ログはmatter.createdエントリから始まります。テキストフィールドはトリムされ、文字数の上限（200）まで短縮されます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "プレーンテキスト：空白は1つにまとめられてトリムされます。文字数の上限：200。制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシャ語の綴りに必要な結合子U+200CとU+200Dは使用できます）（違反した場合：400 MALFORMED_REQUEST）。必須です。公開の案件検証ページに表示されます。"
                  },
                  "client": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "プレーンテキスト：空白は1つにまとめられてトリムされます。文字数の上限：200。制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシャ語の綴りに必要な結合子U+200CとU+200Dは使用できます）（違反した場合：400 MALFORMED_REQUEST）。空欄またはnullは未設定を意味します（nullとして保存されます）。文字列以外の値は拒否されます。",
                    "nullable": true
                  },
                  "case_number": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "プレーンテキスト：空白は1つにまとめられてトリムされます。文字数の上限：200。制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシャ語の綴りに必要な結合子U+200CとU+200Dは使用できます）（違反した場合：400 MALFORMED_REQUEST）。空欄またはnullは未設定を意味します（nullとして保存されます）。文字列以外の値は拒否されます。公開の案件検証ページに表示されます。",
                    "nullable": true
                  },
                  "opposing_party": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "プレーンテキスト：空白は1つにまとめられてトリムされます。文字数の上限：200。制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシャ語の綴りに必要な結合子U+200CとU+200Dは使用できます）（違反した場合：400 MALFORMED_REQUEST）。空欄またはnullは未設定を意味します（nullとして保存されます）。文字列以外の値は拒否されます。",
                    "nullable": true
                  },
                  "jurisdiction": {
                    "type": "string",
                    "description": "自由記述。プレーンテキスト：空白は1つにまとめられてトリムされます。文字数の上限：200。制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシャ語の綴りに必要な結合子U+200CとU+200Dは使用できます）（違反した場合：400 MALFORMED_REQUEST）。空欄またはnullは未設定を意味します（nullとして保存されます）。文字列以外の値は拒否されます。公開の案件検証ページに表示されます。",
                    "maxLength": 200,
                    "nullable": true
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "Smith v. Jones",
                "case_number": "2026-CV-0142"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "作成されました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Matter"
                }
              }
            }
          },
          "400": {
            "description": "MISSING_FIELD：nameがないか空です。MALFORMED_REQUEST：JSONが無効です。MALFORMED_REQUEST：テキストフィールドが文字列ではない、文字数が「200」を超える、または制御文字やテキスト方向文字を含んでいます。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：本番の呼び出し元で、サブスクリプション（または会社）の支払いが期限超過または未払いです。"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED：プランがLegalプランではありません。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/matters/{matter_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/MatterId"
        }
      ],
      "get": {
        "tags": [
          "案件"
        ],
        "operationId": "getMatter",
        "summary": "案件を取得",
        "description": "案件と、そのキャプチャ（上限：500）、証拠管理ログ、アクセスイベント（上限：100）を返します。`members`は`member_uids`の各エントリのメールアドレスを示し、`actor_emails`はこの案件の証拠管理ログと「audit_stream」に記載されたuid（実行者、および`member.added` / `member.removed`の対象者。したがって削除済みのメンバーも含みます）をメールアドレスに対応付けます。メールアドレスを読み取れない場合、値はnullになるか、そのuidがマップに含まれません。これらのフィールドを受け取るのは案件を開ける呼び出し元のみで、`/matter-verify`にメールアドレスが含まれることはありません。公開の共有リンクを取り消せる呼び出し元（案件オーナー、終了した会社またはアーカイブされた会社のオーナー）には、`share`も返されます。これは有効なリンクの`{ share_url, created_at, expires_at }`（`expires_at`は常にnullです。リンクは取り消されるまで有効です）で、リンクがない場合はnullです。その他のメンバーがこのフィールドを受け取ることはありません。「audit_stream」のエントリに「source_ip」と「user_agent」が含まれるのは案件オーナーの場合のみで、メンバーにはこの2つのフィールドを除いたエントリが返されます。\n\n終了した会社の案件には`read_only: true`が付きます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "案件。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Matter"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "members": {
                          "type": "array",
                          "description": "`member_uids`のエントリごとに1件、同じ順序で返します。",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uid": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string",
                                "format": "email",
                                "nullable": true,
                                "description": "アカウントを読み取れない場合はnullです。"
                              }
                            }
                          }
                        },
                        "actor_emails": {
                          "type": "object",
                          "description": "この案件の「custody_log」と「audit_stream」に記載された人物の`{ uid: email }`です（システム実行者を除く）。メールアドレスを読み取れないuidは含まれません。",
                          "additionalProperties": {
                            "type": "string",
                            "format": "email"
                          }
                        },
                        "captures": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/MatterCapture"
                          }
                        },
                        "custody_log": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/CustodyEntry"
                          }
                        },
                        "audit_stream": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/AuditEntry"
                          }
                        },
                        "share": {
                          "type": "object",
                          "nullable": true,
                          "description": "リンクを取り消せる呼び出し元にのみ返されます。有効なリンクがない場合はnullです。",
                          "properties": {
                            "share_url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "created_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "expires_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true,
                              "description": "常にnullです。共有リンクに有効期限はありません。"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED：このプランはLegalプランではありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "patch": {
        "tags": [
          "案件"
        ],
        "operationId": "updateMatter",
        "summary": "案件を更新",
        "description": "オーナーのみ実行できます。テキストフィールドは前後の空白を除去し、上限を超える部分を切り詰めます（文字数の上限：200）。nameは必須です。送信する場合は空でない文字列でなければならず、空または空白のみの名前、null、文字列以外の値は拒否され（400）、何も変更されません。メンバー：「add_member_email」は、ProofSnapアカウントを持ち、案件の会社に所属している人を追加します。アカウントがない場合、アドレスが未確認の場合、アカウントが会社外の場合は、いずれも同一の「404 NOT_FOUND」を返します。「remove_member_uid」はメンバーを削除します（オーナーは削除できません）。両方を送信した場合は「add_member_email」のみが適用されます。1つの案件のメンバーは最大50人です（上限に達している案件では、アドレスを照会する前に拒否します）。メンバーの変更は証拠管理ログに記録されます。name、client、case_number、opposing_party、jurisdiction、statusの変更は、matter.updatedとして証拠管理ログに記録されます。そのtargetは、fields（変更されたフィールド名）と、statusが変更された場合は新しいstatusを含むJSON文字列です。自由入力の値は、ハッシュ化される公開の証拠管理ログには記録されません。変更前後の値はアクセスログ（audit_stream、エントリmatter.updated）に記録されます。アーカイブ済みの案件では、同じリクエストで再開（status \"open\"）しない限り、名前の変更と「add_member_email」は「409 MATTER_ARCHIVED」で拒否されます。「remove_member_uid」と再開は引き続き実行できます。招待は、招待するオーナーごとに1日50件の上限に計上されます（ダッシュボードからの会社招待と案件の「add_member_email」の合計で、拒否された分も含みます。いずれもアドレスを照会するためです）。上限に達すると、リクエストは「429 RATE_LIMITED」を返します。サーバー側の障害は計上されません。\n\nリーガルホールド：`{ \"legal_hold\": true|false }`のみを送信すると、案件のリーガルホールドを設定または解除し（案件オーナーのみ）、同じリクエストでその案件のキャプチャにも適用します。効果はキャプチャ単位のリーガルホールドと同じです（S3 Object Lockのリーガルホールド、証拠管理エントリcapture.legal_hold_placed / capture.legal_hold_released、キャプチャのイベントチェーン）。レスポンスは案件に加えて、`changed`（フラグが変更された）、`captures_held`または`captures_released`、`skipped`（[{ capture_id, code }]、例：ゴミ箱内のキャプチャ）、`truncated`（キャプチャが1000件を超える場合。同じ値を再度送信すると続行します）を含みます。リーガルホールドが有効な間に後から案件に割り当てられたキャプチャは、割り当て時にリーガルホールドの対象になります。レート制限の消費は、リクエストごとに1ユニットと、変更したキャプチャ10件ごとに1ユニットです。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "空白以外の文字を1文字以上含める必要があります。現在の名前を維持する場合は省略します。同じプレーンテキストの規則が適用されます：空白は1つにまとめられ（文字数の上限：200）、制御文字、テキスト方向文字、不可視文字は使用できません（U+200CとU+200Dは使用できます）。",
                    "maxLength": 200
                  },
                  "client": {
                    "type": "string",
                    "nullable": true,
                    "description": "プレーンテキスト：空白は1つにまとめられて前後が除去され（文字数の上限：200）、制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシア語の表記に必要な結合文字U+200CとU+200Dは使用できます）。違反すると「400 MALFORMED_REQUEST」になります。nullまたは空白のみの文字列を指定するとフィールドがクリアされます（nullとして保存）。文字列以外の値は拒否されます（400）。",
                    "maxLength": 200
                  },
                  "case_number": {
                    "type": "string",
                    "nullable": true,
                    "description": "プレーンテキスト：空白は1つにまとめられて前後が除去され（文字数の上限：200）、制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシア語の表記に必要な結合文字U+200CとU+200Dは使用できます）。違反すると「400 MALFORMED_REQUEST」になります。nullまたは空白のみの文字列を指定するとフィールドがクリアされます（nullとして保存）。文字列以外の値は拒否されます（400）。",
                    "maxLength": 200
                  },
                  "opposing_party": {
                    "type": "string",
                    "nullable": true,
                    "description": "プレーンテキスト：空白は1つにまとめられて前後が除去され（文字数の上限：200）、制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシア語の表記に必要な結合文字U+200CとU+200Dは使用できます）。違反すると「400 MALFORMED_REQUEST」になります。nullまたは空白のみの文字列を指定するとフィールドがクリアされます（nullとして保存）。文字列以外の値は拒否されます（400）。",
                    "maxLength": 200
                  },
                  "jurisdiction": {
                    "type": "string",
                    "nullable": true,
                    "description": "プレーンテキスト：空白は1つにまとめられて前後が除去され（文字数の上限：200）、制御文字、テキスト方向（bidi）文字、不可視文字は使用できません（ヒンディー語とペルシア語の表記に必要な結合文字U+200CとU+200Dは使用できます）。違反すると「400 MALFORMED_REQUEST」になります。nullまたは空白のみの文字列を指定するとフィールドがクリアされます（nullとして保存）。文字列以外の値は拒否されます（400）。",
                    "maxLength": 200
                  },
                  "status": {
                    "type": "string",
                    "description": "封印するにはPOST /matters/{matter_id}/sealを使用します。",
                    "enum": [
                      "open",
                      "archived"
                    ]
                  },
                  "add_member_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "remove_member_uid": {
                    "type": "string"
                  },
                  "legal_hold": {
                    "type": "boolean",
                    "description": "案件のリーガルホールドです。単独で送信します（他のフィールドと組み合わせた場合：400）。trueは、案件の現在のすべてのキャプチャと、リーガルホールドが有効な間に割り当てられるすべてのキャプチャをリーガルホールドの対象にします（legal_hold_source \"matter:<id>\"。すでにリーガルホールドの対象であるキャプチャは、元のリーガルホールドを維持します）。falseは、案件が設定したリーガルホールドのみを解除します。手動または一括で設定したリーガルホールドは残ります。案件オーナーのみ実行できます。サブスクリプションの支払い期限超過によってブロックされることはありません。設定には有料プランが必要で（403 LEGAL_HOLD_NOT_AVAILABLE、details.reason plan）、テストモードのキャプチャはスキップされます（`skipped`のコード：LEGAL_HOLD_NOT_AVAILABLE）。false単独は、Legalプランの終了後も受け付けます。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新後の案件。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Matter"
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：nameが空、空白のみ、または文字列ではない。テキストフィールドが文字列ではない、文字数の上限（200）を超える、または制御文字やテキスト方向文字を含む。statusが無効。更新する内容がない。すでにメンバーである。またはオーナーを削除しようとした。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：本番の呼び出し元で、サブスクリプション（または会社）の支払いが期限超過または未払いです。"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED、FORBIDDEN（オーナーではない）、LEGAL_HOLD_NOT_AVAILABLE（legal_hold trueを有料プランなしで指定）、または、EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND、または、NOT_FOUND（そのメールアドレスに該当するアカウントがない：アカウントなし、未確認、会社外のいずれも同一のレスポンス。または「remove_member_uid」がメンバーではない）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "MATTER_SEALED、または、MATTER_ARCHIVED（アーカイブ済みの案件での名前の変更または新規メンバーの追加）。COMPANY_READ_ONLY：案件が、終了した会社または会社アーカイブとして保持されている会社に属しています（呼び出し元はLegalプラン。開く、エクスポート、共有の取り消しは引き続き実行できます）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：招待するオーナーごとの1日50件のメンバー招待の上限に達しました（ダッシュボードからの会社招待と案件の「add_member_email」の合計。details.daily_limit、details.action \"member_invite\"）。Retry-AfterはUTCの1日が終わる時刻を示します。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/matters/{matter_id}/captures": {
      "parameters": [
        {
          "$ref": "#/components/parameters/MatterId"
        }
      ],
      "post": {
        "tags": [
          "案件"
        ],
        "operationId": "assignMatterCaptures",
        "summary": "キャプチャを追加または削除",
        "description": "どのメンバーも呼び出せますが、移動されるのは呼び出し元が作成したキャプチャのみです。その他のキャプチャは、すでに別の案件にあるキャプチャ、すでにこの案件にある（unassignの場合はこの案件にない）キャプチャとともにskippedで返されます。キャプチャIDではないエントリは無視されます（処理件数の上限：100）。各変更は証拠管理ログに記録されます。アーカイブ済みの案件に新しいキャプチャは追加できません（409 MATTER_ARCHIVED）。unassignは引き続き実行できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "capture_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 100
                  },
                  "unassign": {
                    "type": "boolean",
                    "description": "trueを指定すると、キャプチャを案件から削除します。",
                    "default": false
                  }
                },
                "required": [
                  "capture_ids"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "結果。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matter_id": {
                      "type": "string"
                    },
                    "assigned": {
                      "type": "integer",
                      "description": "変更されたキャプチャの数です。"
                    },
                    "skipped": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "skipped_reasons": {
                      "type": "array",
                      "description": "スキップされた各キャプチャの理由です。codeは次のいずれかです：not_found（このアカウントに該当するキャプチャがない）、already_in_matter、in_other_matter（開ける案件であれば「matter_id」がその案件を示します）、not_in_matter（unassign指定時）、org_mismatch、matter_archived、matter_sealed、matter_sealing、no_access。",
                      "items": {
                        "type": "object",
                        "properties": {
                          "capture_id": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string",
                            "enum": [
                              "not_found",
                              "already_in_matter",
                              "in_other_matter",
                              "not_in_matter",
                              "org_mismatch",
                              "matter_archived",
                              "matter_sealed",
                              "matter_sealing",
                              "no_access"
                            ]
                          },
                          "matter_id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "capture_id",
                          "code"
                        ]
                      }
                    },
                    "unassign": {
                      "type": "boolean"
                    },
                    "legal_holds_placed": {
                      "type": "integer",
                      "description": "案件のリーガルホールドが有効な場合に返されます。割り当てられたキャプチャのうち、リーガルホールドを設定した数です。"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：有効なキャプチャIDがありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：本番の呼び出し元で、サブスクリプション（または会社）の支払いが期限超過または未払いです。"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED、または、EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "MATTER_SEALED、または、MATTER_ARCHIVED（アーカイブ済みの案件への追加）。COMPANY_READ_ONLY：案件が、終了した会社または会社アーカイブとして保持されている会社に属しています（呼び出し元はLegalプラン。開く、エクスポート、共有の取り消しは引き続き実行できます）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/matters/{matter_id}/seal": {
      "parameters": [
        {
          "$ref": "#/components/parameters/MatterId"
        }
      ],
      "post": {
        "tags": [
          "案件"
        ],
        "operationId": "sealMatter",
        "summary": "案件を封印",
        "description": "オーナーのみ実行できます。現在の証拠管理ログの先頭ハッシュをOpenTimestampsでアンカーし、デプロイ環境にeIDASが設定されていて呼び出し元が本番（本番のAPIキー、または請求先が登録されたダッシュボードセッション）の場合は、eIDASタイムスタンプでもアンカーします（封印のeIDASタイムスタンプは請求されません。失敗した場合はeIDASタイムスタンプなしで封印を続行します）。テストの呼び出し元（テストAPIキーまたはサンドボックスセッション）はOpenTimestampsのみで封印され、封印には「eidas_status」として「not_obtained」、「eidas_reason」として「test_key」が記録されます。このリクエストにeIDASのオプションはないため、これはエラーではありません。その後、案件は読み取り専用になります。編集もキャプチャの変更もできず、そのキャプチャは削除できません。ゴミ箱内のキャプチャを含む案件は封印されません（409 MATTER_HAS_TRASHED_CAPTURES）。先にキャプチャを復元するか、案件から削除してください。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "封印しました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matter_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "sealed"
                      ]
                    },
                    "seal": {
                      "$ref": "#/components/schemas/MatterSeal"
                    },
                    "custody_head_hash": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：案件に証拠管理ログの先頭がありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：本番の呼び出し元で、サブスクリプション（または会社）の支払いが期限超過または未払いです。"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED：プランがLegalプランではありません。FORBIDDEN：オーナーではありません。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "MATTER_SEALED（すでに封印済み）、MATTER_CHANGED（封印中に証拠管理ログが変更されました。再試行してください）、または、MATTER_HAS_TRASHED_CAPTURES（案件のキャプチャがゴミ箱にあります。先に復元するか、案件から削除してください）。COMPANY_READ_ONLY：案件が、終了した会社または会社アーカイブとして保持されている会社に属しています（呼び出し元はLegalプラン。開く、エクスポート、共有の取り消しは引き続き実行できます）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "TIMESTAMP_SERVICE_UNAVAILABLE（アンカーに失敗し、何も変更されていません。再試行してください）、または、CONFIGURATION_ERROR。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "EIDAS_SEAL_RETRY：封印のeIDASタイムスタンプが時間内に届きませんでした（または発行中です）。封印は行われていません。Retry-Afterの秒数が経過してから再試行してください。再試行では、この証拠管理ログの先頭に対してすでに発行されたタイムスタンプを受け取り、2回目のスタンプは発行されません。SERVICE_UNAVAILABLE：ゲートウェイが認証情報を確認できませんでした。バックオフを入れて再試行してください。",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "EIDAS_SEAL_RETRY",
                    "message": "The eIDAS timestamp of the seal did not arrive in time. Nothing was sealed. Retry after the Retry-After interval; the retry reuses the timestamp already issued for this custody head.",
                    "details": {
                      "reason": "The eIDAS timestamp did not arrive in time. Nothing was sealed. Retry the seal.",
                      "retry_after_seconds": 15
                    }
                  },
                  "request_id": "..."
                }
              }
            }
          }
        }
      }
    },
    "/matters/{matter_id}/export": {
      "parameters": [
        {
          "$ref": "#/components/parameters/MatterId"
        }
      ],
      "post": {
        "tags": [
          "案件"
        ],
        "operationId": "exportMatter",
        "summary": "案件をエクスポート",
        "description": "オーナーのみ実行できます。custody_report.pdf、custody_log.json、matter.json、README.txt、access_log.json（アクセスイベントがある場合）と、各キャプチャの証拠パッケージを含む1つのZIPを作成します。Bates番号付与を有効にすると（デフォルト）、各evidence.pdfのBates番号入りコピーをexhibits/以下に追加し（証拠書類の番号は最も古い証拠から振られます）、formats.loadfileを指定するとConcordance/Opticonのロードファイルも追加します。formats.pdfaを指定すると、コンバーターが利用可能な場合に提出用コピーをPDF/Aにも変換します（同期エクスポートでは制限時間内に限ります）。PDF/Aであるのは「pdfa_count」に数えられたコピーのみで、それ以外はPDF/Aであると主張しないPDFです。README.txtがPDF/Aに言及するのは、「pdfa_count」が0より大きい場合のみです。\n\nキャプチャが20件以下の案件は同期でエクスポートされます（200）。それより大きい案件はバックグラウンドでエクスポートされ、レスポンスは「202」で「job_id」を含みます。GET /matters/{matter_id}/export?job_id=をポーリングしてください。サイズ上限（同期：120 MB。バックグラウンド：800 MB、キャプチャ数：300）に収まらないキャプチャは、レポートには記載されますが、ZIPには含まれません。\n\nステータスがopenの案件と封印済みの案件のどちらでも実行できます。アーカイブ済みの案件は拒否されます（409 MATTER_ARCHIVED。先に再開してください）。ただし、再開できない呼び出し元は例外です：保存期間内にある終了した会社のオーナー、およびArchive onlyのアカウントです。各エクスポートは、アクセスログにexport.generatedとして記録されます。各エクスポートはユーザーごとに1日50件の上限に計上されます。失敗したバックグラウンドエクスポートの分は返却されます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "bates": {
                    "type": "object",
                    "properties": {
                      "enabled": {
                        "type": "boolean",
                        "default": true
                      },
                      "prefix": {
                        "type": "string",
                        "description": "英字と数字のみで、大文字に変換され、最大12文字です。デフォルト：事件番号または案件名から生成します。"
                      },
                      "start": {
                        "type": "integer",
                        "minimum": 1,
                        "default": 1
                      },
                      "exhibit_start": {
                        "type": "integer",
                        "minimum": 1,
                        "default": 1
                      },
                      "pad": {
                        "type": "integer",
                        "minimum": 4,
                        "maximum": 8,
                        "default": 6
                      }
                    }
                  },
                  "formats": {
                    "type": "object",
                    "properties": {
                      "loadfile": {
                        "type": "boolean",
                        "description": "eディスカバリのロードファイルを含めます（Bates番号付与が必要です）。",
                        "default": true
                      },
                      "pdfa": {
                        "type": "boolean",
                        "description": "Bates番号入りの提出用コピーをPDF/Aに変換します（Bates番号付与が必要です）。ベストエフォートです：変換されなかったコピーは、PDF/Aであると主張しないPDFのままです。変換された数はレスポンスの「pdfa_count」で示されます。",
                        "default": true
                      }
                    }
                  },
                  "export_locale": {
                    "type": "string",
                    "description": "custody_report.pdf、証拠書類索引、README.txtの言語：en、de、it、fr、es、pt_BR、cs、el、hi、hu、id、ja、ko、nl、pl、ro、ru、sv、tr、vi、zh_CN、zh_TW、ar、he、da、fi、nb、sk、uk（アンダースコアの代わりにハイフンも使用できます）。その他の値は英語にフォールバックします。"
                  },
                  "declaration": {
                    "type": "object",
                    "description": "互換性のために受け付けます。テキストフィールド（name、title、party、case_caption、executed_location）にはプレーンテキストの規則（PlainTextを参照）が適用され、使用できない文字を含む値は拒否されます（400 MALFORMED_REQUEST）。長すぎる値は切り詰められます（文字数の上限はname、title、executed_location：120、party：160、case_caption：200）。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "エクスポートの準備ができました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matter_id": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "description": "署名付きダウンロードリンクです。24時間有効です。",
                      "format": "uri"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "capture_count": {
                      "type": "integer"
                    },
                    "captures_included": {
                      "type": "integer"
                    },
                    "captures_skipped": {
                      "type": "integer",
                      "description": "サイズ上限に達したため、レポートには記載されたもののZIPに含まれなかったキャプチャです。"
                    },
                    "custody_events": {
                      "type": "integer"
                    },
                    "exhibits_count": {
                      "type": "integer",
                      "description": "Bates番号入りの証拠書類コピーです。"
                    },
                    "bates_prefix": {
                      "type": "string",
                      "nullable": true
                    },
                    "searchable": {
                      "type": "boolean",
                      "description": "常にfalseです。提出用コピーにテキストレイヤーは追加されません。レスポンスの形式を安定させるために残されています。"
                    },
                    "pdfa_count": {
                      "type": "integer",
                      "description": "exhibits/以下の提出用コピーのうちPDF/Aである数です。0は、PDF/Aのコピーがなく、PDF/Aであると主張するコピーもないことを意味します。"
                    },
                    "loadfile": {
                      "type": "boolean"
                    },
                    "size_bytes": {
                      "type": "integer"
                    },
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "バックグラウンドでエクスポートを開始しました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matter_id": {
                      "type": "string"
                    },
                    "async": {
                      "type": "boolean"
                    },
                    "job_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing"
                      ]
                    },
                    "poll_path": {
                      "type": "string",
                      "description": "/v1ステージを含みます。"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：エクスポートのオプションが無効です（details.reason）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：本番の呼び出し元で、サブスクリプション（または会社）の支払いが期限超過または未払いです。"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED：プランがLegalプランではありません。FORBIDDEN：オーナーではありません。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "MATTER_ARCHIVED：先に案件を再開してください（PATCH status \"open\"）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "CONFIGURATION_ERROR：エクスポートを作成または開始できませんでした。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          },
          "504": {
            "description": "UPSTREAM_TIMEOUT：同期エクスポートが約25秒以内に完了しませんでした（details.reason）。再試行してください。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "案件"
        ],
        "operationId": "getMatterExport",
        "summary": "バックグラウンドエクスポートをポーリング",
        "description": "オーナーのみ実行できます。開始から30分経過しても処理中のジョブは、エラー\"export timed out\"で失敗として報告されます。ジョブの終了は1回のみです：失敗と報告されたジョブが後からreadyになることはなく、readyのジョブが失敗と報告されることもありません。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ジョブのステータスです。readyの場合は、urlと各カウントが設定されます。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "ready",
                        "failed"
                      ]
                    },
                    "url": {
                      "type": "string",
                      "nullable": true
                    },
                    "captures_included": {
                      "type": "integer",
                      "nullable": true
                    },
                    "captures_skipped": {
                      "type": "integer",
                      "nullable": true
                    },
                    "custody_events": {
                      "type": "integer",
                      "nullable": true
                    },
                    "size_bytes": {
                      "type": "integer",
                      "nullable": true
                    },
                    "error": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：「job_id」がありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED：プランがLegalプランではありません。FORBIDDEN：オーナーではありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND、または、NOT_FOUND（不明なジョブの場合）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/matters/{matter_id}/share": {
      "parameters": [
        {
          "$ref": "#/components/parameters/MatterId"
        }
      ],
      "post": {
        "tags": [
          "案件"
        ],
        "operationId": "shareMatter",
        "summary": "公開検証リンクを作成",
        "description": "オーナーのみ実行できます。案件の名前、事件番号、管轄、ステータス、証拠管理ログ、封印を誰でも閲覧できるリンクを返します（GET /matter-verifyを参照）。キャプチャの内容は共有されません。再度呼び出すと同じリンクを返します。リンクは取り消すまで有効です。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "共有リンク。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matter_id": {
                      "type": "string"
                    },
                    "share_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "token": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：本番の呼び出し元で、サブスクリプション（または会社）の支払いが期限超過または未払いです。"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED：プランがLegalプランではありません。FORBIDDEN：オーナーではありません。EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "MATTER_ARCHIVED：アーカイブ済みの案件は共有されません。COMPANY_READ_ONLY：案件が、終了した会社または会社アーカイブとして保持されている会社に属しています（呼び出し元はLegalプラン。開く、エクスポート、共有の取り消しは引き続き実行できます）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "delete": {
        "tags": [
          "案件"
        ],
        "operationId": "revokeMatterShare",
        "summary": "公開リンクを取り消し",
        "description": "オーナーのみ実行できます。リンクは機能しなくなります。その後POSTすると新しいリンクが作成されます。終了した会社（または会社アーカイブとして保持されている会社）のオーナーと、Archive onlyプランの案件のオーナーは、Legalプランがなくてもリンクを取り消せます（リンクの作成はLegalプランの機能のままです）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "取り消しました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matter_id": {
                      "type": "string"
                    },
                    "revoked": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：本番の呼び出し元で、サブスクリプション（または会社）の支払いが期限超過または未払いです。"
          },
          "403": {
            "description": "MATTERS_NOT_ENABLED、FORBIDDEN（オーナーではない）、または、EMAIL_NOT_VERIFIED：メールアドレスが未確認のダッシュボードセッション、またはそのようなアカウントのAPIキーです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "公開"
        ],
        "operationId": "health",
        "summary": "ヘルスチェック",
        "description": "APIが応答している間は常に正常応答を返します（200）。deep=1（またはtrue）を指定すると、レスポンスにdependenciesが追加されます：各ダウンストリームサービスが設定されているかどうかと、eIDASについてはタイムスタンプサービスへのライブプローブの結果です。プローブされるのはeIDASのみで、その他は設定状況のみを報告します。eIDASが設定されていてプローブが失敗すると、statusはdegradedになります。時間内に応答しないプローブはdependenciesで報告され（probe_timeout、またはeidas.error timeout）、/healthの失敗として報告されることはありません。deep=1にはクライアントIPごとのレート制限があります（1分あたり10回）。超過すると、リクエストはRetry-Afterとともに「429 RATE_LIMITED」を返します。",
        "security": [],
        "parameters": [
          {
            "name": "deep",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ヘルス。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "degraded"
                      ]
                    },
                    "stage": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "uptime_ms": {
                      "type": "integer",
                      "description": "応答中のインスタンスが起動してからのミリ秒数です。"
                    },
                    "version": {
                      "type": "string"
                    },
                    "dependencies": {
                      "type": "object",
                      "properties": {
                        "eidas": {
                          "type": "object",
                          "properties": {
                            "configured": {
                              "type": "boolean"
                            },
                            "healthy": {
                              "type": "boolean",
                              "description": "設定されていない場合はnullです。",
                              "nullable": true
                            },
                            "error": {
                              "type": "string",
                              "description": "eIDASプローブが正常と報告しなかった場合の固定コードです：timeout（15秒以内に応答なし）、unavailable（タイムスタンプサービスが異常と応答）、error（プローブを実行できなかった）。詳細はサーバー側で記録され、返されることはありません。",
                              "enum": [
                                "timeout",
                                "unavailable",
                                "error"
                              ]
                            }
                          }
                        },
                        "ots": {
                          "type": "object",
                          "properties": {
                            "configured": {
                              "type": "boolean"
                            }
                          }
                        },
                        "c2pa_sign": {
                          "type": "object",
                          "properties": {
                            "configured": {
                              "type": "boolean"
                            }
                          }
                        },
                        "ntp": {
                          "type": "object",
                          "properties": {
                            "configured": {
                              "type": "boolean"
                            }
                          }
                        },
                        "whois": {
                          "type": "object",
                          "properties": {
                            "configured": {
                              "type": "boolean"
                            }
                          }
                        },
                        "error": {
                          "type": "string",
                          "description": "依存関係のチェック自体が失敗した場合のみ返されます：20秒以内に応答がなかった場合は「probe_timeout」、それ以外は「probe_failed」です。レスポンスは引き続き正常です（200）。"
                        }
                      },
                      "description": "deep=1の場合のみ返されます。"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/ledger/{hash}": {
      "get": {
        "tags": [
          "公開"
        ],
        "operationId": "ledgerLookup",
        "summary": "マニフェストハッシュを照会",
        "description": "manifest.jsonのハッシュ（SHA-256）がこの値であるパッケージをProofSnapが発行した記録があるかどうかを確認します。キャプチャ、証明書、比較、墨消しは、発行時に、提供されるマニフェストのハッシュ（適格タイムスタンプの工程の後）とともに記録されます。発行台帳の開始前に発行されたパッケージは含まれません。issued: falseは、記録がないことのみを意味します。",
        "security": [],
        "parameters": [
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "description": "manifest.jsonのハッシュ（SHA-256）です。16進数64文字で、大文字小文字は問わず、先頭にsha256:を付けることもできます。",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "照会結果。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "manifest_sha256": {
                      "type": "string"
                    },
                    "issued": {
                      "type": "boolean"
                    },
                    "issued_at": {
                      "type": "string",
                      "nullable": true,
                      "format": "date-time",
                      "description": "issuedがfalseの場合は含まれません。"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "capture",
                        "certify",
                        "compare",
                        "redaction"
                      ],
                      "nullable": true,
                      "description": "issuedがfalseの場合は含まれません。"
                    },
                    "eidas": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "発行されたパッケージにeIDAS適格タイムスタンプ（manifest.json.tsr）が含まれるかどうかを示します。issuedがfalseの場合は含まれません。2026-10-01より前に書き込まれた記録ではnullです。"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND：ハッシュが16進数64文字ではありません。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/matter-verify": {
      "get": {
        "tags": [
          "公開"
        ],
        "operationId": "matterVerify",
        "summary": "共有された案件の公開ビュー",
        "description": "案件の共有リンクの背後にある読み取り専用データです：案件の詳細、証拠管理ログ（ハッシュチェーンを再計算できます）、OpenTimestampsの証明とeIDASトークンを含む封印です。キャプチャの内容、ダウンロードリンク、アクセスログは含まれません。attested_by.organizationは、案件が属する会社についてオーナーが設定した名前（会社の案件の場合）で、それ以外はnullです。個人の案件には組織名は記載されません。「custody_log[].actor_org」は、そのエントリが書き込まれた時点で実行者が属していた会社で（エントリとともに、ハッシュ対象のペイロードの外に記録されます）、会社の案件にのみ含まれます。これが記録されるようになる前に書き込まれたエントリはnullを示します。クライアントIPごとのレート制限があります（デフォルトは60秒あたり30リクエスト）。",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{16,64}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "案件ビュー。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matter": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "case_number": {
                          "type": "string",
                          "nullable": true
                        },
                        "jurisdiction": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string"
                        },
                        "sealed": {
                          "type": "boolean"
                        },
                        "attested_by": {
                          "type": "object",
                          "properties": {
                            "organization": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        },
                        "capture_count": {
                          "type": "integer"
                        },
                        "custody_count": {
                          "type": "integer"
                        },
                        "custody_head_hash": {
                          "type": "string",
                          "nullable": true
                        },
                        "seal": {
                          "type": "object",
                          "properties": {
                            "root_hash": {
                              "type": "string"
                            },
                            "ots_present": {
                              "type": "boolean"
                            },
                            "eidas_present": {
                              "type": "boolean"
                            },
                            "ots_hex": {
                              "type": "string",
                              "nullable": true
                            },
                            "ots_pending": {
                              "type": "boolean"
                            },
                            "tsr_base64": {
                              "type": "string",
                              "nullable": true
                            },
                            "eidas_serial": {
                              "type": "string",
                              "nullable": true
                            },
                            "eidas_issued_at": {
                              "type": "string",
                              "nullable": true
                            },
                            "eidas_ltv": {
                              "type": "boolean"
                            },
                            "sealed_at": {
                              "type": "string"
                            },
                            "eidas_status": {
                              "type": "string",
                              "enum": [
                                "confirmed",
                                "not_obtained",
                                "not_configured"
                              ],
                              "nullable": true,
                              "description": "eIDASトークンなしで2026-10-01より前に行われた封印ではnullです。"
                            },
                            "eidas_reason": {
                              "type": "string",
                              "enum": [
                                "token_refused",
                                "unavailable",
                                "test_key",
                                "account_limit"
                              ],
                              "description": "「eidas_status」が「not_obtained」の場合のみ返されます。test_key：封印がテストの呼び出し元によって行われたため、eIDASタイムスタンプは要求されませんでした。account_limit：アカウントに支払い済みの請求書がまだなく、eIDASの上限（UTCの1日あたり20回、UTCの1か月あたり50回）に達したため、eIDASタイムスタンプは要求されませんでした。"
                            },
                            "eidas_verification_status": {
                              "type": "string",
                              "nullable": true,
                              "description": "封印時にトークンがProofSnapのチェックに合格した場合はverifiedです。"
                            },
                            "eidas_revocation_status": {
                              "type": "string",
                              "nullable": true,
                              "enum": [
                                "good",
                                "revoked_after_gen_time",
                                "unknown",
                                "not_checked",
                                null
                              ],
                              "description": "封印時に確定したTSA証明書のステータスです（ライブでは取得しません）。"
                            },
                            "eidas_validation": {
                              "type": "object",
                              "nullable": true,
                              "additionalProperties": true,
                              "description": "封印時に記録された「eidas_validation.json」の内容（TSAチェーン、固定されたルート、OCSPレスポンス、CRL、検証記録）です。これにより、「tsr_base64」のトークンをオフラインで検証できます。古い封印ではnullです。"
                            }
                          },
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string"
                        }
                      }
                    },
                    "custody_log": {
                      "type": "array",
                      "items": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/CustodyEntry"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "actor_org": {
                                "type": "string",
                                "nullable": true
                              }
                            }
                          }
                        ]
                      }
                    },
                    "issuer": {
                      "type": "string",
                      "enum": [
                        "ProofSnap"
                      ]
                    },
                    "verified_at": {
                      "type": "string",
                      "nullable": true,
                      "description": "常にnullです。"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND：トークンが無効、不明、または失効済みです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/captures/export-jobs": {
      "post": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "startCaptureExportJob",
        "summary": "すべてのキャプチャを1つのダウンロードとしてエクスポート（非同期ジョブ）",
        "description": "すべてのキャプチャを1つのダウンロードにまとめるジョブを開始します。ダウンロードは最大約2 GBのパートに分割されます。各パートは通常のZIPで、次の内容を含みます：README.txt（英語）とREADME.<language>.txt（同じ内容の翻訳。languageがenでない場合。どちらもバイトオーダーマーク付きUTF-8、改行はCRLFで、各ファイルの1行目は他方を指します）、captures.csv（バイトオーダーマーク付きUTF-8、CRLF。エクスポートのすべてのキャプチャを次の列で記載します：member（会社エクスポートでは作成者のメールアドレス、自分のエクスポートでは空）、capture_id、created_at（リクエストを受信した時刻）、captured_at（キャプチャの時刻。失敗したキャプチャでは空）、url、status（completed、failed、unavailableのいずれか）、export_part、file、ots_file（そのパートが証明を含む場合はcaptures/<capture_id>.upgraded.ots、それ以外は空）、test_mode（テストキーで作成されたキャプチャではtrue：透かし入りで、証拠ではありません）、note（パッケージが含まれない理由。unavailableのすべての行にも記載）。すべてのパートに同じ一覧が含まれ、パート間で一致しない場合は最も番号の大きいパートの一覧が最終版です）、captures/<capture_id>.zip（封印された元の証拠パッケージをバイト単位でそのまま収録）、およびアップグレードされたOpenTimestampsの証明が保存されている場合のcaptures/<capture_id>.upgraded.otsです。内側の各パッケージは、それぞれのverification/verify.shまたはverify.ps1で個別に検証します。2 GBを超えるパッケージは含まれません（noteとともにunavailableとして記載されます。GET /captures/{capture_id}で個別にダウンロードしてください）。失敗したキャプチャはcaptures.csvにのみ記載されます。ゴミ箱内のキャプチャと消去されたキャプチャはエクスポートされません。すべてのパートのエントリの日付はエクスポート時刻です（UTC。拡張タイムスタンプフィールドにも記録されます）。statusがreadyになるまでGET /captures/export-jobs/{job_id}をポーリングしてください。**再利用：**直近のエクスポートがreadyで、スコープ（およびorg）と言語が同じで、ダウンロード期間が1日以上残っており、権限に変更がなく、計画時以降にキャプチャの追加、完了、ゴミ箱への移動、復元、消去がない場合、リクエストはそのジョブを返します（200、reused: true）。再作成は行われず、1日の利用枠も消費しません。同じスコープの新しいreadyのエクスポートは以前のものを置き換えます（以前のジョブはexpiredになり、「expired_reason」はsupersededになります）。開始できるのは、本番のAPIキーまたはダッシュボードセッションで、サンドボックス、Archive only、読み取り専用（Website Archive）のキーを含むすべてのプランが対象です。テストキーの場合は「403 FORBIDDEN」を返し（エクスポートには本番のキャプチャが含まれるため）、GET /captures/export-jobs/{job_id}はテストキーに対してすべてのジョブで「404 EXPORT_JOB_NOT_FOUND」を返します。自分のエクスポート（scope own）には、個人のキャプチャと、現在の会社または自分が所有する会社のために作成したキャプチャが含まれます。その会社が継続中の会社アーカイブである間はキーでも取得できます（アーカイブの他のシートのキャプチャを取得できるのはダッシュボードセッションのみです）。scope company（会社のオーナーのみ。終了した会社でもダウンロード期間内であれば可能です。継続中の会社アーカイブはダッシュボードセッションのみ）は、会社のために作成された全シートのキャプチャと自分のキャプチャをエクスポートし、member列に作成者のメールアドレスを記載します。実行中のジョブはアカウントごとに1件です（「409 EXPORT_JOB_RUNNING」がそのジョブを示します）。開始できるジョブはアカウントおよびUTCの1日ごとに5件で（失敗したジョブの分は返却され、再利用されたジョブは消費しません）、プランの1分あたりのレート制限も適用されます。1つのジョブに含まれるのは最新のキャプチャのみです（上限：20,000、truncated）。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scope": {
                    "type": "string",
                    "enum": [
                      "own",
                      "company"
                    ],
                    "default": "own"
                  },
                  "org": {
                    "type": "string",
                    "description": "scope companyの場合：所有する会社（現在または直近）の両方を所有しているときに、そのいずれかを指定します。"
                  },
                  "language": {
                    "type": "string",
                    "default": "en",
                    "description": "READMEの翻訳の言語です：すべてのパートで、英語のREADME.txtの隣にREADME.<language>.txt（全文の翻訳）を置きます。enの場合はREADME.txtのみです。次のいずれかを指定します：en、de、it、fr、es、pt_BR、cs、el、hi、hu、id、ja、ko、nl、pl、ro、ru、sv、tr、vi、zh_CN、zh_TW、ar、he、da、fi、nb、sk、uk。大文字小文字、ハイフン、地域表記は許容されます（\"PT-BR\"はpt_BRとして扱います）。\"pt\"や\"zh\"のみの指定、およびその他の値は「400 MALFORMED_REQUEST」になります。readyのエクスポートが再利用されるのは言語が同じ場合のみです。ダッシュボードはUIの言語を送信します。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "readyのエクスポートがまだ最新のため、再利用されます：新しいジョブは作成されず、1日の利用枠も消費しません。リンクは「GET poll_path」で取得してください。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "job_id",
                    "status",
                    "scope",
                    "poll_path",
                    "reused"
                  ],
                  "properties": {
                    "job_id": {
                      "type": "string",
                      "example": "cexp_3Fh8sKq0aZr2LmN1"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ready"
                      ]
                    },
                    "scope": {
                      "type": "string",
                      "enum": [
                        "own",
                        "company"
                      ]
                    },
                    "poll_path": {
                      "type": "string",
                      "example": "/v1/captures/export-jobs/cexp_3Fh8sKq0aZr2LmN1"
                    },
                    "reused": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "ジョブを開始しました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "job_id",
                    "status",
                    "scope",
                    "poll_path"
                  ],
                  "properties": {
                    "job_id": {
                      "type": "string",
                      "example": "cexp_3Fh8sKq0aZr2LmN1"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing"
                      ]
                    },
                    "scope": {
                      "type": "string",
                      "enum": [
                        "own",
                        "company"
                      ]
                    },
                    "poll_path": {
                      "type": "string",
                      "example": "/v1/captures/export-jobs/cexp_3Fh8sKq0aZr2LmN1"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：本文がJSONオブジェクトではない、またはscope / orgが無効です。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "FORBIDDEN：テストキーでリクエストした、またはダウンロード期間内にある会社のオーナーではない人がscope companyを指定しました。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "EXPORT_JOB_RUNNING：アカウントのジョブがまだ処理中です。「details.job_id」と「details.poll_path」がそのジョブを示します。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/captures/export-jobs/{job_id}": {
      "get": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "getCaptureExportJob",
        "summary": "キャプチャエクスポートジョブのステータスとダウンロードリンク",
        "description": "ジョブのステータスと進捗を返します。readyになると、パートごとに署名付きリンクを1つ返します。リンクの有効期限は「url_expires_at」までです：最大24時間で、「download_expires_at」を超えることはなく、署名した認証情報の有効期限を超えることもありません（1時間未満の場合があります）。新しいリンクが必要な場合は、「url_expires_at」の経過後に再度ポーリングしてください。「download_expires_at」は、ジョブの最初のパートが開始される直前のUTC午前0時から7日後です（ジョブがreadyになってから6日から7日後）。その後、パートは削除されます。同じスコープの新しいエクスポートに置き換えられた場合、ジョブに含まれるキャプチャが消去された場合、会社のデータが削除された場合、または権限がジョブを対象としなくなった場合（readyのジョブを読み取るたびに確認します）は、ジョブのダウンロードが期限前に失効します（status expired、パートは削除、「expired_reason」）。進捗が30分間報告されないジョブは、この呼び出しによりfailedとして終了し、書き込まれた内容は削除されます。1時間以内で最初にリンクを含むレスポンスは、監査ログに記録されます（capture.export_job.links_issued）。ジョブを閲覧できるのは開始したアカウントのみです。会社アーカイブを含む会社エクスポートは、ダッシュボードセッションからのみ閲覧できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^cexp_[A-Za-z0-9]{16}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ジョブ。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "job_id",
                    "status",
                    "scope",
                    "parts"
                  ],
                  "properties": {
                    "job_id": {
                      "type": "string",
                      "example": "cexp_3Fh8sKq0aZr2LmN1",
                      "pattern": "^cexp_[A-Za-z0-9]{16}$"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "processing",
                        "ready",
                        "failed",
                        "expired"
                      ],
                      "description": "processing：計画とパートの書き込み中です。ready：ダウンロードリンクが利用できます。failed：新しいジョブを開始してください（その日の利用枠は返却済みです）。expired：ダウンロード期間が終了したか、ダウンロードが取り消されました（「expired_reason」。パートは削除されます）。"
                    },
                    "scope": {
                      "type": "string",
                      "enum": [
                        "own",
                        "company"
                      ]
                    },
                    "language": {
                      "type": "string",
                      "enum": [
                        "en",
                        "de",
                        "it",
                        "fr",
                        "es",
                        "pt_BR",
                        "cs",
                        "el",
                        "hi",
                        "hu",
                        "id",
                        "ja",
                        "ko",
                        "nl",
                        "pl",
                        "ro",
                        "ru",
                        "sv",
                        "tr",
                        "vi",
                        "zh_CN",
                        "zh_TW",
                        "ar",
                        "he",
                        "da",
                        "fi",
                        "nb",
                        "sk",
                        "uk"
                      ],
                      "description": "ジョブのREADMEの言語です（README.txtに加えてREADME.<language>.txt。enの場合はREADME.txtのみ）。"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "ended_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "progress": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "captures_total": {
                          "type": "integer",
                          "nullable": true
                        },
                        "captures_done": {
                          "type": "integer"
                        },
                        "parts_total": {
                          "type": "integer",
                          "nullable": true
                        },
                        "parts_done": {
                          "type": "integer"
                        }
                      }
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "アカウントのエクスポート可能なキャプチャ数が上限（20,000）を超える場合はtrueです：ジョブには最新のキャプチャ（20,000）が含まれます。"
                    },
                    "counts": {
                      "type": "object",
                      "nullable": true,
                      "description": "ジョブがreadyのときに設定されます。",
                      "properties": {
                        "captures": {
                          "type": "integer",
                          "description": "captures.csvの行数です。"
                        },
                        "packaged": {
                          "type": "integer",
                          "description": "パート内のパッケージ数です。"
                        },
                        "failed": {
                          "type": "integer",
                          "description": "失敗したキャプチャの数です（パッケージなし、captures.csvにのみ記載）。"
                        },
                        "unavailable": {
                          "type": "integer",
                          "description": "含まれなかったパッケージの数です：エクスポート中に読み取れなかったか、2 GBを超えています（どちらであるかはcaptures.csvに記載されます）。"
                        }
                      }
                    },
                    "parts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "part",
                          "bytes",
                          "count",
                          "download_url"
                        ],
                        "properties": {
                          "part": {
                            "type": "integer",
                            "minimum": 1,
                            "example": 1,
                            "description": "パート番号です。1からパート数までの値です。"
                          },
                          "bytes": {
                            "type": "integer",
                            "example": 1834201112,
                            "description": "パートのZIPのサイズ（バイト）です。"
                          },
                          "count": {
                            "type": "integer",
                            "example": 412,
                            "description": "このパートに含まれるキャプチャパッケージの数です。"
                          },
                          "filename": {
                            "type": "string",
                            "example": "proofsnap-captures-2026-10-07T1430Z-part-1-of-3.zip",
                            "description": "ダウンロードの保存時のファイル名です（Content-Disposition）：proofsnap-captures-<ジョブ開始のUTC日時>で、複数のパートがある場合は-part-N-of-Mが付きます。"
                          },
                          "download_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true,
                            "description": "パートのZIPの署名付きGETです。「url_expires_at」まで有効です。ジョブが期限切れの場合はnullです。"
                          }
                        }
                      }
                    },
                    "download_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "ダウンロード期間の終了時刻です：最初のパートが開始される直前のUTC午前0時から7日後です（その後、ストレージのライフサイクルによりパートが削除されます）。"
                    },
                    "url_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "このレスポンスの「download_url」の値が機能しなくなる時刻です：最大24時間で、「download_expires_at」を超えることはなく、署名に使用した認証情報の有効期限を超えることもありません。新しいリンクが必要な場合は、この時刻の経過後に再度ポーリングしてください。"
                    },
                    "error": {
                      "type": "string",
                      "nullable": true,
                      "example": "export timed out"
                    },
                    "expired_reason": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "window_ended",
                        "superseded",
                        "rights_changed",
                        "capture_erased",
                        "company_deleted",
                        null
                      ],
                      "description": "statusがexpiredの場合に設定されます：window_ended（「download_expires_at」を経過）、superseded（同じスコープの新しいエクスポート）、rights_changed（権限がジョブを対象としなくなった）、capture_erased（ジョブに含まれるキャプチャが消去された）、company_deleted（会社のデータが削除された）。"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "EXPORT_JOB_NOT_FOUND：該当するジョブがない、他のアカウントのジョブである、ジョブの記録が期限切れである（終了から8日後）、またはテストキーでリクエストしました。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/webhook-subscriptions": {
      "get": {
        "tags": [
          "Webhook"
        ],
        "operationId": "listWebhookSubscriptions",
        "summary": "Webhookサブスクリプションを一覧表示",
        "description": "アカウントのWebhookサブスクリプションを、新しい順に、有効なものと無効なものを含めてシークレットなしで返します。APIキーまたはダッシュボードセッションで利用できます。読み取り専用のキー（Website Archive）も利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Webhookサブスクリプション。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "subscriptions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookSubscription"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "post": {
        "tags": [
          "Webhook"
        ],
        "operationId": "createWebhookSubscription",
        "summary": "アカウントのイベントをサブスクライブ",
        "description": "httpsエンドポイントをアカウントのイベントにサブスクライブします：アカウントの一致するすべてのイベントが、そのWebhookサブスクリプション固有のシークレット（このレスポンスで1回だけ返されます）で署名されてPOSTされます。確認済みのメールアドレスが必要です（403 EMAIL_NOT_VERIFIED）。サブスクリプションの支払い期限超過中も利用できます（請求は発生しません）。アカウントごとの有効なWebhookサブスクリプションの上限：developer、startup、growth、custom、legal_solo、legal_seats：25件。website_archive：10件。archive_only、sandbox：0件（409 WEBHOOK_SUBSCRIPTION_LIMIT）。URLには「webhook_url」の規則が適用されます（https、認証情報なし、プライベートまたは予約済みのアドレス不可。配信のたびに再確認します）。Idempotency-Keyに対応しています：24時間以内に同じキーと本文で再試行すると、2つ目のWebhookサブスクリプションを作成する代わりに、シークレットを含む最初のレスポンスを返します。APIキーまたはダッシュボードセッションで利用できます。読み取り専用のキー（Website Archive）も利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "additionalProperties": false,
                "properties": {
                  "url": {
                    "type": "string",
                    "example": "https://hooks.example.com/proofsnap"
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 9,
                    "uniqueItems": true,
                    "items": {
                      "$ref": "#/components/schemas/WebhookEventType"
                    }
                  },
                  "filters": {
                    "$ref": "#/components/schemas/WebhookSubscriptionFilters"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "プレーンテキスト（文字数の上限：200）。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "作成しました。`secret`が表示されるのはここだけです。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscriptionCreated"
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST（events、filters、description、不明なフィールド）、MISSING_FIELD（url）、または、INVALID_URL。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "EMAIL_NOT_VERIFIED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "WEBHOOK_SUBSCRIPTION_LIMIT, IDEMPOTENCY_IN_PROGRESS.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "SSRF_BLOCKED（URLがブロック対象のアドレスを指しています）、または、IDEMPOTENCY_KEY_REUSED。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/webhook-subscriptions/{subscription_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SubscriptionId"
        }
      ],
      "get": {
        "tags": [
          "Webhook"
        ],
        "operationId": "getWebhookSubscription",
        "summary": "Webhookサブスクリプションを取得",
        "description": "1件のWebhookサブスクリプションを、配信状態とともにシークレットなしで返します。APIキーまたはダッシュボードセッションで利用できます。読み取り専用のキー（Website Archive）も利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Webhookサブスクリプション。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "WEBHOOK_SUBSCRIPTION_NOT_FOUND：不明、削除済み、または他のアカウントのものです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "patch": {
        "tags": [
          "Webhook"
        ],
        "operationId": "updateWebhookSubscription",
        "summary": "Webhookサブスクリプションを変更または再有効化",
        "description": "events、filters（nullまたは{}でクリアします）、descriptionを変更するか、無効なWebhookサブスクリプションをstatus \"active\"で再有効化します（失敗カウンターをリセットし、有効なものの上限と照合します）。URLは変更できません：新しいWebhookサブスクリプションを作成してください。確認済みのメールアドレスが必要です。APIキーまたはダッシュボードセッションで利用できます。読み取り専用のキー（Website Archive）も利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 9,
                    "uniqueItems": true,
                    "items": {
                      "$ref": "#/components/schemas/WebhookEventType"
                    }
                  },
                  "filters": {
                    "type": "object",
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/WebhookSubscriptionFilters"
                      }
                    ],
                    "nullable": true
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 200,
                    "nullable": true
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "active"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "変更後のWebhookサブスクリプション。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSubscription"
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "EMAIL_NOT_VERIFIED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_SUBSCRIPTION_NOT_FOUND：不明、削除済み、または他のアカウントのものです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "WEBHOOK_SUBSCRIPTION_LIMIT（上限を超える再有効化）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "delete": {
        "tags": [
          "Webhook"
        ],
        "operationId": "deleteWebhookSubscription",
        "summary": "Webhookサブスクリプションを削除",
        "description": "Webhookサブスクリプション、そのシークレット、キューに入っている配信を削除します。不明または削除済みの場合は「404」を返します（存在しないものとして扱ってください）。APIキーまたはダッシュボードセッションで利用できます。読み取り専用のキー（Website Archive）も利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "削除されました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "WEBHOOK_SUBSCRIPTION_NOT_FOUND：不明、削除済み、または他のアカウントのものです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/events": {
      "get": {
        "tags": [
          "Webhook"
        ],
        "operationId": "listEvents",
        "summary": "イベントログ",
        "description": "過去30日間にアカウントで発生したすべてのイベントを、Webhookサブスクリプションが受信したかどうかにかかわらず、新しい順に返します。APIキーには、そのキーの環境のイベントが表示されます（本番キーには本番のイベント、テストキーにはテストのイベント）。ダッシュボードセッションには本番のイベントが表示されます。バックフィルや、サブスクライブの代わりのポーリングに使用します。APIキーまたはダッシュボードセッションで利用できます。読み取り専用のキー（Website Archive）も利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "このイベントタイプのみ。",
            "schema": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1～100、デフォルト：25。",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "starting_after",
            "in": "query",
            "required": false,
            "description": "イベントIDです。ページはその次から始まります（「next_cursor」を渡します）。他のアカウントや環境のID、または30日より古いIDはエラーになります（400）。",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "イベントのページ。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true,
                      "description": "次のページでは「starting_after」として渡します。最後のページではnullです。"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST（type、limit、starting_after）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/whoami": {
      "get": {
        "tags": [
          "Webhook"
        ],
        "operationId": "whoami",
        "summary": "認証情報の確認",
        "description": "認証情報の内容を返します：プラン、環境、APIキーが読み取り専用かどうか、キーのID、名前、プレフィックス（ダッシュボードセッションではnull）です。連携サービスが接続のテストやラベル付けに使用します。メールアドレスとアカウントIDは含まれません。APIキーまたはダッシュボードセッションで利用できます。読み取り専用のキー（Website Archive）も利用できます。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "認証情報。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "plan": {
                      "type": "string",
                      "nullable": true,
                      "example": "startup",
                      "enum": [
                        "developer",
                        "startup",
                        "growth",
                        "custom",
                        "legal_solo",
                        "legal_seats",
                        "website_archive",
                        "archive_only",
                        "sandbox",
                        null
                      ]
                    },
                    "api_read_only": {
                      "type": "boolean",
                      "description": "Website ArchiveアカウントのAPIキーではtrueです（このプランでは読み取りとサブスクライブはできますが、キャプチャの作成はできません）。他のプランの読み取り専用キーは、代わりにscopesに表示されます。"
                    },
                    "env": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "認証情報が動作する環境です。"
                    },
                    "key": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "key_id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "prefix": {
                          "type": "string",
                          "enum": [
                            "ps_live_",
                            "ps_test_"
                          ],
                          "nullable": true,
                          "description": "AIアプリの接続（credential oauth）ではnullです。"
                        },
                        "credential": {
                          "type": "string",
                          "enum": [
                            "key",
                            "oauth"
                          ],
                          "description": "key：APIキーです。oauth：MCPサーバーを通じて接続されたAIアプリのアクセストークンです。この場合、nameはアプリの名前です。"
                        }
                      }
                    },
                    "email_verified": {
                      "type": "boolean"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "read",
                          "capture"
                        ]
                      },
                      "description": "認証情報で実行できる操作です。フルキーまたはフル接続とダッシュボードセッションはreadとcaptureです。読み取り専用のキーまたは読み取り専用の接続はreadのみです（読み取りルートと検証にのみアクセスでき、一括エクスポートにはアクセスできません）。スコープ外のルートは「403 INSUFFICIENT_SCOPE」を返します。"
                    },
                    "account_ref": {
                      "type": "string",
                      "example": "acct_3f9a0c2b7d1e4f5a6b7c8d9e0f1a2b3c",
                      "description": "アカウントの安定した不透明な参照子です。アカウントのすべてのキー、接続、セッションで同じ値になり、アカウントIDになることはありません。安定したユーザーIDを必要とするアプリ（ChatGPTのアカウントプロファイルなど）向けです。"
                    },
                    "usage": {
                      "type": "object",
                      "description": "キャプチャの利用枠です。period month：今月のキャプチャ数とプランに含まれるキャプチャ数です（プランにキャプチャが含まれない場合や無制限の場合、includedとremainingはnullです。利用枠を超えたキャプチャはプランの料金で請求されます）。period lifetime：無料のサンドボックスで、透かし入りのテストキャプチャは合計で最大50件です。",
                      "properties": {
                        "period": {
                          "type": "string",
                          "enum": [
                            "month",
                            "lifetime"
                          ]
                        },
                        "included": {
                          "type": "integer",
                          "nullable": true
                        },
                        "used": {
                          "type": "integer"
                        },
                        "remaining": {
                          "type": "integer",
                          "nullable": true
                        }
                      }
                    },
                    "oauth": {
                      "type": "object",
                      "description": "MCPサーバーを通じて接続されたAIアプリの場合のみ返されます：付与されたスコープ、接続日時、このリクエストのアクセストークンの終了日時です（アプリはそれまでに更新します）。パスワードを変更すると、それ以前に作成されたすべての接続が終了します。",
                      "properties": {
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "connected_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "expires_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/captures/events": {
      "get": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "listCaptureEvents",
        "summary": "キャプチャイベントチェーン（削除とリーガルホールド）",
        "description": "アカウントのキャプチャに起きたことを記録する、改ざん検知可能な記録です：ゴミ箱への移動、復元、完全に削除（erase）、ゴミ箱の消去、保存期間による削除、アカウントまたは会社に伴う削除、リーガルホールドの設定と解除（サブスクリプション終了後のシステムによる解除では、actorが`system`、detailが`subscription_ended`です）、S3 Object Lockの結果、証拠パッケージのインポート（type `import`、detailはパッケージの種類）。古い順に返します。チェーンはキャプチャとアカウントのデータより長く存続します：含まれるのはIDとマニフェストハッシュのみで、キャプチャの内容や自由入力のテキストは含まれません。\n\n検証方法：（1）各イベントについて、ハッシュ対象フィールド（verification.hashed_fields。キーはソート、空白なし、値がない場合はnull）の正規化JSONのハッシュ（SHA-256）を計算し、`hash`と比較します。（2）各`prev_hash`が前のイベントの`hash`と等しいこと（seq 1では0が64個）、およびseqに欠番がないことを確認します。（3）アンカーについては、`head_hash`がイベント`to_seq`の`hash`と等しいことを確認し、`ots_proof_base64`をファイルに書き出して（base64デコード）、`ots verify -d <head_hash> anchor.ots`を実行します（OpenTimestampsクライアント）。これにより、そのイベントまでのチェーンが遅くともそのBitcoinブロックの時点までに存在していたことが証明されます。アンカーは、前日以前のイベントがあるすべてのアカウントについて1日1回作成されます。\n\nAPIキーまたはダッシュボードセッションで、自分のアカウントが対象です。`scope=company`を指定すると、会社のオーナーは会社のキャプチャのチェーンを取得できます（呼び出し元が複数の会社を所有している場合は`org`で選択します。会社アーカイブとして保持されている会社はダッシュボードセッションのみ）。テストキーの場合は「403 FORBIDDEN」を返します：チェーンは本番のキャプチャを対象としており、チェーンを壊さずにフィルタリングできないためです。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1～500、デフォルト：100。",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "name": "starting_after",
            "in": "query",
            "required": false,
            "description": "イベントのseqです。ページはその次から始まります（「next_starting_after」を渡します）。",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "own",
                "company"
              ],
              "default": "own"
            }
          },
          {
            "name": "org",
            "in": "query",
            "required": false,
            "description": "scope=company：会社ID。",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "チェーンのページ。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "chain": {
                      "type": "string"
                    },
                    "scope": {
                      "type": "string",
                      "enum": [
                        "own",
                        "company"
                      ]
                    },
                    "head": {
                      "type": "object",
                      "properties": {
                        "chain": {
                          "type": "string"
                        },
                        "seq": {
                          "type": "integer"
                        },
                        "head_hash": {
                          "type": "string",
                          "nullable": true
                        },
                        "anchored_seq": {
                          "type": "integer"
                        }
                      }
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaptureEvent"
                      }
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "next_starting_after": {
                      "type": "integer",
                      "nullable": true
                    },
                    "anchors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaptureEventAnchor"
                      }
                    },
                    "verification": {
                      "type": "object",
                      "properties": {
                        "hash": {
                          "type": "string"
                        },
                        "hashed_fields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "genesis_prev_hash": {
                          "type": "string"
                        },
                        "anchor": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST：limit、starting_after、または、scopeが無効です。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "FORBIDDEN：テストキーでリクエストした、または会社を所有していない人がscope=companyを指定しました。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/legal-holds": {
      "post": {
        "tags": [
          "キャプチャ"
        ],
        "operationId": "bulkLegalHold",
        "summary": "リーガルホールドを一括で設定または解除",
        "description": "多数のキャプチャのリーガルホールドを一度に設定（enabled true）または解除（false）します。selectorには次のいずれか1つを指定します：`capture_ids`（IDの数：1～500）、`matter_id`（呼び出し元が開ける案件のキャプチャ）、`host`（そのホスト名の、呼び出し元自身のキャプチャ）、`schedule_id`（呼び出し元のスケジュールで作成された、呼び出し元自身のキャプチャ）。各キャプチャにはPATCH /captures/{capture_id}（action legal_hold）の規則が適用され、個別の結果が返されます：applied、unchanged（すでにその状態）、またはエラーコードによる拒否です（例：FORBIDDEN、CAPTURE_IN_TRASH、CAPTURE_PROCESSING、LEGAL_HOLD_OWNER_ONLY、LEGAL_HOLD_MATTER、LEGAL_HOLD_SOURCE（元のキャプチャがまだリーガルホールドの対象である墨消しの場合）、CAPTURE_NOT_FOUND、LEGAL_HOLD_NOT_AVAILABLE（テストモードのキャプチャの場合））。各キャプチャから作成された墨消しは、unchangedと報告されたキャプチャも含め、そのキャプチャのリーガルホールドに従います。リクエスト内で完了しない場合は、数分以内に完了します。リーガルホールドの設定には有料プランが必要です：無料のサンドボックスでは、リクエスト全体に対して「403 LEGAL_HOLD_NOT_AVAILABLE」を返します（details.reason \"plan\"）。解除はすべてのプランで実行できます。ここで設定したリーガルホールドの「legal_hold_source」は\"bulk\"です。解除は一括でも個別でも同じように実行できます。リクエストあたりのキャプチャ数には上限があります（上限：500）：これを超える案件、ホスト、スケジュールは途中で打ち切られます（`truncated: true`。再度送信してください）。変更された最初の25件のキャプチャのS3 Object Lockのリーガルホールドはリクエスト内で適用され、残りは数分以内に適用されます（`s3_legal_hold.status` pending）。コスト：キャプチャ10件ごとにレート制限1ユニット（最低1ユニット）です。1つのウィンドウで許容される量を超えるリクエストは「400 RATE_LIMIT_COST_TOO_HIGH」になります。APIキーまたはダッシュボードセッションで利用できます。Website ArchiveではAPIキーは読み取り専用です（403 PLAN_API_READ_ONLY）。メールアドレスが未確認のダッシュボードセッションまたはキーには「403 EMAIL_NOT_VERIFIED」を返します。サブスクリプションの支払い期限超過によってブロックされることはありません。",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "enabled",
                  "selector"
                ],
                "additionalProperties": false,
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "設定された各リーガルホールドとともに保持されるプレーンテキストです（解除時には保持されません）。ハッシュ対象のチェーンには含まれません。"
                  },
                  "selector": {
                    "type": "object",
                    "minProperties": 1,
                    "maxProperties": 1,
                    "properties": {
                      "capture_ids": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 500,
                        "items": {
                          "type": "string"
                        }
                      },
                      "matter_id": {
                        "type": "string"
                      },
                      "host": {
                        "type": "string"
                      },
                      "schedule_id": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "キャプチャごとの結果。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "enabled": {
                      "type": "boolean"
                    },
                    "selector": {
                      "type": "string",
                      "enum": [
                        "capture_ids",
                        "matter_id",
                        "host",
                        "schedule_id"
                      ]
                    },
                    "requested": {
                      "type": "integer"
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "applied": {
                      "type": "integer"
                    },
                    "unchanged": {
                      "type": "integer"
                    },
                    "refused": {
                      "type": "integer"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "capture_id": {
                            "type": "string"
                          },
                          "result": {
                            "type": "string",
                            "enum": [
                              "applied",
                              "unchanged",
                              "refused"
                            ]
                          },
                          "code": {
                            "type": "string",
                            "description": "拒否のエラーコードです。"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST（本文、selector、上限（500）を超える「capture_ids」）、RATE_LIMIT_COST_TOO_HIGH。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "EMAIL_NOT_VERIFIED、PLAN_API_READ_ONLY、LEGAL_HOLD_NOT_AVAILABLE（有料プランなしでの設定、details.reason plan）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND（呼び出し元が開けない「matter_id」）、SCHEDULE_NOT_FOUND。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/imports": {
      "post": {
        "tags": [
          "パッケージのインポート"
        ],
        "operationId": "createImport",
        "summary": "パッケージのインポートを開始",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "インポートを作成し、アップロードを開始します。ZIPの正確なサイズをバイト単位で送信してください。レスポンスには、32 MiBのパートごとに1つの署名付きPUT URL（最後のパートはそれより小さい）が含まれ、1時間有効です（`upload.expires_at`。サーバーの署名用認証情報より長くなることはありません）。各パートのバイトをそのURLにPUTし、各レスポンスの`ETag`ヘッダーを保持してから、24時間以内にPOST /imports/{import_id}/completeを呼び出してください。`matter_id`を指定すると、受理されたキャプチャがその案件に追加されます：その時点でキャプチャを追加できる案件である必要があります（開くことができる、ステータスがopenの案件。会社のシートのインポートはその会社の案件のみ）。作成するたびに1日50件の上限に計上されます。インポートは有料プランのdeveloper、startup、growth、custom、legal_solo、legal_seats、website_archive（Website Archiveはダッシュボードセッションからのみ）で利用できます。Developerプランでは1か月あたり最大2 GBをインポートできます。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "filename",
                  "size_bytes"
                ],
                "additionalProperties": false,
                "properties": {
                  "filename": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "表示するファイル名です（プレーンテキスト：制御文字、不可視文字、テキスト方向文字は使用できません）。"
                  },
                  "size_bytes": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 2147483648,
                    "description": "ZIPの正確なサイズ（バイト）です。最大2 GiBです。"
                  },
                  "matter_id": {
                    "type": "string",
                    "description": "省略可能です：受理されたキャプチャをこの案件に追加します。案件にはLegalプランが必要です（他のプランでは「403 MATTERS_NOT_ENABLED」）。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "インポートを作成しました。パートをアップロードしてください。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "import_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "uploading"
                      ]
                    },
                    "upload": {
                      "type": "object",
                      "properties": {
                        "upload_id": {
                          "type": "string"
                        },
                        "part_size": {
                          "type": "integer",
                          "example": 33554432
                        },
                        "parts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "part_number": {
                                "type": "integer"
                              },
                              "url": {
                                "type": "string",
                                "format": "uri",
                                "description": "署名付きのS3 UploadPart URLです：正確に「size_bytes」バイトをPUTし（URLがContent-Lengthに署名しています）、レスポンスのETagヘッダーを読み取ります。他のヘッダーは不要です。"
                              },
                              "size_bytes": {
                                "type": "integer",
                                "description": "このパートの正確なバイト長です：最後以外のパートは「part_size」で、最後のパートは残りの長さです（パートnの開始位置：(n - 1) x part_size）。"
                              }
                            }
                          }
                        },
                        "expires_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST（本文、filename、size_bytes、matter_id、不明なフィールド）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED：サブスクリプションの支払いが期限超過または未払いです。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IMPORT_NOT_ALLOWED（details.reason plan：サンドボックス、または、archive_only。live_credentials_required：テストキー、または請求先が登録されていないセッション）、PLAN_API_READ_ONLY（「website_archive」のAPIキー）、MATTERS_NOT_ENABLED（Legalプランなしの「matter_id」）、EMAIL_NOT_VERIFIED、FORBIDDEN（会社のシートによる他社の案件へのインポート）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "MATTER_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IMPORT_LIMIT（進行中のインポートが3件。details.limit、details.in_progress）、MATTER_SEALED、MATTER_ARCHIVED、COMPANY_READ_ONLY。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "IMPORT_TOO_LARGE：「size_bytes」が2 GiBを超えています（details.max_bytes）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED：1分あたりの上限、または1日50件のインポートの上限に達しました（details.action import_create、details.daily_limit）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      },
      "get": {
        "tags": [
          "パッケージのインポート"
        ],
        "operationId": "listImports",
        "summary": "インポートを一覧表示",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "インポートを新しい順に返します。最終状態のインポートは30日間保持されます（受理されたインポートのキャプチャは残ります）。24時間を過ぎたアップロードはexpiredと表示されます。",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "前のページの「next_cursor」です。"
          }
        ],
        "responses": {
          "200": {
            "description": "インポートのページ。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "imports": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Import"
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST（limitまたはcursor）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/imports/{import_id}": {
      "parameters": [
        {
          "name": "import_id",
          "in": "path",
          "required": true,
          "description": "インポートIDです（imp_に続く16～24文字の英数字）。形式が不正なIDは「404 IMPORT_NOT_FOUND」を返します。",
          "schema": {
            "type": "string",
            "pattern": "^imp_[A-Za-z0-9]{16,24}$"
          }
        }
      ],
      "get": {
        "tags": [
          "パッケージのインポート"
        ],
        "operationId": "getImport",
        "summary": "インポートを取得",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "インポートと、最終状態になった後はその結果を返します。POST /imports/{import_id}/completeの後にポーリングしてください。検証は通常数秒で完了し、2 GiBのパッケージでは数分かかることがあります。アップロード中に?upload=trueを指定すると、レスポンスにuploadが追加されます：ストレージにまだないパートの新しい署名付きURL（parts）と、すでに受信したパート（received：part_number、etag、size_bytes。一覧を取得できなかった場合はnullで、その場合はすべてのパートに再度署名します）、またはアップロードがすでに完了している場合はcompleted: true（completeを再度送信してください）です。ネットワークの切断、パートのURLの期限切れ（URLは最大1時間、アップロード期間は24時間）、ページの再読み込みの後に再開する際に使用します。?upload=trueは、1分あたりのレート制限を1ユニット消費します。",
        "responses": {
          "200": {
            "description": "インポート。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Import"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "IMPORT_NOT_FOUND（他のアカウントのインポートの場合も含みます）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED（?upload=trueの場合のみ）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        },
        "parameters": [
          {
            "name": "upload",
            "in": "query",
            "required": false,
            "description": "true（または1）：アップロード中のインポートについて、新しいパートのURLと受信済みのパートを追加します。",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "1"
              ]
            }
          }
        ]
      },
      "delete": {
        "tags": [
          "パッケージのインポート"
        ],
        "operationId": "cancelImport",
        "summary": "アップロードをキャンセル",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "アップロード中のインポートをキャンセルします：アップロードは中止され、パートが削除され、インポートも削除されます（以降のGETは「404」を返します）。",
        "responses": {
          "200": {
            "description": "キャンセルしました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "import_id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "IMPORT_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IMPORT_STATE：インポートはアップロード中ではなくなっています（details.status）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    },
    "/imports/{import_id}/complete": {
      "parameters": [
        {
          "name": "import_id",
          "in": "path",
          "required": true,
          "description": "インポートIDです（imp_に続く16～24文字の英数字）。形式が不正なIDは「404 IMPORT_NOT_FOUND」を返します。",
          "schema": {
            "type": "string",
            "pattern": "^imp_[A-Za-z0-9]{16,24}$"
          }
        }
      ],
      "post": {
        "tags": [
          "パッケージのインポート"
        ],
        "operationId": "completeImport",
        "summary": "アップロードを完了して検証",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "アップロードを完了し、検証を開始します。partsは省略可能です：すべてのパート番号（1からNまで、順番どおり）を、パートのPUTが返したETagとともに送信するか、省略するとサーバーがアップロード済みのパートをストレージから読み取ります（ETagヘッダーを読み取れないブラウザで便利です）。保存されたサイズが「size_bytes」と等しいことを確認します。GET /imports/{import_id}をポーリングしてください。ストレージが拒否したパート一覧、またはまだアップロードされていないパート（details.missing_parts）はエラーになり（400）、アップロードは開いたままです：不足分をアップロードして（GET /imports/{import_id}?upload=trueで新しいURLを取得できます）再度送信してください。レスポンスが失われた後にcompleteを再度送信しても安全です：実行中のcompleteは「409」を返し、停止したものは2分後に引き継がれ、すでに完了したアップロードは検証に進みます。サイズが「size_bytes」と異なる場合、アップロードは破棄されます（422 IMPORT_SIZE_MISMATCH。インポートは拒否されるため、新しく作成してください）。",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "parts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "part_number",
                        "etag"
                      ],
                      "properties": {
                        "part_number": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "etag": {
                          "type": "string",
                          "description": "パートのPUTのレスポンスのETagヘッダーです。引用符の有無は問いません。"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "検証を開始しました。",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "import_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "verifying"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "MALFORMED_REQUEST（partsの順序が正しくない、またはアップロード済みのパートと一致しない。あるいは、partsなしの場合にまだアップロードされていないパートがある：details.missing_parts）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "PAYMENT_REQUIRED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "IMPORT_NOT_ALLOWED, PLAN_API_READ_ONLY, EMAIL_NOT_VERIFIED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "IMPORT_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IMPORT_STATE：インポートはアップロード中ではなくなっています（details.status。verifying、expiredなど）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "IMPORT_SIZE_MISMATCH（詳細：details.expected、details.actual）。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/AuthUnavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "APIキーを`Authorization: Bearer ps_live_...`として送信してください（スキーム名は大文字小文字を区別しません）。ヘッダーがない場合や形式が不正な場合は「401 MISSING_API_KEY」を返します。不明、失効済み、期限切れのキー、またはAPIアクセスのないアカウントの場合は、`WWW-Authenticate: Bearer realm=\"ProofSnap API\", error=\"invalid_token\"`とともに「401 INVALID_API_KEY」を返します。「403」は、有効な認証情報に対して操作が許可されていない場合（FORBIDDEN、プランによる制限）に使用されます。請求アカウント（Stripeの顧客）がリンクされていないアカウントの`ps_live_`キーはテストキーとして動作します：キャプチャには透かしが入り、請求されることはなく、「include_eidas」は拒否されます（403 EIDAS_REQUIRES_LIVE_KEY）。ゲートウェイはキーの判定を最大60秒間キャッシュするため、失効したキーが最大60秒間機能し続けることがあります。バックエンドの一時的な障害で認証情報を確認できない場合、ゲートウェイは代わりに「503 SERVICE_UNAVAILABLE」を返します。このレスポンスはキャッシュされないため、バックオフを入れて再試行してください。ゲートウェイからの「401」（認証情報の確認）では`WWW-Authenticate`チャレンジがそのまま返されます。ルートハンドラーからの「401」では、ゲートウェイが同じチャレンジを`x-amzn-Remapped-WWW-Authenticate`に名前を変更して配信します。"
      }
    },
    "headers": {
      "XRequestId": {
        "description": "リクエストIDです。サポートへの問い合わせにも役立ちます。成功レスポンスで送信されます。エラーの本文では「request_id」として含まれます。",
        "schema": {
          "type": "string"
        }
      },
      "RateLimitLimit": {
        "description": "現在の60秒ウィンドウで許可されるリクエスト数です。レガシーヘッダーで、RateLimit / RateLimit-Policyと併せて残されています。",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "現在のウィンドウで残っているリクエスト数です。レガシーヘッダーで、RateLimit / RateLimit-Policyと併せて残されています。",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitReset": {
        "description": "現在のウィンドウが終了するISO 8601形式の時刻です。レガシーヘッダーで、RateLimit / RateLimit-Policyと併せて残されています。",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "RetryAfter": {
        "description": "再試行までに待機する秒数です。",
        "schema": {
          "type": "integer"
        }
      },
      "QuotaLimit": {
        "description": "プランに含まれる1か月あたりのキャプチャ数です（月間上限のあるプランの本番キー）。",
        "schema": {
          "type": "integer"
        }
      },
      "QuotaRemaining": {
        "description": "今月残っている、プランに含まれるキャプチャ数です。",
        "schema": {
          "type": "integer"
        }
      },
      "QuotaUsed": {
        "description": "今月完了したキャプチャ数です。",
        "schema": {
          "type": "integer"
        }
      },
      "QuotaCap": {
        "description": "呼び出し元に適用される月間の最大値です（プランのデフォルト、自身の上限、または会社の上限）。",
        "schema": {
          "type": "integer"
        }
      },
      "QuotaOrgLimit": {
        "description": "会社のメンバーのみ：オーナーが設定した場合の、会社全体の月間上限です。",
        "schema": {
          "type": "integer"
        }
      },
      "QuotaOrgUsed": {
        "description": "会社のメンバーのみ：今月、会社全体で受け付けたキャプチャ数です。",
        "schema": {
          "type": "integer"
        }
      },
      "SandboxLimit": {
        "description": "サンドボックス（プランのないダッシュボードセッション）：透かし入りテストキャプチャの累計の利用枠です（50）。",
        "schema": {
          "type": "integer"
        }
      },
      "SandboxRemaining": {
        "description": "サンドボックス：残りの利用枠です。",
        "schema": {
          "type": "integer"
        }
      },
      "SandboxUsed": {
        "description": "サンドボックス：使用済みの利用枠です。",
        "schema": {
          "type": "integer"
        }
      },
      "IdempotentReplay": {
        "description": "このレスポンスが同じIdempotency-Keyの以前のリクエストを再生したものである場合は\"true\"です。",
        "schema": {
          "type": "string",
          "enum": [
            "true"
          ]
        }
      },
      "WWWAuthenticate": {
        "description": "すべての「401」とともに送信されるRFC 6750のチャレンジです。ゲートウェイではなくルートハンドラーが返した「401」では、API Gatewayが`x-amzn-Remapped-WWW-Authenticate`に名前を変更して配信します。無効、失効済み、期限切れのAPIキー、または不正もしくは失効済みのセッショントークン（INVALID_API_KEY）：`Bearer realm=\"ProofSnap API\", error=\"invalid_token\"`。Authorizationヘッダーがない、または形式が不正（MISSING_API_KEY）：`Bearer realm=\"ProofSnap API\"`。",
        "schema": {
          "type": "string"
        },
        "example": "Bearer realm=\"ProofSnap API\", error=\"invalid_token\""
      },
      "RateLimitPolicy": {
        "description": "レート制限のポリシーです。IETFドラフトdraft-ietf-httpapi-ratelimit-headersに従います（構造化フィールド形式。ドラフトに基づくため、ドラフトとともに変更される場合があります）：`\"default\";q=<requests per window>;w=60`。",
        "schema": {
          "type": "string"
        },
        "example": "\"default\";q=120;w=60"
      },
      "RateLimit": {
        "description": "現在のレート制限の状態です。IETFドラフトdraft-ietf-httpapi-ratelimit-headersに従います（ドラフトに基づきます）：`\"default\";r=<requests left>;t=<seconds until the window resets>`。レート制限のあるルート（キャプチャの単一とバッチ、compare、redact、certify-hash）のレスポンスで、リミッターの実行後に送信され、「429」の場合に限りません（認証などでリミッターの前に拒否されたリクエストには含まれません）。",
        "schema": {
          "type": "string"
        },
        "example": "\"default\";r=117;t=42"
      }
    },
    "parameters": {
      "CaptureId": {
        "name": "capture_id",
        "in": "path",
        "required": true,
        "description": "キャプチャ、証明書、比較、墨消し、またはインポートしたパッケージのIDです。IDはcap_、cert_、cmp_、red_、imp_のいずれかで始まります。形式が不正なIDは「404 CAPTURE_NOT_FOUND」を返します。",
        "schema": {
          "type": "string",
          "example": "cap_a1B2c3D4e5F6g7H8"
        }
      },
      "ScheduleId": {
        "name": "schedule_id",
        "in": "path",
        "required": true,
        "description": "スケジュールIDです。他のアカウントのスケジュールは「404 SCHEDULE_NOT_FOUND」を返します。",
        "schema": {
          "type": "string",
          "example": "sch_a1B2c3D4e5F6g7H8"
        }
      },
      "MatterId": {
        "name": "matter_id",
        "in": "path",
        "required": true,
        "description": "案件IDです。メンバーではない案件は「404 MATTER_NOT_FOUND」を返します。",
        "schema": {
          "type": "string",
          "example": "mat_a1B2c3D4e5F6g7H8"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "再試行を安全にする、クライアント指定の任意のキーです。使用されるのは先頭の文字のみで（上限：255）、キーはアカウント単位で24時間有効です。同じキーと同じ本文で再試行すると、`Idempotent-Replay: true`とともに元のレスポンス本文を返します（単一キャプチャ、バッチ、比較は「202」、墨消しは「201」。`status`はキャプチャ、比較、墨消し、およびバッチの各キャプチャの現在のステータスに更新されます）。新しいキャプチャの作成や請求は行われません。同じキーで本文が異なる場合は「422 IDEMPOTENCY_KEY_REUSED」を返します。最初のリクエストの受付中に再試行すると、`error.details.capture_id`に元のID（バッチの場合は「batch_id」）を含めて「409 IDEMPOTENCY_IN_PROGRESS」を返します。リクエストでは`Idempotency-Key-Previous`で以前のキーを送信することもできます：アカウントにそのキーの記録がある場合、リクエストはそのキーで続行されます（ProofSnap MCPサーバーは、時間枠に結び付けられたキーにこれを使用します）。",
        "schema": {
          "type": "string",
          "maxLength": 255
        }
      },
      "SubscriptionId": {
        "name": "subscription_id",
        "in": "path",
        "required": true,
        "description": "WebhookサブスクリプションIDです。他のアカウントのWebhookサブスクリプションは「404 WEBHOOK_SUBSCRIPTION_NOT_FOUND」を返します。",
        "schema": {
          "type": "string",
          "example": "whs_a1B2c3D4e5F6g7H8"
        }
      }
    },
    "responses": {
      "RateLimited": {
        "description": "RATE_LIMITED：現在の60秒ウィンドウのリクエストが多すぎます。`error.details.retry_after_seconds`はRetry-Afterと同じ値です。RateLimitはr=0とウィンドウがリセットされるまでの秒数を報告します。",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "RATE_LIMITED",
                "message": "Too many requests. See Retry-After header.",
                "details": {
                  "retry_after_seconds": 42
                }
              },
              "request_id": "..."
            }
          }
        }
      },
      "InternalError": {
        "description": "INTERNAL_ERROR：予期しないサーバーエラーです。指数バックオフで再試行してください。",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "AuthUnavailable": {
        "description": "SERVICE_UNAVAILABLE：ゲートウェイが認証情報を確認できませんでした（バックエンドの一時的な障害）。キャッシュされません：バックオフを入れて再試行してください。",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "SERVICE_UNAVAILABLE",
                "message": "Authentication is temporarily unavailable. Please retry."
              },
              "request_id": "..."
            }
          }
        }
      },
      "EidasOrAuthUnavailable": {
        "description": "EIDAS_UNAVAILABLE：「include_eidas」が要求されましたが、このデプロイ環境では適格タイムスタンプが設定されていません。「include_eidas」なしで再試行してください。SERVICE_UNAVAILABLE：ゲートウェイが認証情報を確認できませんでした（バックエンドの一時的な障害で、キャッシュされません）。バックオフを入れて再試行してください。",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "401、2種類のコードがあります。MISSING_API_KEY：Authorizationヘッダーがない、または形式が不正です（`WWW-Authenticate: Bearer realm=\"ProofSnap API\"`）。INVALID_API_KEY：認証情報は送信されましたが有効ではありません：不明、失効済み、期限切れのAPIキー、APIアクセスのないアカウント、または無効もしくは失効済みのセッショントークンです（`WWW-Authenticate: Bearer realm=\"ProofSnap API\", error=\"invalid_token\"`）。同じ認証情報で再試行しないでください。「403」は、認証情報は有効ですが、この操作が許可されていないことを意味します（FORBIDDEN、プランによる制限）。",
        "headers": {
          "WWW-Authenticate": {
            "$ref": "#/components/headers/WWWAuthenticate"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "missing": {
                "value": {
                  "error": {
                    "code": "MISSING_API_KEY",
                    "message": "Missing or malformed Authorization header. Send Authorization: Bearer <your API key>."
                  },
                  "request_id": "..."
                }
              },
              "invalid": {
                "value": {
                  "error": {
                    "code": "INVALID_API_KEY",
                    "message": "The API key is invalid, revoked or expired, or the account has no API access."
                  },
                  "request_id": "..."
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "すべてのエラーはこの形式です。エラーレスポンスには、`request_id`と同じ値の`X-Request-ID`ヘッダーが含まれます。\n\nリクエストサイズ：リクエスト本文は最大6 MBです（Lambdaのペイロード上限。API Gateway自体の上限は10 MBです）。それより大きい本文はAPIコードに到達する前に拒否されるため、そのレスポンスはこの形式になりません。\n\n| HTTP | コード | 意味 |\n| --- | --- | --- |\n| 400 | `MALFORMED_REQUEST` | 本文が有効なJSONではない（メッセージ\"Request body is not valid JSON\"）、またはリクエストが無効です：`details.reason`がフィールドと理由を示す場合は`message`がその理由を繰り返し、それ以外の場合は\"The request is invalid.\"です。 |\n| 400 | `MISSING_FIELD` | 必須フィールドがありません。 |\n| 400 | `INVALID_URL` | URLが有効なhttp(s) URLではない、2048文字を超える、または「webhook_url」がhttpsではありません。 |\n| 400 | `INVALID_HASH` | certify-hash：ハッシュが16進数64文字ではありません。 |\n| 400 | `INVALID_TIMESTAMP_TYPE` | 「options.timestamp_type」が\"bitcoin\"ではありません。 |\n| 400 | `INVALID_VIEWPORT` | options.viewportが\"desktop\"または\"mobile\"ではありません。 |\n| 400 | `METADATA_TOO_LARGE` | options.metadataのキーが10個を超える、文字列以外の値がある、または値の文字数が上限（500）を超えています。 |\n| 400 | `INVALID_EVIDENCE_PACK_OPTIONS` | 「options.evidence_pack」が無効です。 |\n| 400 | `INVALID_BATCH` | バッチのurlsが、2～50個の有効なURLの配列ではありません。 |\n| 400 | `REDACTION_NO_OPS` | 墨消しに操作がない、またはどの操作にも一致するものがありませんでした。 |\n| 400 | `INVALID_CRON` | 「cron_expr」を解析できませんでした。 |\n| 400 | `INTERVAL_TOO_SHORT` | スケジュールの実行間隔がプランの最小値を下回っています。 |\n| 400 | `RATE_LIMIT_COST_TOO_HIGH` | リクエストに必要なレート制限のユニットが、1つのウィンドウで許容される量を超えています。`details.max_per_window`、`details.window_seconds`、`details.requested`。分割してください。 |\n| 400 | `WEBHOOK_REQUIRES_API_KEY` | ダッシュボードセッションから`webhook_url`が送信されました。WebhookはAPIキーのWebhook署名シークレットで署名されるため、APIキーが必要です。 |\n| 401 | `MISSING_API_KEY` | Authorizationヘッダーがない、または形式が不正です。`WWW-Authenticate: Bearer realm=\"ProofSnap API\"`。 |\n| 401 | `INVALID_API_KEY` | キーが不明、失効済み、期限切れ、APIアクセスがない、またはセッショントークンが無効もしくは失効済みです。`WWW-Authenticate: Bearer realm=\"ProofSnap API\", error=\"invalid_token\"`。 |\n| 402 | `QUOTA_EXCEEDED` | 月間の最大値またはサンドボックスの利用枠に達しました（この理由で拒否されたバックグラウンド証明の`error`にも含まれます）。 |\n| 402 | `PAYMENT_REQUIRED` | 本番のサブスクリプションの支払いが期限超過または未払いです（この理由でスキップされたスケジュールキャプチャの`error`にも含まれます）。 |\n| 403 | `FORBIDDEN` | リソースが他者のものである、または操作がオーナー専用です。メッセージ：\"You do not have access to this resource.\"（必要に応じてdetails.reasonが詳細を示します）。 |\n| 403 | `EMAIL_NOT_VERIFIED` | メールアドレスが未確認のダッシュボードセッションが、永続的なもの、有料のもの、または人を招待するものを作成しようとしました（キャプチャ、バッチ、比較、墨消し、APIキー、Webhook署名シークレット、チェックアウト、プラン変更、シート変更、certify-hash、スケジュール、会社招待、案件とそのすべての変更、案件メンバー、案件へのキャプチャの割り当て、共有とその取り消し、封印、エクスポート、リーガルホールド）。読み取りは引き続き実行できます。メッセージ：\"Confirm your email address first. Use the link we sent you, or send a new one from the dashboard.\" アカウントのメールアドレスが未確認の場合、APIキーも同様に拒否されます。 |\n| 403 | `EIDAS_REQUIRES_LIVE_KEY` | 「include_eidas」がテストキー（請求アカウントがリンクされていないアカウントの「ps_live_」キーはテストキーとして扱います）で送信された、またはテストキャプチャの比較や墨消しで送信されました（`details.reason`）。請求アカウントがリンクされていないためテストとして動作する本番キーまたはセッションには、`details.reason` \"no_billing_account\"が返されます。 |\n| 403 | `MATTERS_NOT_ENABLED` | 案件にはLegalプランが必要です。 |\n| 403 | `SCHEDULE_LIMIT_REACHED` | プランの有効なスケジュールの上限に達しました（またはプランにスケジュールがありません）。 |\n| 403 | `ON_CHANGE_REQUIRES_PLAN` | このプランでは「on_change」の変更検知を利用できません。 |\n| 403 | `PLAN_ARCHIVE_ONLY` | Archive onlyプランは、証拠の閲覧、ダウンロード、検証を維持するプランです。キャプチャ、スケジュール、証明、比較、墨消しは作成できません。 |\n| 403 | `PLAN_NOT_AVAILABLE` | このアカウントでは選択できないプランです：Archive onlyは、有料のAPIサブスクリプションの終了後（証拠がまだ保持されている間）に購入するか、developer、startup、growth、website_archive、または、「legal_solo」からのプラン変更で利用できます。会社アーカイブを利用できるのは、サブスクリプションが終了した会社のオーナーのみで、ダウンロード期間内に限ります。`details.reason`が理由を示します。 |\n| 403 | `PLAN_API_READ_ONLY` | Website Archiveプラン：APIキーは読み取り専用です（一覧表示、ダウンロード、検証、Webhook）。キャプチャ、スケジュール、証明、インポートはダッシュボードで作成するか、APIプランをご利用ください。 |\n| 403 | `LEGAL_HOLD_OWNER_ONLY` | 会社のキャプチャのリーガルホールドを解除できるのは会社のオーナーのみです（シートは設定できます）。 |\n| 403 | `LEGAL_HOLD_NOT_AVAILABLE` | リーガルホールドの設定には、有料プラン（`details.reason` \"plan\"：無料のサンドボックス、またはサブスクリプションが終了したアカウント）と本番のキャプチャ（`details.reason` \"test_capture\"：透かし入りのテストモードのキャプチャ）が必要です。この理由でリーガルホールドの解除が拒否されることはありません。 |\n| 403 | `IMPORT_NOT_ALLOWED` | パッケージのインポートには、サンドボックスや「archive_only」ではない有料プラン（`details.reason` \"plan\"）と、本番のAPIキーまたは請求先が登録されたダッシュボードセッション（`details.reason` \"live_credentials_required\"）が必要です。 |\n| 404 | `CAPTURE_NOT_FOUND` | キャプチャが存在しない、削除された、またはIDの形式が不正です。 |\n| 404 | `MATTER_NOT_FOUND` | 案件が存在しない、またはメンバーではありません。 |\n| 404 | `IMPORT_NOT_FOUND` | インポートが存在しない、他のアカウントのものである、またはIDの形式が不正です。 |\n| 404 | `WEBHOOK_SUBSCRIPTION_NOT_FOUND` | Webhookサブスクリプションが存在しない、削除された、または他のアカウントのものです。 |\n| 404 | `SCHEDULE_NOT_FOUND` | スケジュールが存在しない、または他のアカウントのものです。 |\n| 404 | `NOT_FOUND` | その他のリソースが見つかりません（発行台帳のハッシュ形式、共有トークン、エクスポートジョブ、メンバー）。 |\n| 404 | `EXPORT_JOB_NOT_FOUND` | キャプチャエクスポートジョブが存在しない、他のアカウントのものである、期限切れである、またはテストキーで要求されました。 |\n| 405 | `METHOD_NOT_ALLOWED` | このルートではそのHTTPメソッドは許可されていません。 |\n| 409 | `CAPTURE_PROCESSING` | キャプチャはまだ処理中のため、削除（またはリーガルホールドの変更）はまだできません。 |\n| 409 | `CAPTURE_LEGAL_HOLD` | キャプチャはリーガルホールドの対象であり、削除できません。 |\n| 409 | `CAPTURE_IN_TRASH` | リーガルホールド：キャプチャはゴミ箱にあります。先に復元してください。 |\n| 409 | `CAPTURE_HOLD_GRACE` | キャプチャのリーガルホールド解除後の猶予期間内は完全に削除できません。`details.until`。ゴミ箱への移動は可能です。 |\n| 409 | `LEGAL_HOLD_MATTER` | キャプチャのリーガルホールドは案件のリーガルホールドによって設定されており、まだ有効です：案件で解除してください（案件の閲覧者には`details.matter_id`）。 |\n| 409 | `LEGAL_HOLD_SOURCE` | 墨消しまたは比較のリーガルホールドは作成元のキャプチャ（比較の場合は比較したいずれかのキャプチャ）に従っており、そのキャプチャはまだリーガルホールドの対象です（そのキャプチャに直接、または案件を通じて設定）：そのリーガルホールドが解除されるまで、パッケージはリーガルホールドの対象のままです（`details.source_capture_id`）。 |\n| 409 | `COMPANY_READ_ONLY` | 会社のサブスクリプションが終了しています（または会社アーカイブとして保持されています）：その案件で実行できるのは、開く、エクスポート、共有リンクの取り消しのみで、そのキャプチャから新しいものを作成することもできません。 |\n| 409 | `WEBHOOK_SUBSCRIPTION_LIMIT` | プランの有効なWebhookサブスクリプションの上限に達しました（APIプランとLegalプランは25、Website Archiveは10、Archive onlyとサンドボックスは0）。`details.limit`、`details.active`。 |\n| 409 | `WEBHOOK_SECRET_ROTATION_PENDING` | 以前のWebhook署名シークレットがまだ24時間の重複期間内にあります。`details.previous_secret_expires_at`。 |\n| 409 | `IDEMPOTENCY_IN_PROGRESS` | このIdempotency-Keyの最初のリクエストがまだ受付中です。 |\n| 409 | `COMPARE_NOT_READY` | 比較するには、両方のキャプチャが完了している必要があります。 |\n| 409 | `REDACTION_NOT_READY` | 墨消しするには、元のキャプチャが完了している必要があります。 |\n| 409 | `MATTER_SEALED` | 案件（またはキャプチャの案件）は封印済みであり、変更できません。 |\n| 409 | `MATTER_SEALING` | 案件の封印を実行中です（最大60秒）：その間は、キャプチャの割り当て、名前の変更、メンバーの変更、リンクされたキャプチャのゴミ箱への移動、2回目の封印はできません。`Retry-After`。 |\n| 409 | `MATTER_ARCHIVED` | 案件はアーカイブ済みです：新しいキャプチャの追加、名前の変更、新しいメンバーの追加、共有、エクスポートはできません。先に再開してください（PATCH status \"open\"）。キャプチャやメンバーの削除は引き続き実行できます。 |\n| 409 | `MATTER_CHANGED` | 封印中に証拠管理ログが変更されました。封印は行われていません。再試行してください。 |\n| 409 | `MATTER_LINKED` | キャプチャの削除：キャプチャは、呼び出し元がすでに所属していない案件の証拠書類です。先に案件オーナーが案件から削除します。 |\n| 409 | `MATTER_HAS_TRASHED_CAPTURES` | 案件の封印：案件のキャプチャがゴミ箱にあります。復元するか案件から削除してから、再度封印してください。 |\n| 409 | `MEMBER_HAS_INDIVIDUAL_SUBSCRIPTION` | 会社招待：招待された人自身のAPIサブスクリプションがまだ更新されます。その人が解約した後、オーナーが再度招待します。 |\n| 409 | `IMPORT_LIMIT` | すでに3件のインポートが進行中です（アップロード中または検証中）。`details.limit`、`details.in_progress`。 |\n| 409 | `IMPORT_STATE` | インポートがこの操作を許可する状態ではありません（アップロード中ではなくなったインポートのcompleteまたはキャンセル）。`details.status`。 |\n| 409 | `EXPORT_JOB_RUNNING` | キャプチャのエクスポートがまだ準備中です。`details.job_id`と`details.poll_path`がそのジョブを示します。終了してから新しいエクスポートを開始してください。 |\n| 413 | `IMPORT_TOO_LARGE` | パッケージが2 GiBを超えています。`details.max_bytes`。 |\n| 413 | `VERIFY_PACKAGE_TOO_LARGE` | POST /captures/{capture_id}/verify：保存されたパッケージが上限（256 MiB）を超えています。同梱のスクリプトでオフラインで検証してください。`details.size_bytes`、`details.limit_bytes`。 |\n| 422 | `IDEMPOTENCY_KEY_REUSED` | Idempotency-Keyが、異なる本文または異なるキー環境（本番またはテスト）で再利用されました。 |\n| 422 | `SSRF_BLOCKED` | URLが、プライベート、ループバック、リンクローカル、またはその他のブロック対象のアドレスを指しています。 |\n| 422 | `TARGET_UNREACHABLE` | URLのホスト名にDNSレコードがない、または解決できませんでした。 |\n| 422 | `REDACTION_SCREENSHOT_UNREADABLE` | ボックスによる墨消しのためにスクリーンショットをデコードできませんでした。 |\n| 422 | `REDACTION_LEAK_DETECTED` | 墨消しされた語句が、キャプチャURL以外の場所に墨消し後も残っていました。何も発行されていません。`details.files`、`details.rule_indexes`、`details.metadata_fields`、`details.in_capture_url`。 |\n| 422 | `REDACTION_SOURCE_UNSUPPORTED` | 墨消しできるのはWebページのキャプチャのみです。`details.source`または`details.manifest_type`。 |\n| 422 | `REDACTION_SOURCE_INTEGRITY_FAILED` | 元のキャプチャのファイルが、署名付きマニフェストに記載されたハッシュ（SHA-256）と一致しない、またはファイルがありません。何も発行されていません。`details.mismatched`、`details.missing`。 |\n| 422 | `COMPARE_PROFILE_MISMATCH` | POST /compare：2つのキャプチャは、デバイスプロファイルまたはキャプチャ設定が異なります。`details.differing`、`details.before`、`details.after`。それでも比較するには、allow_profile_mismatch: trueを送信してください（この場合、テキストと画像の結果は未確定になります）。 |\n| 422 | `COMPARE_URL_MISMATCH` | POST /compare：2つのキャプチャは異なるページのものです。`details.before`、`details.after`（urlと「final_url」はオリジンとパスで示します）。それでも比較するには、allow_url_mismatch: trueを送信してください。 |\n| 422 | `RULE902_NOT_AVAILABLE_FOR_MISMATCH` | POST /compare：異なる方法でレンダリングされたキャプチャ（allow_profile_mismatch）に対する「include_rule_902」です。`details.differing`。 |\n| 422 | `COMPARE_SOURCE_INTEGRITY_FAILED` | POST /compareの元のキャプチャのファイルが、署名付きマニフェストに記載されたハッシュ（SHA-256）と一致しない、またはファイルがありません。比較も請求も行われていません。`details.capture_id`、`details.mismatched`、`details.missing`、`details.sources[]`。 |\n| 422 | `REDACTION_PATTERN_TOO_SLOW` | 「text_redactions」の正規表現パターンの実行時間が、このページで長すぎました（壊滅的なバックトラッキング）。発行も請求も行われていません。`details.rule_index`。パターンを簡略化してください。 |\n| 422 | `IMPORT_SIZE_MISMATCH` | アップロードされたパッケージが、通知された「size_bytes」と一致しません。アップロードは破棄されました。`details.expected`、`details.actual`。 |\n| 422 | `IMPORT_NOT_SUPPORTED` | インポートされた証拠パッケージの比較または墨消しです。 |\n| 429 | `RATE_LIMITED` | 現在のウィンドウのリクエストが多すぎる、または案件の作成（200）、封印（20）、エクスポート（50）、メンバー招待（50）、パッケージのインポート（50、`import_create`）の1日の上限に達しました（`details.daily_limit`、`details.action`）。`Retry-After`が再試行の時期を示します。 |\n| 429 | `CONCURRENT_CAPTURE_LIMIT` | アカウントで同時に実行中のキャプチャが多すぎます（developer 10、startup 25、growth 100、legal_solo、legal_seats 25、custom 200、website_archive 25、sandbox 5）。バッチは収まる数のURLを開始し、残りを`not_admitted`に記載します。空きがない場合はリクエスト全体が拒否されます。`details.limit`、`details.in_flight`、`details.requested`、`Retry-After`。 |\n| 429 | `TEST_MODE_DAILY_LIMIT` | テストモードの処理（テストキーまたは請求先が登録されていないセッション。透かし入りで請求なし）には、アカウントおよびUTCの1日ごとの上限があります（ユニット数の上限：200。バッチはURLの数を計上します）。`details.used`、`details.limit`、`details.reset_at`、`Retry-After`。 |\n| 429 | `IMPORT_DAILY_BYTES_LIMIT` | パッケージのインポート：アカウントのUTCの1日あたりのインポート量（通知されたサイズで5 GiB）に達しました。`details.period`、`details.limit_bytes`、`details.used_bytes`、`details.requested_bytes`、`details.reset_at`。 |\n| 429 | `IMPORT_MONTHLY_BYTES_LIMIT` | パッケージのインポート：アカウントのUTCの1か月あたりのインポート量（20 GiB。developerは2 GiB）に達しました。詳細は同じで、プラン固有の上限が適用される場合は`details.plan`が加わります。 |\n| 500 | `INTERNAL_ERROR` | 予期しないエラーです。バックオフを入れて再試行してください。 |\n| 500 | `CAPTURE_FAILED` | キャプチャを開始できなかった、または（失敗したキャプチャの`error`では）完了できませんでした。 |\n| 500 | `CAPTURE_TIME_BUDGET_EXCEEDED` | 失敗したキャプチャの`error`、または同期の墨消しで返されます：実行が制限時間を超え、パッケージの発行も請求も行われていません。 |\n| 500 | `CAPTURE_SCREENSHOT_TIMEOUT` | 失敗したキャプチャの`error`で返されます：ブラウザがスクリーンショットのレンダリングを完了しませんでした。すべての取得方法（1回での撮影、より小さい帯への分割、ブラウザ自体のスクリーンショット）がタイムアウトし、制限時間に余裕がある場合に新しく起動したブラウザで行う1回の再試行もタイムアウトしました。請求は行われていません。もう一度お試しください。 |\n| 500 | `CERTIFY_FAILED` | 失敗した証明の`error`で返されます：証明を完了できませんでした。 |\n| 500 | `REDACTION_FAILED` | 失敗した墨消しの`error`で返されます：墨消しを完了できませんでした。既知の理由で拒否された墨消しには、代わりにその理由のコードが含まれます（例：REDACTION_LEAK_DETECTED）。 |\n| 500 | `TIMESTAMP_SERVICE_UNAVAILABLE` | 案件の封印：OpenTimestampsのアンカーに失敗しました。何も変更されていません。再試行してください。 |\n| 500 | `CONFIGURATION_ERROR` | サーバー側の処理が失敗した、または設定されていません（`details.reason`）。 |\n| 503 | `SERVICE_UNAVAILABLE` | 認証が一時的に利用できません（認証情報を確認できませんでした）。キャッシュされません。再試行してください。 |\n| 503 | `EIDAS_UNAVAILABLE` | 「include_eidas」が要求されましたが、eIDASタイムスタンプが設定されていません。 |\n| 503 | `EIDAS_SEAL_RETRY` | 案件の封印：eIDASタイムスタンプが時間内に届きませんでした。封印は行われていません。`Retry-After`の後に再試行してください。再試行では、すでに発行されたタイムスタンプを再利用します。 |\n| 503 | `LIMIT_CHECK_UNAVAILABLE` | 案件の封印：1日の上限を確認できませんでした。何も行われていません。再試行してください。 |\n| 504 | `UPSTREAM_TIMEOUT` | 同期の処理（certify-hash、案件のエクスポート）が時間内に応答しませんでした。まだ完了する可能性があります：`details`が示すもの（`certify_id`、`poll_path`）をポーリングするか、再試行してください。 |\n| 404 | `ORG_INVITE_NOT_FOUND` | 会社招待が不明である、他の人宛てである、保留中ではなくなっている、または会社が稼働していません（details.reason `company_inactive`）。 |\n| 409 | `ORG_INVITE_NO_SEATS` | 会社招待の承諾：会社のすべてのシートが使用中です。招待は有効なままです。 |\n| 409 | `ORG_INVITE_IN_OTHER_ORG` | 会社招待の承諾：呼び出し元は他の会社のシートを保有しています。招待は有効なままです。 |\n| 409 | `ORG_INVITE_HAS_SUBSCRIPTION` | 会社招待の承諾：呼び出し元自身のAPIサブスクリプションがまだ更新されます。招待は有効なままです。 |\n| 409 | `ORG_OWNER_CANNOT_LEAVE` | 会社のオーナーが自分の会社から退出しようとしました。 |\n| 410 | `ORG_INVITE_EXPIRED` | 7日を超えた会社招待の承諾です。 |",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "機械可読のエラーコードです（UPPER_SNAKE_CASE）。"
              },
              "message": {
                "type": "string",
                "description": "人が読めるメッセージです。"
              },
              "details": {
                "type": "object",
                "additionalProperties": true,
                "description": "任意の追加情報です（`reason`、`field`、`retry_after_seconds`など）。"
              }
            },
            "required": [
              "code",
              "message"
            ]
          },
          "request_id": {
            "type": "string",
            "description": "リクエストID。"
          }
        },
        "example": {
          "error": {
            "code": "INVALID_URL",
            "message": "URL is not a valid http(s) URL",
            "details": {
              "reason": "Only http and https schemes are allowed"
            }
          },
          "request_id": "..."
        }
      },
      "CaptureOptions": {
        "type": "object",
        "description": "キャプチャのオプションです。すべてのフィールドは省略可能です。",
        "properties": {
          "scroll_full_page": {
            "type": "boolean",
            "description": "スクロール可能なページ全体をキャプチャします。falseの場合はビューポートのみをキャプチャします。",
            "default": true
          },
          "expand_collapsed": {
            "type": "boolean",
            "description": "スクリーンショットの前に折りたたまれたセクションを開きます：閉じた<details>要素、アコーディオンと開閉ボタン（aria-expandedとaria-controlsを持つもの）、および\"see more\" / \"show replies\"のテキストコントロールです。次のように保護されています：ナビゲーション、ヘッダー、メニュー、ダイアログの内部は対象外で、別のURLへのリンク、フォームの送信、状態を変更するラベル（like、follow、buy、deleteなど）も対象外です。各コントロールの操作は最大1回で、ページから移動しようとするコントロールがあると展開を停止し、元のURLを再度読み込みます。結果はコントロールごとに「forensic_log.json」に記録され（page_modifications.expand_collapsed：検出、開いた、閉じたまま、スキップの理由、開始されたリクエスト、前後のページの高さ）、概要はmetadata.jsonに記録されます（expand_collapsed：requested、opened_total、left_closed_total）。evidence.pdfと証明書には、実際に開かれた内容のみが記載されます。",
            "default": true
          },
          "viewport": {
            "type": "string",
            "description": "desktopはピクセル比1の1920x1080、mobileはモバイルSafariのユーザーエージェントを使用するピクセル比3の390x844です。その他の値は「400 INVALID_VIEWPORT」を返します。",
            "enum": [
              "desktop",
              "mobile"
            ],
            "default": "desktop"
          },
          "viewport_width": {
            "type": "number",
            "minimum": 320,
            "maximum": 3840,
            "description": "カスタムビューポートの幅（CSSピクセル）です。「viewport_height」と一緒に送信する必要があり、そうでない場合は「400 MALFORMED_REQUEST」を返します。"
          },
          "viewport_height": {
            "type": "number",
            "minimum": 240,
            "maximum": 4320,
            "description": "カスタムビューポートの高さ（CSSピクセル）です。「viewport_width」と一緒に送信する必要があります。"
          },
          "device_scale_factor": {
            "type": "number",
            "minimum": 1,
            "maximum": 3,
            "description": "スクリーンショットのデバイスピクセル比です。"
          },
          "wait_for_selector": {
            "type": "string",
            "description": "キャプチャの前に、このCSSセレクターを最大10秒間待機します。表示されない場合は、エラーなしでキャプチャを続行します。「forensic_log.json page_modifications」に記録されます。",
            "maxLength": 200
          },
          "wait_ms": {
            "type": "number",
            "minimum": 0,
            "maximum": 15000,
            "description": "ページの読み込み後の追加の待機時間（ミリ秒）です。"
          },
          "screenshot_format": {
            "type": "string",
            "description": "jpegの場合はscreenshot.jpegを、pngの場合は可逆圧縮のscreenshot.pngを提供します。C2PA Content Credentialsが追加されるのはJPEGのスクリーンショットのみです。",
            "enum": [
              "jpeg",
              "png"
            ],
            "default": "jpeg"
          },
          "url_stamp": {
            "type": "boolean",
            "description": "ページ画像の上に、キャプチャしたURL、キャプチャのUTC時刻（ブラウザがスクリーンショットを生成した時刻。帯状に分割して撮影した長いページでは、最後の帯が生成された時刻）、証拠IDを示すヘッダー帯を追加し、ソフトウェアによる注記であることを表示します。帯は画像の上に追加されるため、ページのピクセルが隠れることはありません。「chain_of_custody.json」には「screenshot_url_header.raw_screenshot_sha256」が「raw_screenshot_source」とともに記録されます：1回で撮影したページ（browser_image、browser_png、browser_jpeg_joined、browser_jpeg_reencoded）では、帯を追加する前の、ブラウザが生成したページ画像のハッシュ（SHA-256）です。帯状に分割して撮影し結合した長いページ（joined_bands、joined_bands_lossless、joined_bands_reencoded）では、C2PA Content Credentialsを追加する前の、ProofSnapが帯とともに書き込んだ結合画像のハッシュ（SHA-256）です。帯を追加できない場合（追加すると画像がJPEGの上限である65,535 pxを超える場合、描画に失敗した場合、またはフォールバックのスクリーンショット経路に限り、ページ画像のピクセル数が上限（32,000,000）を超える場合）、スクリーンショットは帯なしで提供されます：metadata.jsonの「screenshot.url_stamp_skipped」と、「chain_of_custody.json」の「screenshot_url_header」（appliedがfalseで、理由を含みます）に記録されます。",
            "default": false
          },
          "network_log": {
            "type": "boolean",
            "description": "network.har（リクエストとレスポンスのヘッダーとタイミングを含むHAR。本文は省略）とnetwork.original.harを含めます。",
            "default": true
          },
          "warc": {
            "type": "boolean",
            "description": "ページ読み込みのHTTPトランザクションを含むcapture.warc（ISO 28500）を含めます。レスポンス本文は制限時間内に読み取られます（最大30秒で、eIDAS、C2PA、終了時の時刻読み取りのために確保した時間を除いた、キャプチャの制限時間のうち任意の処理に使える範囲に限ります）。この制限で途切れた本文はWARC-Truncated: timeとともに空で保存され、到達しなかったレスポンスは含まれません。「chain_of_custody.json」の「warc_captured」（および「forensic_log.json」のwarc）に、「truncated、truncation_reason、response_pairs、records_total」と各カウントが記録されます。",
            "default": false
          },
          "external_archive": {
            "type": "boolean",
            "description": "Internet ArchiveのSave Page NowサービスにURLのアーカイブを依頼します（Internet Archiveはそのコピーを公開で保持します）。結果は、どのリクエストによってスナップショットが作成されたかと、リクエストに対する時刻によって分類されます：created（このリクエストのために作成）、recent_existing（Internet Archiveが以前のスナップショットで応答）、created_after_request（新しいスナップショットは存在するが、リクエストは確認されていない）、existing（古いスナップショットのみ存在）、pending、rate_limited、failed（Internet Archiveがリクエストを拒否）、unconfirmed（確認も拒否もする応答がなく、スナップショットも不明）、unavailable、skipped、skipped_sensitive、または、skipped_query。認証情報を含むように見えるURL、またはトークンに似たパラメータ、パラメータ名、パスセグメントを含むURLは送信されません。デフォルトでは無効です。trueに設定すると、クエリ文字列を含むURLも送信されます。結果は「forensic_log.json」（external_archive。キャプチャに対する「snapshot_offset_seconds」を含みます）と「chain_of_custody.json」に記録され、GET /captures/{capture_id}が「external_archive」として返します。リクエストはページの読み込み直後に、キャプチャの他の処理と並行して送信されます。失敗してもキャプチャは失敗しません。",
            "default": false
          },
          "dismiss_consent": {
            "type": "boolean",
            "description": "ページの読み込み前にすべてに同意する同意Cookieを設定し、Cookie同意バナーを閉じることを試みます。ページが変更されるため、デフォルトでは無効です。実行した内容は「forensic_log.json consent_dismissal」に記録されます。",
            "default": false
          },
          "dismiss_popups": {
            "type": "boolean",
            "description": "ニュースレター、プロモーションなどのオーバーレイポップアップを、それぞれの閉じるコントロールで閉じます。閉じたポップアップの数と使用したコントロールは「forensic_log.json page_modifications」に記録されます。閉じた各ポップアップは「forensic_log.json page_modifications」（popups_dismissed、popups_dismissed_controls）に記録され、evidence.pdfには閉じた数が記載されます。",
            "default": false
          },
          "dark_mode": {
            "type": "boolean",
            "description": "ダークカラースキームでレンダリングします。ページの外観が変更されます。「forensic_log.json page_modifications」に記録されます。evidence.pdfと「forensic_log.json page_modifications」で開示されます。",
            "default": false
          },
          "block_ads": {
            "type": "boolean",
            "description": "既知の広告ホストとトラッカーホストへのリクエストをブロックします。コンテンツが省略されます。「forensic_log.json page_modifications」に記録されます。",
            "default": false
          },
          "block_resources": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "image",
                "font",
                "media",
                "stylesheet"
              ]
            },
            "description": "ブロックするリソースタイプです。コンテンツが省略されます。「forensic_log.json page_modifications」に記録されます。"
          },
          "inject_css": {
            "type": "string",
            "description": "キャプチャの前にページに追加するCSSです。ページが変更されます。「forensic_log.json page_modifications」にそのまま保存されます。常に「forensic_log.json page_modifications」（injected_css）に、「injected_css_status」の`applied`または`failed`、および「injected_css_error」とともにそのまま保存されます。evidence.pdfにはカスタムCSSが挿入されたことが記載されますが、コードは印刷されません。",
            "maxLength": 10000
          },
          "inject_js": {
            "type": "string",
            "description": "キャプチャの前にページ内で実行するJavaScriptです。ページが変更されます。常に「forensic_log.json page_modifications」（injected_js）に、「injected_js_status」と「injected_js_error」とともにそのまま保存されます：`applied`（最後まで実行された）、`invalid`（構文エラーなどでコンパイルされず、実行されなかったためページは変更されていない）、`failed`（実行中に例外が発生したため、停止前にページが変更された可能性がある）、`timed_out`（キャプチャが5秒後に待機を終了した。スクリプトが実行を続けてページを変更した可能性がある）。evidence.pdfには結果が記載され、「forensic_log.json」が参照先として示されます。来歴証明書には、`invalid`でない限り、挿入されたコードがページの変更の一つとして記載されます。どちらにもコードは印刷されません。",
            "maxLength": 10000
          },
          "locale": {
            "type": "string",
            "description": "エミュレートするブラウザのロケールです（deやde-DEなど。ブラウザの言語とAccept-Languageを設定します）。エミュレーションのみです：プロキシは使用しないため、訪問者のIPに依存するコンテンツにはキャプチャサーバーのリージョンが引き続き反映されます。metadata.jsonのgeoに記録されます。",
            "pattern": "^[a-z]{2}(-[A-Z]{2})?$"
          },
          "timezone": {
            "type": "string",
            "description": "エミュレートするブラウザのタイムゾーンです（IANA名。Europe/Berlinなど）。エミュレーションのみです。"
          },
          "language": {
            "type": "string",
            "description": "人が読むためのPDFの言語。次のいずれかです：en、de、it、fr、es、pt_BR、cs、el、hi、hu、id、ja、ko、nl、pl、ro、ru、sv、tr、vi、zh_CN、zh_TW、ar、he、da、fi、nb、sk、uk。大文字と小文字、ハイフン、地域の違いは許容されます（\"DE\"、\"fr-FR\"、\"PT-BR\"は受け付けられます）。単独の\"pt\"と\"zh\"は拒否されます。サポートされていない値は「400 MALFORMED_REQUEST」を返します。",
            "default": "en",
            "example": "de"
          },
          "timestamp_type": {
            "type": "string",
            "description": "受け付けるのは\"bitcoin\"のみです（OpenTimestampsのアンカーは常に試行されます）。その他の値は「400 INVALID_TIMESTAMP_TYPE」を返します。適格タイムスタンプには「include_eidas」を使用してください。",
            "enum": [
              "bitcoin"
            ],
            "default": "bitcoin"
          },
          "include_eidas": {
            "type": "boolean",
            "description": "manifest.jsonのハッシュ（SHA-256）に対するeIDAS適格タイムスタンプ（RFC 3161）も要求します。manifest.json.tsrとして提供されます（検証データが返された場合は「eidas_validation.json」も提供されます）。本番キーのみ利用できます：テストキーは「403 EIDAS_REQUIRES_LIVE_KEY」を返します。デプロイ環境にeIDASサービスが設定されていない場合、リクエストは請求の前に拒否されます（503 EIDAS_UNAVAILABLE）。トークンを使用する前に、ProofSnapはトークンを確認し（署名、トークンが保持するハッシュ、CA Disig QCA4ルートへの証明書チェーン、TSA証明書のステータス）、その確認を「eidas_validation.json」（verification）に記録します。キャプチャ中にタイムスタンプのリクエストが失敗した場合、またはトークンがこの確認に合格しない場合、パッケージはタイムスタンプなしでOpenTimestampsのアンカーのみで提供され、スタンプは請求されません。timestamps.eidas（キャプチャの行、GET /captures/{capture_id}、completedのWebhook）は、ステータス「not_obtained」と理由（token_refused、unavailable、time_budget）を示します。スクリーンショット以降、キャプチャの任意の処理（WARCの本文、アーカイブとWHOISの応答、C2PA署名、2回目の時刻読み取り）はスタンプのための時間を残し、先に打ち切られます。スタンプごとに請求されます。",
            "default": false
          },
          "include_rule_902": {
            "type": "boolean",
            "description": "「rule_902_certification.pdf」を追加します：署名のない証明書テンプレート（[FRE 902(13)/(14)](https://www.govinfo.gov/content/pkg/USCODE-2023-title28/html/USCODE-2023-title28-app-federalru-dup2-rule902.htm)、[28 U.S.C. 1746](https://www.govinfo.gov/content/pkg/USCODE-2023-title28/html/USCODE-2023-title28-partV-chap115-sec1746.htm)）で、人が記入して署名するためのものです。そのハッシュ（SHA-256）はmanifest.jsonに記載されます。「evidence_pack.custodian」に空でない値がある場合にも追加されます。生成に失敗した場合、キャプチャはこのファイルなしで完了します。",
            "default": false
          },
          "case_reference": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlainText"
              }
            ],
            "description": "案件または事件のラベルです。空白は1つにまとめられます。プレーンテキストの規則（PlainTextを参照）に従います。metadata.json、「forensic_log.json」、「chain_of_custody.json」に記録され、evidence.pdfに印刷されます。",
            "maxLength": 200
          },
          "case_id": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlainText"
              }
            ],
            "description": "お使いのシステムの事件識別子です。「case_reference」と同様に記録され、プレーンテキストの規則（PlainTextを参照）に従います。",
            "maxLength": 200
          },
          "case_note": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlainText"
              }
            ],
            "description": "自由入力のメモです。プレーンテキストの規則（PlainTextを参照）に従います。metadata.json、「forensic_log.json」、「chain_of_custody.json」（legal_context.note）に記録されます。",
            "maxLength": 500
          },
          "webhook_url": {
            "type": "string",
            "description": "capture.completedまたはcapture.failedを受信するhttps URLです。Webhooksを参照してください。URLはhttpsである必要があり、プライベート、ループバック、リンクローカル、キャリアグレードNAT、クラウドメタデータのアドレスを指すことはできません（キャプチャURLと同じ規則です。違反すると「422 SSRF_BLOCKED」）。空または空白のみの値はWebhookなしを意味します。APIキーが必要です：WebhookはキーのWebhook署名シークレットで署名されるため、ダッシュボードセッションから送信すると「400 WEBHOOK_REQUIRES_API_KEY」で拒否されます。",
            "format": "uri"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "maxProperties": 10,
            "description": "最大10個の文字列タグ（値の文字数の上限：500）で、キャプチャとともに返されます。違反すると「400 METADATA_TOO_LARGE」を返します。"
          },
          "evidence_pack": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean",
                "description": "falseの場合、evidence.pdfから証明ページを除外します。",
                "default": true
              },
              "jurisdiction": {
                "type": "string",
                "description": "「forensic_log.json」のoptionsに記録されます。その他の効果はありません。",
                "enum": [
                  "US-Federal",
                  "EU-eIDAS"
                ],
                "default": "US-Federal"
              },
              "custodian": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "受け付けますが、テンプレートには印刷されません。テンプレートの宣言者フィールドは、署名する人のために空欄のままです。",
                    "maxLength": 200
                  },
                  "law_firm": {
                    "type": "string",
                    "description": "受け付けますが、テンプレートには印刷されません。テンプレートの宣言者フィールドは、署名する人のために空欄のままです。",
                    "maxLength": 200
                  },
                  "role": {
                    "type": "string",
                    "description": "受け付けますが、テンプレートでは使用されません。",
                    "maxLength": 200
                  },
                  "case_caption": {
                    "type": "string",
                    "description": "受け付けますが、テンプレートでは使用されません。",
                    "maxLength": 200
                  }
                },
                "additionalProperties": false,
                "description": "すべての値はプレーンテキストの規則（PlainTextを参照）に従います。違反すると「400 INVALID_EVIDENCE_PACK_OPTIONS」を返します。"
              }
            },
            "description": "無効な値は「400 INVALID_EVIDENCE_PACK_OPTIONS」を返します。"
          }
        }
      },
      "CaptureRequest": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "キャプチャするページです。httpまたはhttpsのみで、最大2048文字です。プライベート、ループバック、リンクローカル、メタデータのアドレスは「422 SSRF_BLOCKED」で拒否され、DNSレコードのないホスト名は「422 TARGET_UNREACHABLE」を返します。",
            "format": "uri",
            "maxLength": 2048
          },
          "options": {
            "$ref": "#/components/schemas/CaptureOptions"
          },
          "private_note": {
            "$ref": "#/components/schemas/PrivateNote"
          }
        },
        "example": {
          "url": "https://example.com",
          "options": {
            "case_reference": "Smith v. Jones",
            "webhook_url": "https://your-app.example/webhooks/proofsnap"
          }
        }
      },
      "CaptureAccepted": {
        "type": "object",
        "properties": {
          "capture_id": {
            "type": "string",
            "example": "cap_a1B2c3D4e5F6g7H8"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing"
            ]
          },
          "url": {
            "type": "string"
          },
          "poll_path": {
            "type": "string",
            "description": "/v1ステージを含むステータスパスです（例：/v1/captures/cap_...）。"
          },
          "message": {
            "type": "string"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "private_note": {
            "type": "string",
            "description": "保存されたプライベートメモ（正規化済み）です。送信された場合のみ含まれます。"
          },
          "warnings": {
            "$ref": "#/components/schemas/Rule902DisabledWarnings"
          }
        }
      },
      "CaptureResult": {
        "type": "object",
        "description": "キャプチャ、証明書、比較、または墨消しです。フィールドはステータスによって異なります。",
        "properties": {
          "capture_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "completed",
              "failed"
            ]
          },
          "url": {
            "type": "string",
            "description": "キャプチャされたURLです（証明書と比較ではnull）。",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "batch_id": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "type": {
            "type": "string",
            "description": "比較ではcomparison、インポートされた証拠パッケージではimportです。",
            "enum": [
              "comparison",
              "import"
            ]
          },
          "compared": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "比較のみ：比較元の2つのキャプチャIDです。"
          },
          "diff_summary": {
            "$ref": "#/components/schemas/DiffSummary"
          },
          "estimated_completion_seconds": {
            "type": "integer",
            "description": "processingのみ：おおよその見積もりで、最小値は5です。"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "CAPTURE_FAILED",
                  "CAPTURE_TIME_BUDGET_EXCEEDED",
                  "CAPTURE_SCREENSHOT_TIMEOUT",
                  "SSRF_BLOCKED",
                  "TARGET_UNREACHABLE",
                  "PAYMENT_REQUIRED",
                  "COMPARE_PROFILE_MISMATCH",
                  "COMPARE_URL_MISMATCH",
                  "RULE902_NOT_AVAILABLE_FOR_MISMATCH",
                  "COMPARE_SOURCE_INTEGRITY_FAILED",
                  "QUOTA_EXCEEDED",
                  "CERTIFY_FAILED",
                  "REDACTION_FAILED"
                ],
                "description": "失敗の公開理由です（エラー表を参照）。CAPTURE_SCREENSHOT_TIMEOUT：ブラウザがスクリーンショットを完了しませんでした。CAPTURE_TIME_BUDGET_EXCEEDED：実行が制限時間をすべて使い切りました。いずれも請求されません。比較の行（cmp_）は、COMPARE_SOURCE_INTEGRITY_FAILED（リクエストの受付後に元のパッケージが変更された）、COMPARE_PROFILE_MISMATCH、または、COMPARE_URL_MISMATCH（実行時に比較する封印済みの記録でのみ検出される）、または、「RULE902_NOT_AVAILABLE_FOR_MISMATCH」でも失敗することがあり、その場合はユニットが返却されます。バックグラウンドで実行されるハッシュ証明は、実行時点で月間の最大値に達している場合、「QUOTA_EXCEEDED」で失敗します。CERTIFY_FAILED、REDACTION_FAILED：ハッシュ証明または墨消しを完了できませんでした。リクエストを再試行してください。"
              },
              "message": {
                "type": "string"
              }
            },
            "description": "failedのみ。"
          },
          "failed_at": {
            "type": "string",
            "description": "failedのみ。",
            "format": "date-time"
          },
          "captured_at": {
            "type": "string",
            "description": "ページがキャプチャされた時刻です（completedの行のみ）。墨消しの場合は元のキャプチャの時刻です（「redacted_at」が墨消しの作成時刻です）。",
            "format": "date-time"
          },
          "redacted_at": {
            "type": "string",
            "format": "date-time",
            "description": "墨消しのみ：墨消しが作成された時刻。墨消しの「captured_at」は、作成元キャプチャのキャプチャ時刻です。"
          },
          "compared_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "比較のみ：比較が作成された時刻。「captured_at」にも同じ値が入っています（古いクライアント向けに維持）。「compared_at」を使用してください。"
          },
          "package_url": {
            "type": "string",
            "description": "completedのみ：パッケージZIPの署名付きダウンロードリンクで、最大24時間有効です（「package_url_expires_at」を参照）。新しいリンクが必要な場合は、キャプチャを再度読み取ってください。",
            "format": "uri"
          },
          "package_url_expires_at": {
            "type": "string",
            "description": "completedのみ：「package_url」が機能しなくなる時刻で、このレスポンスから最大24時間後です（サーバーの一時的な認証情報で署名されたリンクは、それより早く機能しなくなる場合があります）。新しいリンクが必要な場合は、キャプチャを再度読み取ってください。",
            "format": "date-time"
          },
          "verification_url": {
            "type": "string",
            "description": "completedのみ：ProofSnapの公開検証ツールへのリンクです。",
            "format": "uri"
          },
          "manifest_hash": {
            "type": "string",
            "description": "completedのみ：manifest.jsonのsha256:<hex>です。",
            "example": "sha256:3f2a..."
          },
          "timestamps": {
            "$ref": "#/components/schemas/Timestamps"
          },
          "c2pa": {
            "type": "object",
            "properties": {
              "included": {
                "type": "boolean"
              },
              "signed_screenshot_sha256": {
                "type": "string",
                "description": "署名付きスクリーンショットのsha256:<hex>です。",
                "nullable": true
              }
            },
            "description": "completedのみ。"
          },
          "file_count": {
            "type": "integer",
            "description": "completedのみ。"
          },
          "size_bytes": {
            "type": "integer",
            "description": "completedのみ。"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "enum": [
                    "consent_gated"
                  ]
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                },
                "final_host": {
                  "type": "string",
                  "nullable": true
                },
                "final_url": {
                  "type": "string",
                  "nullable": true
                },
                "message": {
                  "type": "string"
                },
                "remedy": {
                  "type": "object",
                  "properties": {
                    "option": {
                      "type": "string"
                    },
                    "value": {
                      "type": "boolean"
                    }
                  }
                }
              }
            },
            "description": "completedのみ：キャプチャがページではなくCookie同意ウォールまたはインタースティシャルに到達した場合に返されます。dismiss_consent: trueで再実行してください。"
          },
          "external_archive": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ExternalArchive"
              }
            ],
            "description": "completedのみ。「external_archive」オプションで行われたInternet Archiveへのリクエストです：現在の結果（status）、パッケージに封印された状態（status_at_sealing）、スナップショットのリンクです。リクエストが行われなかった場合は{ requested: false }です。"
          },
          "storage": {
            "$ref": "#/components/schemas/CaptureStorage"
          },
          "private_note": {
            "type": "string",
            "nullable": true,
            "description": "プライベートメモです（PrivateNoteを参照）。キャプチャの作成者にのみ返され、証拠パッケージには含まれません。"
          },
          "legal_hold": {
            "type": "boolean",
            "description": "キャプチャはリーガルホールドの対象です：trueの間は削除されません（PATCH /captures/{capture_id}、action legal_hold）。サブスクリプションが終了し、データを保持するプランなしで30日が経過すると、自動的に解除され、キャプチャは削除されます。"
          },
          "legal_hold_set_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "現在のリーガルホールドが設定された時刻です。リーガルホールドがない場合はnullです。"
          },
          "legal_hold_reason": {
            "type": "string",
            "nullable": true,
            "description": "現在のリーガルホールドとともに保存された理由です。リーガルホールドまたは理由がない場合はnullです。"
          },
          "legal_hold_set_by_email": {
            "type": "string",
            "nullable": true,
            "description": "会社のオーナーのみ、リーガルホールド中の会社のキャプチャについて：リーガルホールドを設定した人のメールアドレスです。"
          },
          "legal_hold_source": {
            "type": "string",
            "nullable": true,
            "description": "現在のリーガルホールドの出所です：\"manual\"（PATCH /captures/{capture_id}）、\"bulk\"（POST /legal-holds）、\"matter:<matter_id>\"（案件のリーガルホールド）、\"derived:<capture_id>\"（作成元のキャプチャがリーガルホールド中であるためにリーガルホールドの対象となる墨消しまたは比較）。リーガルホールドがない場合はnullです。"
          },
          "legal_hold_released_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "最後のリーガルホールドが解除された時刻です（解除後の猶予期間の開始）。リーガルホールド中、または一度も解除されていない場合、およびサブスクリプション終了時の自動解除の後（猶予期間なし）はnullです。"
          },
          "deletion_blocked_until": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "解除後の猶予期間の終了時刻です：それまでキャプチャは完全に削除されません（完全削除のDELETEは「409 CAPTURE_HOLD_GRACE」、ゴミ箱の消去なし、保存期間による削除なし）。ゴミ箱への移動は可能です。サブスクリプション終了後のアカウントと会社の削除は、これを待ちません。猶予期間が進行中でない場合はnullです（リーガルホールドが有効な間も同様で、この場合は期限なしでブロックされます）。"
          },
          "s3_legal_hold": {
            "type": "object",
            "nullable": true,
            "description": "保存されたパッケージオブジェクト（ZIP、アップグレードされたOpenTimestampsの証明、別途保存された複製のすべてのバージョン）のS3 Object Lockのリーガルホールドです。status：on、off、pending（適用中）、failed（サーバーが再試行します）、unsupported（ストレージにObject Lockの設定がありません。キャプチャの記録に対するリーガルホールドは引き続き適用されます）、none（パッケージが保存されていません。例：失敗したキャプチャ）。",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "on",
                  "off",
                  "pending",
                  "failed",
                  "unsupported",
                  "none"
                ]
              },
              "at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "source_held": {
            "type": "boolean",
            "nullable": true,
            "description": "墨消しと比較：作成元のキャプチャがリーガルホールドの対象である場合はtrueです。派生パッケージは元のキャプチャのリーガルホールドに従います：元のキャプチャがリーガルホールド中の間は、墨消しや比較もリーガルホールドの対象となり（legal_hold_source derived:<capture_id>）、そのリーガルホールドを単独で解除することはできません（409 LEGAL_HOLD_SOURCE）。その他のキャプチャではnullです。"
          },
          "import": {
            "$ref": "#/components/schemas/CaptureImport"
          },
          "source": {
            "type": "string",
            "description": "キャプチャの作成方法です：api、schedule、certify-hash、compare、redact、import。GET /captures/{capture_id}が返すのはインポートされたパッケージ（\"import\"）の場合のみで、GET /capturesの行には常に含まれます。"
          },
          "preview_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "キャプチャの小さいプレビュー画像です（スクリーンショットの上部、上限：640 x 800 px、JPEG）。1時間有効の署名付きです。証拠パッケージには含まれず、パッケージの内容を変更しません。パッケージとともに保持、リーガルホールド、削除されます。2026-10-26より前に作成されたキャプチャ、証明、比較ではnullです。墨消しのプレビューは墨消し後のスクリーンショットから作成されます。"
          }
        }
      },
      "Timestamps": {
        "type": "object",
        "properties": {
          "bitcoin_ots": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "description": "manifest.json.otsのBitcoin OpenTimestamps証明の状態です。pending_confirmation：証明はBitcoinブロックを待っています（通常は数時間です。確認はキャプチャの完了から約2時間後に始まり、間隔を広げながら繰り返されます）。verified：Bitcoinブロックがマニフェストハッシュを証明しています（block_height、block_time）。not_present：パッケージにmanifest.json.otsがありません（パッケージの封印時にカレンダーに到達できませんでした）。unconfirmed：確認期間の7日以内に確認が見つかりませんでした。パッケージ内の証明は、OpenTimestampsクライアントで引き続きアップグレードして確認できます（ots upgrade、ots verify）。package_missing：証拠パッケージがストレージになくなったため、証明を確認できなくなりました。manifest_mismatch：保存されたパッケージのmanifest.jsonが、封印時に記録されたマニフェストハッシュと一致しません。このパッケージについてタイムスタンプは確認されません。この2つは最終状態です。パッケージ自体が変更されることはありません。not_checked：自動確認の導入前にキャプチャが完了し、一度も確認されていません。パッケージには、OpenTimestampsクライアントでアップグレードして検証できるmanifest.json.otsが含まれている場合があります。Webhookと作成のレスポンスは完了時に送信されるため、pending_confirmation（カレンダーが失敗した場合は「not_present」）を示します。現在の状態はGET /captures/{capture_id}で読み取ってください。パッケージは証明が保留の状態で封印されます：その時点で、マニフェストハッシュはOpenTimestampsカレンダーに送信済みです。Bitcoinブロック{block_height}（{block_time} UTC）で確認されると、証明は遅くともその時刻までにmanifest.jsonが存在していたことを示します。アップグレードされた証明（upgraded_proof_url）をダウンロードし、manifest.jsonの隣にmanifest.json.upgraded.otsとして配置すると、verify.shとverify.ps1が自動的に確認します。",
                "enum": [
                  "pending_confirmation",
                  "verified",
                  "not_present",
                  "unconfirmed",
                  "package_missing",
                  "manifest_mismatch",
                  "not_checked"
                ]
              },
              "block_height": {
                "type": "integer",
                "nullable": true,
                "description": "証明を裏付けるBitcoinのブロック高です。statusがverifiedの場合に設定されます。"
              },
              "block_time": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "そのBitcoinブロックの時刻です。GET /captures/{capture_id}のみで返され、statusがverifiedの場合に設定されます。"
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "ProofSnapがアンカーを確認した時刻です。GET /captures/{capture_id}のみで返され、statusがverifiedの場合に設定されます。"
              },
              "upgraded_proof_url": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "GET /captures/{capture_id}のみで返されます。アンカーが検証されると、ProofSnapはカレンダーからアップグレードしたOpenTimestampsの証明を保存します（Bitcoinブロックの証明を含むため、カレンダーに接続せずにオフラインで検証できます）。これはその証明の署名付きダウンロードで、「package_url」と同様に最大24時間有効です。新しいリンクが必要な場合は、キャプチャを再度読み取ってください。ない場合はnullです（まだ検証されていない、またはバックグラウンドのバックフィルで後から保存される場合）。封印済みのパッケージが変更されることはありません：ファイルをパッケージのmanifest.jsonの隣にmanifest.json.upgraded.otsとして保存してください。2026-09-29以降に封印されたパッケージは、同梱のスクリプトで検証します（verification/verify.shとverify.ps1は、manifest.json.otsの代わりにこのファイルを使用します）。それより古いパッケージでは`ots verify manifest.json.upgraded.ots -f manifest.json`を実行してください。案件のエクスポートには、captures/<capture_id>.zipの隣にcaptures/<capture_id>.upgraded.otsとして含まれます。パッケージとともに削除されます。"
              }
            }
          },
          "eidas": {
            "$ref": "#/components/schemas/EidasTimestamp"
          }
        }
      },
      "DiffSummary": {
        "type": "object",
        "properties": {
          "text_insertions": {
            "type": "integer",
            "description": "追加された行数です（「text_lines_added」と同じ値。2026-10-14以降、テキストは行数で数えられます。「text_unit」を参照）。それ以前に作成された比較では文字数を数えています。非推奨（2026-10-14）：既存の利用者のために残されており、削除されません。「text_lines_added」を使用してください。",
            "deprecated": true
          },
          "text_deletions": {
            "type": "integer",
            "description": "削除された行数です（「text_lines_removed」と同じ値。2026-10-14以降は行数、それ以前は文字数）。非推奨（2026-10-14）：既存の利用者のために残されており、削除されません。「text_lines_removed」を使用してください。",
            "deprecated": true
          },
          "text_unit": {
            "type": "string",
            "enum": [
              "line"
            ],
            "description": "テキストのカウントの単位です：line（domtextcontent.txtの各行で、改行を含みます）。文字数を数えていた2026-10-14より前の比較には含まれません。"
          },
          "text_lines_added": {
            "type": "integer",
            "description": "追加された行数です（行差分の追加部分におけるAfterテキストの行）。"
          },
          "text_lines_removed": {
            "type": "integer",
            "description": "削除された行数です（行差分の削除部分におけるBeforeテキストの行）。"
          },
          "text_lines_before": {
            "type": "integer",
            "description": "Beforeテキストの行数です。"
          },
          "text_lines_after": {
            "type": "integer",
            "description": "Afterテキストの行数です。"
          },
          "text_changed_percent": {
            "type": "number",
            "description": "100 x（削除行数 + 追加行数）/（Beforeの行数 + Afterの行数）で、小数点以下1桁です。"
          },
          "text_diff_capped": {
            "type": "boolean",
            "description": "行差分が処理の上限に達し、テキストの一部が全体の置換として数えられた場合はtrueです（過大に報告することはあっても、変更を隠すことはありません）。"
          },
          "metadata_changes": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "異なるmetadata.jsonのフィールドごとの{ key, before, after, class }です。対象は次のものに限ります：url、final_url、page_title、http_status、http_headers.content-type、http_headers.server、dns.connected_ip、resolved_ips（ソートした一覧として比較）、tls.issuer、tls.valid_to、およびデバイスプロファイルのフィールド（viewport_width、viewport_height、device_scale_factor、is_mobile、user_agent）。classは次のいずれかです：content（url、final_url、page_title、http_status、http_headers.content-type：変更として数えます）、infrastructure（http_headers.server、dns.connected_ip、resolved_ips、tls.issuer、tls.valid_to：どのサーバーがページを配信したかを示し、報告のみ）、device_profile（キャプチャがページをどのようにレンダリングしたかを示し、報告のみ）。2026-10-10より前に作成された比較にclassはありません。"
          },
          "meta_content": {
            "type": "integer",
            "description": "classがcontentである異なるメタデータフィールドです。changedの判定に数えられます。"
          },
          "meta_infra": {
            "type": "integer",
            "description": "classがinfrastructureである異なるメタデータフィールドです（サーバーソフトウェア、接続先IP、解決されたIP、TLSの発行者と有効期限）。コンテンツ配信ネットワークはローテーションするアドレスから応答するため、変更のないページでも2回の読み込みでここが異なることがあります。情報として報告され、changedの判定には数えられません。"
          },
          "meta_device_profile": {
            "type": "integer",
            "description": "異なるデバイスプロファイルのフィールドです（ビューポート、スケール、モバイルエミュレーション、ユーザーエージェント）。情報として報告され、changedの判定には数えられません。"
          },
          "image_changes": {
            "type": "object",
            "description": "各元キャプチャが封印した画像インベントリ（image_inventory.json）に基づく画像比較です。statusはran、または、「not_run」です（reason：source_without_inventory（キャプチャがインベントリを記録するようになる前に作成された元キャプチャ）、source_inventory_failed、または、source_inventory_unreadable）。代わりに他のものが使用されることはありません。画像ごとの完全な結果は、パッケージの「image_changes.json」にあります。",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "ran",
                  "not_run"
                ]
              },
              "reason": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "source_without_inventory",
                  "source_inventory_failed",
                  "source_inventory_unreadable",
                  null
                ],
                "description": "画像が比較されなかった理由です：source_without_inventory（キャプチャが画像インベントリを記録するようになる前に作成された元キャプチャ。新しいキャプチャでは記録されます）、source_inventory_failed（そのキャプチャの作成時にインベントリを記録できなかった）、または、source_inventory_unreadable。比較が実行された場合はnullです。"
              },
              "images_changed": {
                "type": "integer",
                "nullable": true,
                "description": "置換、追加、または削除されたファーストパーティ画像（ページ自身の登録可能ドメインから配信されるもの、または2026-10-14以降、ページがog:imageやアイコンとして自身のものと宣言したドメイン、もしくは両方のキャプチャでページの画像の大半を配信するドメインから配信されるもの：「image_changes.json site_image_hosts」）で、changedの画像部分です。移動した画像は含まれません。比較が実行されなかった場合はnullです。非推奨（2026-10-14）：既存の利用者のために残されており、削除されません。「site_images_changed」を使用してください。",
                "deprecated": true
              },
              "first_party": {
                "$ref": "#/components/schemas/ImageChangeCounts"
              },
              "third_party": {
                "$ref": "#/components/schemas/ImageChangeCounts"
              },
              "tracking_pixel": {
                "$ref": "#/components/schemas/ImageChangeCounts"
              },
              "inventories_truncated": {
                "type": "boolean",
                "description": "元のインベントリがエントリの上限に達した場合はtrueです。「inventory_cutoff」を参照してください。"
              },
              "site_images_changed": {
                "type": "integer",
                "description": "「images_changed」と同じです（数えられます）。"
              },
              "other_images_changed": {
                "type": "integer",
                "description": "置換、削除、または追加された他ドメインの画像とトラッキングピクセルです（数えられません）。"
              },
              "site_image_hosts": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "ページのドメインに加えてサイト自身のものとして数えられた登録可能ドメインです（「image_changes.json」の「site_image_hosts」）。"
              },
              "inventory_cutoff": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "before_only_index_limit": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Beforeにのみ見つかった画像は、Beforeインベントリ内のインデックスがこの値より小さい場合に判定可能（removed）です。null：上限なし（Afterインベントリは完全です）。"
                  },
                  "after_only_index_limit": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Afterにのみ見つかった画像は、Afterインベントリ内のインデックスがこの値より小さい場合に判定可能（added）です。null：上限なし（Beforeインベントリは完全です）。"
                  }
                },
                "description": "2026-10-14の2回目の監査（image_changes.json algorithm 3）以降はオブジェクトで、文書内のインデックスで判定します：もう一方のインベントリがエントリの上限に達した場合、片側にのみ見つかった画像が判定可能なのは、インデックスがもう一方のインベントリのエントリ数からマージン（10エントリとそのエントリ数の5パーセントのうち大きい方）を引いた値より小さい場合のみです。それ以外の場合はundeterminedです（undetermined_reason beyond_inventory_limit）。切り詰められたインベントリがない場合はnullです。それ以前に作成された比較には数値（以前の規則における文書内の相対位置）が含まれます。"
              }
            }
          },
          "changed": {
            "type": "boolean",
            "nullable": true,
            "description": "表示テキストが異なる、contentのメタデータフィールドが異なる（meta_content）、またはファーストパーティ画像が置換、削除、追加された（image_changes.images_changed）場合はtrueです。インフラストラクチャとデバイスプロファイルのフィールド、移動した画像（同じバイトが別のアドレスにあるもの）、サードパーティ画像、トラッキングピクセルは報告されますが、この値を設定しません。数えられる変更が確実にはないものの、テキストまたは画像の結果が未確定である場合（異なる方法でレンダリングされたキャプチャ、allow_profile_mismatch）はnull（2026-10-14以降）です。パッケージには、この規則が「comparison_method.json counted_as_change」に記載されます。非推奨（2026-10-14）：既存の利用者のために残されており、削除されません。verdict（changed | unchanged | undetermined）と、種類ごとの「text_verdict、images_verdict、metadata_verdict」を使用してください。",
            "deprecated": true
          },
          "text_verdict": {
            "type": "string",
            "enum": [
              "changed",
              "unchanged",
              "undetermined"
            ],
            "description": "2つのキャプチャが異なるデバイスプロファイルまたはキャプチャ設定でレンダリングされた場合（allow_profile_mismatch）はundeterminedです。"
          },
          "images_verdict": {
            "type": "string",
            "enum": [
              "changed",
              "unchanged",
              "undetermined",
              "not_run"
            ]
          },
          "metadata_verdict": {
            "type": "string",
            "enum": [
              "changed",
              "unchanged"
            ],
            "description": "contentクラスのメタデータフィールド（アドレス、最終アドレス、タイトル、HTTPステータス、コンテンツタイプ）から判定します。"
          },
          "verdict": {
            "type": "string",
            "enum": [
              "changed",
              "unchanged",
              "undetermined"
            ],
            "description": "全体の結果を語で示します：changedがtrueの場合はchanged、changedがnullの場合はundeterminedです。"
          },
          "undetermined_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "render_profile_mismatch",
              "capture_settings_mismatch",
              null
            ]
          },
          "text_changes": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "GETのみ：変更されたテキストチャンク（最大60個）です。"
          },
          "change_regions": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "GETのみ：スクリーンショット上に位置付けられたテキスト変更（最大60個、元キャプチャの「text_layout.json」に基づく）で、スクリーンショットのピクセル単位です。各変更には、「counterpart_y_px」（もう一方のスクリーンショット上の垂直位置で、最も近い変更のないテキストブロックから引き継がれます）と「report_region」（evidence.pdfで示される変更箇所の番号で、最大10か所、またはnull）が、「change_regions.json」と同様に含まれます。"
          },
          "change_regions_info": {
            "type": "object",
            "nullable": true
          },
          "order_reversed": {
            "type": "boolean",
            "description": "GETのみ：「capture_id_1」（Before）として指定されたキャプチャが、「capture_id_2」（After）として指定されたキャプチャより後にキャプチャされた場合はtrueです（compare.jsonの「order_reversed」と同じ）。比較は指定された順序を維持し、レポートとダッシュボードにその旨が示されます。"
          },
          "render_profile_mismatch": {
            "type": "boolean",
            "description": "GETのみ：2つのキャプチャは異なるデバイスプロファイルでレンダリングされました（compare.json）。"
          },
          "capture_settings_mismatch": {
            "type": "boolean",
            "description": "GETのみ：2つのキャプチャは異なるキャプチャ設定で作成されました（compare.json）。"
          },
          "capture_settings_differing": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "setting": {
                  "type": "string"
                },
                "before": {},
                "after": {}
              }
            },
            "description": "GETのみ：異なる設定です。{ setting, before, after }。"
          },
          "profile_mismatch_allowed": {
            "type": "boolean",
            "description": "GETのみ：異なる方法でレンダリングされたキャプチャについて、「allow_profile_mismatch」を指定して比較を行いました。非推奨（2026-10-14）：既存の利用者のために残されており、削除されません。「render_profile_mismatch」と「capture_settings_mismatch」を使用してください。",
            "deprecated": true
          },
          "url_mismatch": {
            "type": "boolean",
            "description": "GETのみ：2つのキャプチャに共通のアドレスがありません（「allow_url_mismatch」を指定して作成）。"
          }
        },
        "description": "比較の概要。"
      },
      "ImageChangeCounts": {
        "type": "object",
        "properties": {
          "unchanged": {
            "type": "integer"
          },
          "replaced": {
            "type": "integer"
          },
          "moved": {
            "type": "integer"
          },
          "removed": {
            "type": "integer"
          },
          "added": {
            "type": "integer"
          },
          "undetermined": {
            "type": "integer"
          },
          "alt_changed": {
            "type": "integer"
          },
          "position_changed": {
            "type": "integer"
          },
          "undetermined_same_error": {
            "type": "integer",
            "description": "両側が同じHTTPエラーステータス（例：両方のキャプチャで「404」）を返した未確定のペアです。undeterminedに含まれ、レポートで数えられますが、一覧には記載されません。"
          },
          "occurrences": {
            "type": "integer",
            "description": "このパーティのすべての結果です：ページ上の出現回数です。"
          },
          "distinct": {
            "type": "object",
            "description": "結果に含まれる異なる画像の数です（合計とカテゴリごと。複数回表示された画像は1回と数えます）：各結果が表すのは、After側のハッシュ（SHA-256）で、After側がない場合はBefore側のハッシュ、ハッシュ（SHA-256）を持たない場合はその側のアドレスです。",
            "properties": {
              "total": {
                "type": "integer"
              },
              "unchanged": {
                "type": "integer"
              },
              "replaced": {
                "type": "integer"
              },
              "moved": {
                "type": "integer"
              },
              "removed": {
                "type": "integer"
              },
              "added": {
                "type": "integer"
              },
              "undetermined": {
                "type": "integer"
              }
            }
          }
        },
        "description": "カテゴリごとのカウントで、ページ上の出現回数として数えます（1つの画像が3回表示された場合は3回と数えます）：unchanged、replaced（同じアドレスで異なるバイト）、moved（異なるアドレスで同じバイト。報告されますが、変更としては数えられません）、removed、added、undetermined（両側ともハッシュ（SHA-256）のない画像で、removedやaddedとしては決して数えられません）。さらに、代替テキストまたはページの画像内の位置が変わったペアの画像、両側で同じHTTPエラーの未確定のペア、および異なる画像の数も含まれます。"
      },
      "BatchRequest": {
        "type": "object",
        "required": [
          "urls"
        ],
        "properties": {
          "urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri",
              "maxLength": 2048
            },
            "minItems": 2,
            "maxItems": 50,
            "description": "2～50個のURLで、それぞれCaptureRequest.urlと同様に検証されます。バッチの受付時にホスト名のDNS確認は行われません。DNSまたはアドレスの確認に失敗したURLは、後でstatus failed（およびcapture.failed）で失敗します。"
          },
          "options": {
            "$ref": "#/components/schemas/CaptureOptions"
          },
          "private_note": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PrivateNote"
              }
            ],
            "description": "バッチのすべてのキャプチャに保存される1つのプライベートメモです。キャプチャのプライベートメモ（例：\"mobile capture\"）で、プレーンテキストです（文字数の上限：200。PlainTextの規則）。キャプチャの記録にのみ保存され、封印された証拠パッケージには含まれません（ZIP、PDF、マニフェスト、いずれのハッシュにも含まれません）。証拠としての価値はないため、証拠に影響を与えずに、後からPATCH /v1/captures/{capture_id}で変更またはクリアできます。読み取れるのはキャプチャの作成者のみです。メモが不要な場合は省略するか、nullまたは空文字列を送信してください。"
          }
        }
      },
      "BatchResult": {
        "type": "object",
        "properties": {
          "batch_id": {
            "type": "string",
            "example": "batch_a1B2c3D4e5F6g7H8"
          },
          "count": {
            "type": "integer"
          },
          "captures": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "capture_id": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "description": "キャプチャを開始できなかった場合はfailedです。",
                  "enum": [
                    "processing",
                    "failed"
                  ]
                }
              }
            }
          },
          "not_admitted": {
            "type": "array",
            "description": "アカウントの同時実行の上限に達した場合のみ返されます：開始されなかったURLを、送信された順に示します。費用は発生しません（レート制限のユニットも月間のユニットも消費しません）。後で再度送信してください。すべてのURLが開始された場合は含まれません。",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string"
                },
                "code": {
                  "type": "string",
                  "description": "URLが開始されなかった理由です。",
                  "enum": [
                    "CONCURRENT_CAPTURE_LIMIT"
                  ]
                }
              }
            }
          },
          "in_flight_limit": {
            "type": "integer",
            "description": "「not_admitted」と一緒にのみ返されます：アカウントで同時に実行できるキャプチャの数です（developer 10、startup 25、growth 100、legal_solo、legal_seats 25、custom 200、website_archive 25、sandbox 5）。"
          },
          "warnings": {
            "$ref": "#/components/schemas/Rule902DisabledWarnings"
          }
        }
      },
      "VerifyResult": {
        "type": "object",
        "properties": {
          "verdict": {
            "type": "string",
            "nullable": true,
            "description": "match：署名が有効で、記載されたすべてのファイルが存在し、記録されたハッシュ（SHA-256）と一致します。modified：署名が無効、またはファイルが欠落または変更されています。invalid：パッケージを確認できませんでした。nullになるのは、今回再確認されなかったインポート済みパッケージの場合のみです（`rechecked: false`で、`reason`とインポート時に記録された検証が`stored_verification`に含まれます）。",
            "enum": [
              "match",
              "modified",
              "invalid",
              null
            ]
          },
          "reason": {
            "type": "string",
            "description": "invalidのみ。`rechecked: false`のインポート済みパッケージの場合は、再確認されなかった理由です（too_large_for_synchronous_check、time_budget、storage_error）。"
          },
          "capture_id": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "s3"
            ]
          },
          "checks": {
            "type": "object",
            "properties": {
              "manifest_signature": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "valid",
                      "invalid"
                    ]
                  },
                  "algorithm": {
                    "type": "string",
                    "enum": [
                      "RSA-4096"
                    ]
                  }
                }
              },
              "declared_files": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "all_match",
                      "mismatch"
                    ]
                  },
                  "mismatched": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "missing": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "bitcoin_ots": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "manifest.json.otsの有無のみを示します。ここでは証明は確認されません。",
                    "enum": [
                      "present",
                      "not_present"
                    ]
                  }
                }
              },
              "eidas_disig": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "manifest.json.tsrの有無を示します。トークン自体はchecks.eidasで確認されます。missing：manifest.jsonに「eidas_requested」が記録されています（パッケージはトークン付きで発行されました）が、manifest.json.tsrがパッケージにありません。",
                    "enum": [
                      "present",
                      "missing"
                    ]
                  }
                },
                "nullable": true,
                "description": "manifest.json.tsrがなく、manifest.jsonに「eidas_requested」が記録されていない場合はnullです。"
              },
              "proofsnap_issuance": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "issued_by_proofsnap：マニフェストハッシュがProofSnapの発行台帳にあります。unverified：発行台帳にありません（発行台帳の開始前に発行されたパッケージは含まれません）。unknown：照会に失敗しました。",
                    "enum": [
                      "issued_by_proofsnap",
                      "unverified",
                      "unknown"
                    ]
                  },
                  "manifest_sha256": {
                    "type": "string"
                  },
                  "issued_at": {
                    "type": "string",
                    "nullable": true,
                    "format": "date-time"
                  },
                  "type": {
                    "type": "string"
                  }
                }
              },
              "eidas": {
                "type": "object",
                "nullable": true,
                "description": "manifest.json.tsrがなく、manifest.jsonに「eidas_requested」が記録されていない場合はnullです。リクエストに応じてProofSnapが保存済みパッケージから確認したeIDASタイムスタンプトークンです。これはProofSnapが行う確認です。トークンを独自に検証する方法はnoteフィールドに記載されています。",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "verified",
                      "verified_revocation_unknown",
                      "failed",
                      "unavailable",
                      "missing"
                    ],
                    "description": "missing：manifest.jsonに「eidas_requested: true」が記録されているため、パッケージは適格タイムスタンプ付きで発行されましたが、manifest.json.tsrがパッケージにありません（この場合、レスポンスには「EIDAS_TOKEN_MISSING」の警告が含まれます）。verified：すべてのチェックに合格し、発行時に記録されたTSA証明書のステータスが判明しています（good、または鍵の危殆化以外の理由でトークンの時刻より後に取り消し）。verified_revocation_unknown：実行されたすべてのチェックに合格しましたが、記録されたデータからTSA証明書のステータスを確定できませんでした（revocation.status unknown、または、not_checked）。failed：少なくとも1つのチェックが失敗しました。failuresを参照してください（この場合、レスポンスには「EIDAS_TOKEN_FAILED」の警告が含まれます）。unavailable：トークンの判定がありません（reason：未設定、timeout、input_rejected（サイズ超過の検証データなど、検証ツールが入力を拒否した場合）、inconclusive）。トークンについて何かを示すものではありません。"
                  },
                  "reason": {
                    "type": "string",
                    "description": "unavailableのみ：timeout、input_rejected、inconclusive、または短い説明です。"
                  },
                  "checked_by": {
                    "type": "string",
                    "example": "ProofSnap API on request"
                  },
                  "checked_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "gen_time": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "トークン内の時刻です（TSTInfo genTime）。"
                  },
                  "tsa_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "署名者の証明書から取得します（コモンネームと組織）。デフォルト値が使用されることはありません。"
                  },
                  "serial_number": {
                    "type": "string",
                    "nullable": true
                  },
                  "policy_oid": {
                    "type": "string",
                    "nullable": true
                  },
                  "hash_algorithm": {
                    "type": "string",
                    "nullable": true
                  },
                  "signature_algorithm": {
                    "type": "string"
                  },
                  "signing_certificate_form": {
                    "type": "string",
                    "enum": [
                      "ESSCertIDv2",
                      "ESSCertID"
                    ]
                  },
                  "signer_certificate": {
                    "type": "object",
                    "nullable": true,
                    "properties": {
                      "subject": {
                        "type": "string"
                      },
                      "issuer": {
                        "type": "string"
                      },
                      "serial_number": {
                        "type": "string"
                      },
                      "sha256": {
                        "type": "string"
                      },
                      "not_before": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "not_after": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  },
                  "root": {
                    "type": "object",
                    "properties": {
                      "label": {
                        "type": "string",
                        "example": "CA Disig QCA4"
                      },
                      "sha256": {
                        "type": "string"
                      }
                    }
                  },
                  "chain_checked_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "チェーンの確認の基準時刻です：トークンのgenTimeであるため、トークンの発行後に期限切れになった証明書でも失敗しません。"
                  },
                  "chain": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "subject": {
                          "type": "string"
                        },
                        "sha256": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "revocation": {
                    "type": "object",
                    "description": "発行時に記録されたデータに基づくTSA証明書のステータスです（basis recorded_at_issuance）。署名によって検証され、genTime時点で有効であったことが求められます。ライブでは取得しません。",
                    "properties": {
                      "status": {
                        "type": "string",
                        "enum": [
                          "good",
                          "revoked",
                          "revoked_after_gen_time",
                          "unknown",
                          "not_checked"
                        ],
                        "description": "revoked_after_gen_time：鍵の危殆化以外の理由でトークンの時刻より後に取り消されました（トークンはverifiedのままです）。not_checked：失効データが記録も確認もされていません。"
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "ocsp",
                          "crl"
                        ],
                        "nullable": true
                      },
                      "basis": {
                        "type": "string",
                        "enum": [
                          "recorded_at_issuance"
                        ]
                      },
                      "produced_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "this_update": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "next_update": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                      },
                      "reason": {
                        "type": "string",
                        "description": "ステータスが不明である理由です。"
                      }
                    }
                  },
                  "checks": {
                    "type": "object",
                    "description": "各チェックの結果です：passed、failed、not_applicable（nonce：保存されたトークンには記録なし）、unknown（使用可能なデータのない失効確認）、not_checked（以前の失敗によりチェックが停止）。",
                    "properties": {
                      "response_status": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "message_imprint": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "nonce": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "content_type": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "message_digest": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "signature": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "signing_certificate": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "timestamping_eku": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "chain": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      },
                      "revocation": {
                        "type": "string",
                        "enum": [
                          "passed",
                          "failed",
                          "not_applicable",
                          "unknown",
                          "not_checked"
                        ]
                      }
                    }
                  },
                  "failures": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "check": {
                          "type": "string"
                        },
                        "reason": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "note": {
                    "type": "string"
                  },
                  "detail": {
                    "type": "string",
                    "nullable": true,
                    "description": "「input_rejected」のみ：検証ツールが拒否した内容です。"
                  }
                }
              }
            },
            "description": "verdictがinvalidの場合は含まれません。判定は「manifest_signature」と「declared_files」のみに依存します。eidasはその隣に報告され、失敗した場合はwarningsにも報告されます。"
          },
          "warnings": {
            "type": "array",
            "description": "判定以外で注意が必要な場合のみ含まれます。EIDAS_TOKEN_FAILED：manifest.json.tsrがchecks.eidasのチェックに合格しませんでした。EIDAS_TOKEN_MISSING：manifest.jsonに「eidas_requested」が記録されていますが、manifest.json.tsrがパッケージにありません。",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "enum": [
                    "EIDAS_TOKEN_FAILED",
                    "EIDAS_TOKEN_MISSING"
                  ]
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ScheduleRequest": {
        "type": "object",
        "required": [
          "url",
          "mode"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "キャプチャするページです。CaptureRequest.urlと同様に検証されます。",
            "format": "uri",
            "maxLength": 2048
          },
          "mode": {
            "type": "string",
            "description": "interval：「interval_seconds」ごとに実行します。cron：「cron_expr」に従って実行します。on_change：「interval_seconds」ごとにページを確認し、テキストが変更された場合のみキャプチャします。",
            "enum": [
              "interval",
              "cron",
              "on_change"
            ]
          },
          "interval_seconds": {
            "type": "integer",
            "description": "intervalと「on_change」で必須です。プランの最小値以上である必要があります（developer、startup、growth、custom、legal_solo、legal_seats：300。website_archive：86400）。満たさない場合は「400 INTERVAL_TOO_SHORT」を返します。",
            "minimum": 300
          },
          "cron_expr": {
            "type": "string",
            "description": "cronで必須です（文字数の上限：200）。解析できない式は「400 INVALID_CRON」を返します。連続する2回の実行の間隔がプランの最小値より短い場合は「400 INTERVAL_TOO_SHORT」を返します。",
            "maxLength": 200,
            "example": "0 9 * * 1-5"
          },
          "timezone": {
            "type": "string",
            "description": "「cron_expr」の評価に使用するIANAタイムゾーンです。デフォルトはUTCです。",
            "example": "Europe/Berlin"
          },
          "webhook_url": {
            "type": "string",
            "description": "https URLです。intervalとcronの実行はcapture.completedまたはcapture.failedを送信し、「on_change」は「monitor.change_detected」を送信します。URLはhttpsである必要があり、プライベート、ループバック、リンクローカル、キャリアグレードNAT、クラウドメタデータのアドレスを指すことはできません（キャプチャURLと同じ規則です。違反すると「422 SSRF_BLOCKED」）。空または空白のみの値はWebhookなしを意味します。スケジュールが持つ「webhook_url」はトップレベルの1つのみです：「options.webhook_url」は保存されません（トップレベルの「webhook_url」が送信されない場合は、トップレベルのものとして使用されます）。そのため、「on_change」のスケジュールがcapture.completedも送信することはありません。APIキーが必要です：WebhookはキーのWebhook署名シークレットで署名されるため、ダッシュボードセッションから送信すると「400 WEBHOOK_REQUIRES_API_KEY」で拒否されます。",
            "format": "uri"
          },
          "js_render": {
            "type": "boolean",
            "description": "「on_change」のみ：単純なHTTP取得ではなく、ブラウザの完全なレンダリングでページを確認します（JavaScriptが必要なページ向け）。",
            "default": false
          },
          "options": {
            "$ref": "#/components/schemas/CaptureOptions"
          },
          "max_capture_age_seconds": {
            "type": "integer",
            "nullable": true,
            "minimum": 86400,
            "maximum": 34560000,
            "description": "「on_change」のみ：スケジュールの最新のキャプチャがこの値より古い場合、ページが変更されていなくてもフルキャプチャを行います（capture.completedを送信します）。少なくともN日ごとのコピーを求める規則に対応するためのものです（例：90日の場合は7776000）。日数の範囲：1～400。「interval_seconds」より長い値にする必要があります。null（デフォルト）の場合は変更時にのみキャプチャします。PATCHでnullを指定すると削除されます。"
          },
          "alert_on": {
            "type": "string",
            "enum": [
              "any",
              "text"
            ],
            "nullable": true,
            "description": "「on_change」のみ（2026-10-14）：検出したどの変更で「monitor.change_detected」を送信するかを指定します。any（デフォルト、以前の動作）：すべての変更キャプチャ。text：前回のキャプチャとの比較で表示テキストの変更が検出された場合のみ（diff_summary.text_verdict changed）。比較でテキストが変更されていない、または判定できないとされた変更キャプチャでは何も送信されません（キャプチャは引き続き実行および請求され、サブスクリプションにcapture.completedを送信します）。比較結果がない場合（ベースラインがない、比較に失敗した）は通知します。他のモードまたは値の場合は「400 MALFORMED_REQUEST」を返します。intervalとcronのスケジュールではnullです。"
          },
          "email_on_change": {
            "type": "boolean",
            "nullable": true,
            "description": "「on_change」のみ（2026-10-26）：変更を通知するとき（「alert_on」を参照）に、アカウントの確認済みアドレスにメールを送信します。デフォルトは無効です。変更をユーザーに自ら伝えることができない、ProofSnap MCPサーバーを通じて接続されたAIアプリが作成したスケジュールでは有効です。テストモードの変更、または比較でページが変更されていないとされた場合は送信されません。同時に待機している変更は1通のメールにまとめて送信され、変更通知メールは1日最大20通です。falseまたはnullはどのモードでも受け付けます。他のモードでのtrue、またはブール値以外の値は「400 MALFORMED_REQUEST」になります。"
          }
        },
        "example": {
          "url": "https://example.com/terms",
          "mode": "on_change",
          "interval_seconds": 3600,
          "webhook_url": "https://your-app.example/webhooks/proofsnap"
        }
      },
      "Schedule": {
        "type": "object",
        "properties": {
          "schedule_id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "interval",
              "cron",
              "on_change"
            ]
          },
          "interval_seconds": {
            "type": "integer",
            "nullable": true
          },
          "cron_expr": {
            "type": "string",
            "nullable": true
          },
          "timezone": {
            "type": "string",
            "nullable": true
          },
          "webhook_url": {
            "type": "string",
            "nullable": true,
            "description": "スケジュールのWebhookです（「options.webhook_url」に保持していた古いスケジュールでは、その値がここに表示され、optionsに含まれることはありません）。APIキーが必要です：WebhookはキーのWebhook署名シークレットで署名されるため、ダッシュボードセッションから送信すると「400 WEBHOOK_REQUIRES_API_KEY」で拒否されます。"
          },
          "options": {
            "type": "object",
            "description": "デフォルトが適用されたキャプチャオプションです。"
          },
          "js_render": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ]
          },
          "next_run_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_run_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "last_capture_id": {
            "type": "string",
            "nullable": true
          },
          "run_count": {
            "type": "integer"
          },
          "consecutive_failures": {
            "type": "integer"
          },
          "pause_reason": {
            "type": "string",
            "description": "スケジュールが自動的に一時停止された理由です：max_failures（5回連続の実行失敗）、no_billing、plan_downgrade（プランの上限、またはArchive onlyプラン）、invalid_cron、または、key_revoked。有効な場合、またはユーザーが一時停止した場合はnullです。",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "max_capture_age_seconds": {
            "type": "integer",
            "nullable": true
          },
          "current_capture_id": {
            "type": "string",
            "nullable": true,
            "description": "スケジュールの最新の完了済みキャプチャです（現在のバージョン。「last_capture_id」は最後に実行されたものです）。"
          },
          "current_captured_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "alert_on": {
            "type": "string",
            "enum": [
              "any",
              "text"
            ],
            "nullable": true,
            "description": "on_change：anyまたはtext（このオプションの導入前に作成されたスケジュールではany）。intervalとcronではnullです。"
          },
          "email_on_change": {
            "type": "boolean",
            "nullable": true,
            "description": "on_change：通知されたすべての変更をアカウントにメールで送信するかどうかを示します。intervalとcronではnullです。"
          },
          "warnings": {
            "$ref": "#/components/schemas/Rule902DisabledWarnings"
          }
        }
      },
      "Matter": {
        "type": "object",
        "properties": {
          "matter_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "client": {
            "type": "string",
            "nullable": true
          },
          "case_number": {
            "type": "string",
            "nullable": true
          },
          "opposing_party": {
            "type": "string",
            "nullable": true
          },
          "jurisdiction": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "archived",
              "sealed"
            ]
          },
          "sealed": {
            "type": "boolean"
          },
          "capture_count": {
            "type": "integer"
          },
          "custody_count": {
            "type": "integer",
            "description": "証拠管理ログのエントリ数です。"
          },
          "custody_head_hash": {
            "type": "string",
            "description": "最新の証拠管理ログエントリのsha256:<hex>です。",
            "nullable": true
          },
          "seal": {
            "type": "object",
            "nullable": true,
            "description": "封印されるまではnullです。",
            "allOf": [
              {
                "$ref": "#/components/schemas/MatterSeal"
              }
            ]
          },
          "member_uids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_by": {
            "type": "string",
            "description": "オーナー。",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "read_only": {
            "type": "boolean",
            "description": "終了した会社、または会社アーカイブとして保持されている会社の案件に含まれます（true）：開く、エクスポート、共有の取り消しのみ実行できます。"
          },
          "legal_hold": {
            "type": "boolean",
            "description": "案件のリーガルホールドが有効です（PATCH { legal_hold }）。"
          },
          "legal_hold_set_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "MatterSeal": {
        "type": "object",
        "properties": {
          "root_hash": {
            "type": "string",
            "description": "sha256:<hex>：封印されてOpenTimestampsに送信された証拠管理ログの先頭です。"
          },
          "ots": {
            "type": "string",
            "description": "OpenTimestampsの証明（16進数）です。"
          },
          "ots_pending": {
            "type": "boolean"
          },
          "eidas": {
            "type": "object",
            "properties": {
              "tsr_base64": {
                "type": "string",
                "nullable": true
              },
              "serial": {
                "type": "string",
                "nullable": true
              },
              "issued_at": {
                "type": "string",
                "nullable": true
              },
              "ltv": {
                "type": "boolean"
              },
              "verification_status": {
                "type": "string",
                "enum": [
                  "verified"
                ],
                "description": "トークンは封印時にProofSnapのチェックに合格しました（共通の検証ツールで、キャプチャのトークンと同じチェックです）。"
              },
              "revocation_status": {
                "type": "string",
                "enum": [
                  "good",
                  "revoked_after_gen_time",
                  "unknown",
                  "not_checked"
                ],
                "description": "封印時に収集したOCSPレスポンスまたはCRLから確定したTSA証明書のステータスです。"
              },
              "validation": {
                "type": "object",
                "nullable": true,
                "description": "トークンのオフライン確認のために封印時に記録された「eidas_validation.json」の内容です：tsaCertChain、rootCaPem、ocspResponse、crlResponse（大きすぎる場合は削除され、omittedに名前が記載されます）、ocspUrl、ocspFetchedAt、ocspStatus、crlUrl、verification。2026-10-01より前の封印には含まれません。",
                "additionalProperties": true
              }
            },
            "nullable": true,
            "description": "デプロイ環境にeIDASが設定され、呼び出し元が本番で、トークンが取得されてチェックに合格した場合の、同じハッシュに対するeIDASタイムスタンプです。それ以外の場合はnullです（「eidas_status」を参照）。"
          },
          "sealed_by": {
            "type": "string",
            "nullable": true
          },
          "sealed_at": {
            "type": "string",
            "format": "date-time"
          },
          "eidas_status": {
            "type": "string",
            "enum": [
              "confirmed",
              "not_obtained",
              "not_configured"
            ],
            "description": "2026-10-01より前の封印には含まれません。not_obtained：封印にはOpenTimestampsのアンカーのみが含まれます（eidas_reason token_refused、unavailable、または、test_key）。eIDASスタンプのタイムアウトで封印が作成されることはありません：その場合、リクエストは代わりに「503 EIDAS_SEAL_RETRY」を返します。"
          },
          "eidas_reason": {
            "type": "string",
            "enum": [
              "token_refused",
              "unavailable",
              "test_key",
              "account_limit"
            ],
            "description": "「not_obtained」のみ。test_key：テストの呼び出し元（テストAPIキーまたはサンドボックスセッション）が封印したため、eIDASタイムスタンプは要求されませんでした。account_limit：アカウントに支払い済みの請求書がまだなく、eIDASの上限（UTCの1日あたり20回、UTCの1か月あたり50回）に達しました。"
          }
        },
        "nullable": true
      },
      "CustodyEntry": {
        "type": "object",
        "properties": {
          "seq": {
            "type": "integer"
          },
          "ts": {
            "type": "string",
            "format": "date-time"
          },
          "actor_uid": {
            "type": "string",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "actor_role": {
            "type": "string",
            "enum": [
              "api",
              "user"
            ],
            "nullable": true
          },
          "action": {
            "type": "string",
            "description": "例：matter.created、matter.updated、capture.added、capture.removed、capture.legal_hold_placed、capture.legal_hold_released、member.added、member.removed、package.imported（「matter_id」を指定してインポートされた証拠パッケージ。targetはキャプチャIDです）。"
          },
          "target": {
            "type": "string",
            "nullable": true
          },
          "prev_hash": {
            "type": "string"
          },
          "entry_hash": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "description": "package.importedのみ：manifest_sha256、zip_sha256、package_kind、verdict、levels。エントリとともに保存されますが、「entry_hash」の対象外です。",
            "additionalProperties": true
          }
        },
        "description": "ハッシュチェーンの1つのリンクです。「entry_hash」はseq、ts、actor、action、target、「prev_hash」を対象とします。"
      },
      "MatterCapture": {
        "type": "object",
        "properties": {
          "capture_id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          },
          "captured_at": {
            "type": "string",
            "nullable": true
          },
          "file_count": {
            "type": "integer",
            "nullable": true
          },
          "manifest_hash": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "AuditEntry": {
        "type": "object",
        "properties": {
          "ts": {
            "type": "string"
          },
          "actor_uid": {
            "type": "string",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "actor_role": {
            "type": "string",
            "nullable": true
          },
          "action": {
            "type": "string",
            "description": "例：capture.downloaded、export.generated、share.created、share.revoked。"
          },
          "target": {
            "type": "string",
            "nullable": true
          },
          "source_ip": {
            "type": "string",
            "nullable": true,
            "description": "案件オーナーのみ（メンバーには含まれません）。"
          },
          "user_agent": {
            "type": "string",
            "nullable": true,
            "description": "案件オーナーのみ（メンバーには含まれません）。"
          }
        },
        "description": "アクセスイベントです。ハッシュチェーンには含まれません。"
      },
      "CertifyResult": {
        "type": "object",
        "properties": {
          "certify_id": {
            "type": "string",
            "example": "cert_a1B2c3D4e5F6g7H8"
          },
          "status": {
            "type": "string",
            "enum": [
              "completed"
            ]
          },
          "hash_sha256": {
            "type": "string",
            "description": "単一の証明書のみ。"
          },
          "combined": {
            "type": "boolean",
            "description": "結合された証明書のみ。"
          },
          "file_count": {
            "type": "integer",
            "description": "結合された証明書のみ。"
          },
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "description": "送信したラベルです。",
                  "nullable": true
                },
                "sha256": {
                  "type": "string"
                }
              }
            },
            "description": "結合された証明書のみ。"
          },
          "label": {
            "type": "string",
            "description": "指定したラベル、または結合された証明書の場合は\"N files\"です。",
            "nullable": true
          },
          "certified_at": {
            "type": "string",
            "format": "date-time"
          },
          "timestamps": {
            "type": "object",
            "properties": {
              "bitcoin_ots": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "pending_confirmation",
                      "not_present"
                    ],
                    "description": "pending_confirmation：manifest.json.otsがパッケージに含まれており、Bitcoinブロックを待っています。not_present：OpenTimestampsカレンダーに到達できず、パッケージにmanifest.json.otsがなく、manifest.jsonにも記載されていません。"
                  },
                  "block_height": {
                    "type": "integer",
                    "nullable": true
                  }
                }
              },
              "eidas": {
                "$ref": "#/components/schemas/EidasTimestamp"
              }
            }
          },
          "package_url": {
            "type": "string",
            "format": "uri"
          },
          "package_url_expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "verify_url": {
            "type": "string",
            "description": "公開のProofSnap検証ツールへのリンク。",
            "format": "uri"
          },
          "warnings": {
            "$ref": "#/components/schemas/Rule902DisabledWarnings"
          }
        }
      },
      "PlainText": {
        "type": "string",
        "description": "裁判所向けの文書や公開ページに印刷される短い自由入力フィールド（case_reference、case_id、case_note、「evidence_pack.custodian」の値、certify-hashの「case_reference」、墨消しのcustodian、エクスポートの宣言、会社名と案件名）のプレーンテキスト規則です。値はNFCに正規化され、空白は1つにまとめられて前後が除去され、長さは文字数（Unicodeコードポイント）で数えられます。拒否されるもの：制御文字（C0、C1）、bidiの埋め込み、オーバーライド、アイソレート（U+202A～U+202E、U+2066～U+2069）、方向マーク（U+200E、U+200F、U+061C）、ゼロ幅文字と不可視文字（U+200B、U+2060～U+2064、U+FEFF、U+00AD、U+034F、U+180E、U+206A～U+206F、U+FFF9～U+FFFB）、ハングルのフィラー文字（U+115F、U+1160、U+3164、U+FFA0）、タグ文字（U+E0000～U+E007F）、孤立サロゲート、私用文字。ハングルの音節、アラビア文字、ヘブライ文字、デーヴァナーガリー、CJKを含むすべての文字体系の文字は受け付けます。U+200C / U+200D（ZWNJ、ZWJ）は、いくつかの文字体系の正しい表記に必要なため使用できます。"
      },
      "EidasTimestamp": {
        "type": "object",
        "description": "本番キーで「include_eidas」が要求された場合のeIDASの結果です。要求されなかった場合は含まれません。confirmed：パッケージにmanifest.json.tsrが含まれます（失効状態が不明な場合を除き請求されます）。not_obtained：トークンは提供されず、何も請求されていません。パッケージにはOpenTimestampsのアンカーのみが含まれます（reason token_refused：トークンが返されましたが、発行時のチェックに合格しませんでした。unavailable：トークンを取得できませんでした。time_budget：リクエストが残り時間に収まらなかったため、実行されなかった、認証局へのリクエストの前にタイムスタンプサービスに拒否された、または停止されました。これは同期の墨消しルート、または長いキャプチャの終盤で発生します。account_limit：アカウントに支払い済みの請求書がまだなく、eIDASの上限（キャプチャ、バッチ、スケジュール、証明、比較、墨消し、案件の封印の合計で、UTCの1日あたり20スタンプまたはUTCの1か月あたり50スタンプ）に達したため、リクエストは行われませんでした。支払い済みの請求書があるアカウントに上限はありません）。2026-10-01より前に完了した行はconfirmedのみを報告します。",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "confirmed",
              "not_obtained"
            ]
          },
          "reason": {
            "type": "string",
            "enum": [
              "token_refused",
              "unavailable",
              "time_budget",
              "account_limit"
            ],
            "description": "「not_obtained」のみ。"
          },
          "serial": {
            "type": "string",
            "nullable": true,
            "description": "confirmedのみ。"
          },
          "issued_at": {
            "type": "string",
            "nullable": true,
            "description": "confirmedのみ。"
          },
          "revocation": {
            "type": "string",
            "enum": [
              "unknown"
            ],
            "description": "confirmedのみで、発行時にTSA証明書のステータスを確定できなかった場合に限ります（トークンは他のすべてのチェックに合格しています）。トークンは提供され、請求されません。"
          },
          "billed": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "失効状態unknownとともに含まれます（false）：このトークンは請求されませんでした。"
          }
        }
      },
      "ExternalArchive": {
        "type": "object",
        "description": "キャプチャのInternet Archive（Wayback Machine）の結果です。Internet Archiveは第三者の公開アーカイブです。",
        "required": [
          "requested"
        ],
        "properties": {
          "requested": {
            "type": "boolean",
            "description": "Internet Archiveへのリクエストが行われなかった場合はfalseです（external_archive: false、証明または比較、アーカイブ機能の導入前に作成されたキャプチャ、またはリクエストが制限時間に収まらなかった場合）。この場合、他のフィールドはすべて含まれません。"
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "recent_existing",
              "created_after_request",
              "existing",
              "pending",
              "rate_limited",
              "failed",
              "unconfirmed",
              "unavailable",
              "skipped",
              "skipped_sensitive",
              "skipped_query"
            ],
            "description": "現在の結果です。封印時に保留中のSave Page Nowジョブについては、スケジューラーがリクエストの約5分後と30分後にジョブのステータスを読み取り、これが最終結果になります（created、recent_existing、failed、rate_limited、または確認期間内に応答がなかった場合はunconfirmed）。created、recent_existing、created_after_request、existingには「snapshot_url」が含まれます。"
          },
          "status_at_sealing": {
            "type": "string",
            "enum": [
              "created",
              "recent_existing",
              "created_after_request",
              "existing",
              "pending",
              "rate_limited",
              "failed",
              "unconfirmed",
              "unavailable",
              "skipped",
              "skipped_sensitive",
              "skipped_query"
            ],
            "description": "パッケージに封印された状態です（metadata.json、「forensic_log.json」、「chain_of_custody.json」、evidence.pdfに記録されます）。パッケージ自体が変更されることはありません。保留中のジョブが後続処理で解決されない限り、statusと同じ値です。"
          },
          "method": {
            "type": "string",
            "nullable": true,
            "enum": [
              "spn2_authenticated",
              "spn_anonymous",
              null
            ]
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "snapshot_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Wayback Machineの公開コピーです。常に次の形式です：https://web.archive.org/web/{snapshot_timestamp}/{url}."
          },
          "snapshot_timestamp": {
            "type": "string",
            "nullable": true,
            "description": "WaybackタイムスタンプYYYYMMDDhhmmss（UTC）です。"
          },
          "snapshot_offset_seconds": {
            "type": "integer",
            "nullable": true,
            "description": "スナップショットの時刻からキャプチャの時刻を引いた秒数です（負の値：キャプチャの前）。"
          },
          "resolved_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "スケジューラーの後続処理が最終結果を記録した時刻です。封印された状態が最終結果である場合はnullです。"
          },
          "job_id": {
            "type": "string",
            "nullable": true,
            "description": "Save Page NowのジョブIDです（認証済みリクエスト）。"
          },
          "follow_up_pending": {
            "type": "boolean",
            "description": "スケジューラーがまだジョブのステータスを読み取る必要がある間はtrueです。"
          },
          "skip_reason": {
            "type": "string",
            "nullable": true,
            "description": "statusがskipped、skipped_sensitive、または、「skipped_query」の場合の、URLが送信されなかった理由です：credentials_in_url、sensitive_path、opaque_path_segment、sensitive_fragment、sensitive_parameter_name、opaque_parameter_value、query_string（古い行ではstatus自体の値）。"
          },
          "resolved": {
            "type": "object",
            "nullable": true,
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "created",
                  "recent_existing",
                  "failed",
                  "rate_limited",
                  "unresolved"
                ]
              },
              "job_status": {
                "type": "string",
                "nullable": true,
                "description": "Save Page Nowジョブから読み取ったsuccess、error、pendingのいずれかです。読み取れなかった場合はnullです。"
              },
              "snapshot_url": {
                "type": "string",
                "nullable": true,
                "description": "https://web.archive.org/web/<14 digits>/<URL>です。存在しない場合または無効な場合はnullです。"
              },
              "snapshot_timestamp": {
                "type": "string",
                "nullable": true
              },
              "checked_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "reason": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "no_request_time",
                  "capture_deleted",
                  "capture_failed",
                  null
                ],
                "description": "ジョブの応答がない理由です：no_request_time（行に読み取りをスケジュールするためのリクエスト時刻がない）、capture_deleted、capture_failed（ジョブの保留中にキャプチャがゴミ箱に移動されたか失敗したため、後続処理が行われなかった。リクエストから30分以内にゴミ箱から復元されたキャプチャは再度後続処理が行われます）。それ以外の場合はnullです。"
              }
            },
            "description": "後続処理の記録（履歴）で、固定の射影です：「snapshot_url」は「snapshot_timestamp」の有効なWaybackスナップショットURLである場合のみ含まれ、reasonは後続処理がジョブの応答なしで終了した場合のみ含まれます。"
          }
        }
      },
      "CaptureStorage": {
        "type": "object",
        "description": "保存期間、複製コピー、および（スケジュールキャプチャの）バージョン履歴です。",
        "properties": {
          "retention": {
            "type": "object",
            "properties": {
              "years": {
                "type": "integer",
                "example": 10
              },
              "counted_from": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "「created_at」と最後に確認された使用のうち遅い方です：ページが変更されていないことを確認した最後のチェック、または同じスケジュールの新しいキャプチャがこのキャプチャを置き換えた時刻です。"
              },
              "earliest_deletion_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "「counted_from」に年数を加えた値で、おおよそのものです：削除はその後のスケジューラーの処理で実行され、その後のチェックによって移動する場合があります。リーガルホールド中はnullです。"
              },
              "legal_hold": {
                "type": "boolean"
              }
            }
          },
          "duplicate_copy": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "none",
                  "pending",
                  "stored",
                  "not_copied"
                ],
                "description": "stored：パッケージ（およびアップグレードされたOTSの証明）の2つ目のコピーが、別のEUリージョンの別のバケットに保持され、元のパッケージとともに削除されます。pending：コピー中です（数分）。none：テストパッケージ、および複製機能の導入前のパッケージで、コピーされるまでの状態です。"
              },
              "copied_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "version": {
            "type": "object",
            "description": "スケジュールキャプチャのみ。",
            "properties": {
              "superseded_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "superseded_by": {
                "type": "string",
                "nullable": true
              },
              "unchanged_first_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "このキャプチャ以降、ページのテキストが変更されていないことを確認した最初のチェック（on_change）です。"
              },
              "unchanged_last_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "unchanged_checks": {
                "type": "integer",
                "description": "記録された変更なしのチェック数です（最大で1時間に1回）。"
              }
            }
          }
        }
      },
      "WebhookEventType": {
        "type": "string",
        "enum": [
          "capture.completed",
          "capture.failed",
          "certify.completed",
          "certify.failed",
          "redaction.completed",
          "redaction.failed",
          "monitor.change_detected",
          "capture.anchor_confirmed",
          "schedule.paused"
        ],
        "description": "カタログのイベントです（Webhooksタグ）。"
      },
      "WebhookSubscriptionFilters": {
        "type": "object",
        "description": "hostと「schedule_id」はどちらか一方のみ指定できます。Webhookサブスクリプションは、そのhost（キャプチャしたURLの小文字のホスト名）の行、またはそのスケジュールの行のイベントのみを受信します。指定しない場合は`{}`です。",
        "properties": {
          "host": {
            "type": "string",
            "example": "www.example.com"
          },
          "schedule_id": {
            "type": "string",
            "example": "sch_a1B2c3D4e5F6g7H8"
          }
        }
      },
      "WebhookSubscription": {
        "type": "object",
        "properties": {
          "subscription_id": {
            "type": "string",
            "example": "whs_a1B2c3D4e5F6g7H8"
          },
          "url": {
            "type": "string",
            "description": "イベントがPOSTされるhttpsエンドポイントです。"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "filters": {
            "$ref": "#/components/schemas/WebhookSubscriptionFilters"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled"
            ]
          },
          "env": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ],
            "description": "Webhookサブスクリプションを作成した認証情報の環境です。本番のWebhookサブスクリプションは本番の行のイベントのみを受信し、テストのWebhookサブスクリプションはテストの行のイベントのみを受信します。"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_by": {
            "type": "string",
            "enum": [
              "key",
              "session"
            ],
            "description": "key：APIキーで作成されました。そのキーを失効させるとWebhookサブスクリプションは無効になります（disabled_reason key_revoked）。"
          },
          "consecutive_failures": {
            "type": "integer",
            "description": "最後の成功以降に失敗した配信の数です。"
          },
          "last_success_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_failure_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_error": {
            "type": "string",
            "nullable": true,
            "description": "最後に失敗した配信のエラークラスです（timeout、connection_failed、blocked_address、redirect_not_followed、http_<status>）。"
          },
          "disabled_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "gone",
              "failing",
              "key_revoked",
              null
            ],
            "description": "gone：エンドポイントが応答しました（410）。failing：5日間すべての配信が失敗し、成功がありませんでした。key_revoked：作成に使用したAPIキーが失効しました。PATCH status activeで再有効化します。"
          },
          "disabled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "subscription_id",
          "url",
          "events",
          "filters",
          "description",
          "status",
          "env",
          "created_at",
          "created_by",
          "consecutive_failures",
          "last_success_at",
          "last_failure_at",
          "last_error",
          "disabled_reason",
          "disabled_at"
        ]
      },
      "WebhookSubscriptionCreated": {
        "type": "object",
        "properties": {
          "subscription_id": {
            "type": "string",
            "example": "whs_a1B2c3D4e5F6g7H8"
          },
          "url": {
            "type": "string",
            "description": "イベントがPOSTされるhttpsエンドポイントです。"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "filters": {
            "$ref": "#/components/schemas/WebhookSubscriptionFilters"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled"
            ]
          },
          "env": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ],
            "description": "Webhookサブスクリプションを作成した認証情報の環境です。本番のWebhookサブスクリプションは本番の行のイベントのみを受信し、テストのWebhookサブスクリプションはテストの行のイベントのみを受信します。"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_by": {
            "type": "string",
            "enum": [
              "key",
              "session"
            ],
            "description": "key：APIキーで作成されました。そのキーを失効させるとWebhookサブスクリプションは無効になります（disabled_reason key_revoked）。"
          },
          "secret": {
            "type": "string",
            "description": "whsec_に続く標準のbase64です。表示されるのは1回のみです：このWebhookサブスクリプションへのすべての配信はこれで署名されます（Standard Webhooks）。今すぐ保存してください。後から読み取ることはできません。24時間以内のIdempotency-Keyの再生では、シークレットを含む同じ本文が返されます。"
          }
        },
        "required": [
          "subscription_id",
          "url",
          "events",
          "filters",
          "description",
          "status",
          "env",
          "created_at",
          "created_by",
          "secret"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_a1B2c3D4e5F6g7H8"
          },
          "type": {
            "$ref": "#/components/schemas/WebhookEventType"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "env": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ]
          },
          "data": {
            "type": "object",
            "description": "Webhookサブスクリプションが受信するイベント本文から、「subscription_id」と署名付きリンク（package_url、package_url_expires_at、upgraded_proof_url、compare.package_url）を除いたものです。"
          }
        },
        "required": [
          "id",
          "type",
          "created_at",
          "env",
          "data"
        ]
      },
      "PrivateNote": {
        "type": "string",
        "nullable": true,
        "maxLength": 200,
        "description": "キャプチャのプライベートメモ（例：\"mobile capture\"）で、プレーンテキストです（文字数の上限：200。PlainTextの規則）。キャプチャの記録にのみ保存され、封印された証拠パッケージには含まれません（ZIP、PDF、マニフェスト、いずれのハッシュにも含まれません）。証拠としての価値はないため、証拠に影響を与えずに、後からPATCH /v1/captures/{capture_id}で変更またはクリアできます。読み取れるのはキャプチャの作成者のみです。メモが不要な場合は省略するか、nullまたは空文字列を送信してください。",
        "example": "mobile capture"
      },
      "CaptureEvent": {
        "type": "object",
        "description": "アカウントのキャプチャイベントチェーンの1つのイベントです。hash = ハッシュ対象フィールド（v、chain、seq、type、capture_id、manifest_sha256、actor、access、detail、at、prev_hash。キーはソート、空白なし、値がない場合はnull）の正規化JSONのSHA-256（16進数）です。「prev_hash」は前のイベントのhashで、seq 1では0が64個です。",
        "properties": {
          "v": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "chain": {
            "type": "string",
            "description": "アカウントです：個人のキャプチャではuid、会社のキャプチャではorg_<org_id>です。"
          },
          "seq": {
            "type": "integer",
            "minimum": 1
          },
          "type": {
            "type": "string",
            "enum": [
              "trash",
              "restore",
              "erase",
              "purge",
              "retention_deletion",
              "account_deletion",
              "company_deletion",
              "legal_hold_on",
              "legal_hold_off",
              "s3_legal_hold",
              "import"
            ]
          },
          "capture_id": {
            "type": "string"
          },
          "manifest_sha256": {
            "type": "string",
            "nullable": true,
            "description": "キャプチャのmanifest.jsonのハッシュ（SHA-256）で、削除の前に読み取られます。"
          },
          "actor": {
            "type": "string",
            "description": "操作を行ったアカウントのuid、またはサーバーの定期処理の場合はsystemです。"
          },
          "access": {
            "type": "string",
            "description": "author、company_owner、matter_owner、または、system。"
          },
          "detail": {
            "type": "string",
            "nullable": true,
            "description": "legal_hold_on / legal_hold_off：リーガルホールドの出所（manual、bulk、matter:<id>、derived:<capture_id>）、またはシステムによる解除（actor system）の場合はその理由コード「subscription_ended」です。s3_legal_hold：S3の結果（on、off、failed、unsupported、none）です。import：インポートされたパッケージの種類です。自由入力のテキストは含まれません。"
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "description": "イベントがチェーンに書き込まれた時刻です。前のイベントのatより早くなることはありません。"
          },
          "prev_hash": {
            "type": "string"
          },
          "hash": {
            "type": "string"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "操作自体がコミットされた時刻です（状態変更のトランザクション）。ハッシュの対象外です。通常はatとミリ秒単位で等しくなります。これより遅くなるのは、サーバーがチェーンへの追加を再試行した場合のみです（操作は変更と同じトランザクションで記録されるため、失われることはありません）。"
          }
        }
      },
      "CaptureEventAnchor": {
        "type": "object",
        "description": "チェーンの1日1回のOpenTimestampsアンカーです：「head_hash」はイベント「to_seq」のハッシュで、それ以前のすべてのイベントにコミットします。",
        "properties": {
          "anchor_id": {
            "type": "string"
          },
          "day": {
            "type": "string",
            "format": "date"
          },
          "from_seq": {
            "type": "integer"
          },
          "to_seq": {
            "type": "integer"
          },
          "head_hash": {
            "type": "string"
          },
          "ots_proof_base64": {
            "type": "string",
            "nullable": true,
            "description": "「head_hash」に対するOpenTimestampsの証明（.otsファイル、base64）です。"
          },
          "ots_status": {
            "type": "string",
            "enum": [
              "pending",
              "bitcoin",
              "unconfirmed"
            ],
            "description": "pending：「ots_proof_base64」はカレンダーのコミットメントを保持します（ots verifyがカレンダーに問い合わせます）。bitcoin：Bitcoinブロックに対してアップグレードされた証明に置き換えられました（bitcoin_block_height）。unconfirmed：14日以内にBitcoinの証明が返されませんでした。保存された証明は引き続きカレンダーを通じて検証できます。"
          },
          "bitcoin_block_height": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ImportSummary": {
        "type": "object",
        "description": "検証済みパッケージの3つのレベルです。",
        "properties": {
          "kind_label_key": {
            "type": "string",
            "description": "パッケージの種類のラベルキーで、import_kind_<kind>です。"
          },
          "integrity": {
            "type": "string",
            "enum": [
              "verified",
              "failed"
            ]
          },
          "time_anchor": {
            "type": "string",
            "enum": [
              "eidas_qualified",
              "eidas_qualified_revocation_unknown",
              "ots_bitcoin_attested_unconfirmed",
              "ots_pending",
              "none"
            ]
          },
          "provenance": {
            "type": "string",
            "nullable": true,
            "enum": [
              "issued_by_proofsnap",
              "unverified",
              "registered_by_extension_account",
              "not_registered",
              "unknown",
              null
            ]
          },
          "registered_at": {
            "type": "string",
            "format": "date-time",
            "description": "拡張機能のレジストリがパッケージを記録した時刻です（provenance registered_by_extension_account）。"
          },
          "issued_at": {
            "type": "string",
            "format": "date-time",
            "description": "API発行台帳が発行を記録した時刻です（provenance issued_by_proofsnap）。"
          }
        }
      },
      "Import": {
        "type": "object",
        "properties": {
          "import_id": {
            "type": "string",
            "example": "imp_a1B2c3D4e5F6g7H8i9J0"
          },
          "status": {
            "type": "string",
            "enum": [
              "uploading",
              "verifying",
              "accepted",
              "rejected",
              "duplicate",
              "expired"
            ]
          },
          "filename": {
            "type": "string"
          },
          "size_bytes": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "upload_expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "uploadingのみ：この時刻までに完了してください（作成から24時間後）。"
          },
          "finished_at": {
            "type": "string",
            "format": "date-time",
            "description": "インポートが最終ステータスに達した時刻です。"
          },
          "capture_id": {
            "type": "string",
            "description": "acceptedのみ：新しいキャプチャです（インポートと同じID）。"
          },
          "duplicate_of": {
            "type": "string",
            "description": "duplicateのみ：このマニフェストをすでに保持している自分のキャプチャです。"
          },
          "kind": {
            "type": "string",
            "enum": [
              "web_capture_v21",
              "web_capture_legacy",
              "session",
              "file_certification_single",
              "file_certification_combined",
              "api_capture",
              "api_certify",
              "api_compare",
              "api_redaction"
            ],
            "description": "パッケージの種類です。検出後に設定されます。"
          },
          "summary": {
            "$ref": "#/components/schemas/ImportSummary"
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "rejectedとexpired：理由コードです（例：file_mismatch、file_missing、unlisted_file、bad_signature、no_hashed_files、unknown_schema、zip_too_large、test_package、ots_digest_mismatch、eidas_token_failed、forensic_chain_broken、size_mismatch、upload_not_completed、verification_incomplete）。コードのみで、ファイル名が含まれることはありません。"
          },
          "zip_sha256": {
            "type": "string",
            "description": "アップロードされたZIPのハッシュ（SHA-256）です。計算後に設定されます。"
          },
          "manifest_sha256": {
            "type": "string",
            "description": "パッケージのmanifest.jsonのハッシュ（SHA-256）です（acceptedとduplicate）。"
          },
          "matter_id": {
            "type": "string",
            "description": "インポートの作成時に指定された案件です。"
          },
          "matter_assignment": {
            "type": "string",
            "enum": [
              "assigned",
              "skipped"
            ],
            "description": "acceptedで「matter_id」がある場合：キャプチャが案件に追加されたかどうかを示します（その時点で案件が封印された、アーカイブされた、または開けなくなった場合はスキップされます。インポートはacceptedのままです）。"
          },
          "upload": {
            "type": "object",
            "description": "?upload=trueを指定し、statusがuploadingの間のみ返されます。",
            "properties": {
              "upload_id": {
                "type": "string"
              },
              "part_size": {
                "type": "integer"
              },
              "parts": {
                "type": "array",
                "description": "まだ受信していないパートの署名付きPUT URLです。正確に「size_bytes」をPUTしてください。",
                "items": {
                  "type": "object",
                  "properties": {
                    "part_number": {
                      "type": "integer"
                    },
                    "url": {
                      "type": "string"
                    },
                    "size_bytes": {
                      "type": "integer"
                    }
                  }
                }
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "received": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "object",
                  "properties": {
                    "part_number": {
                      "type": "integer"
                    },
                    "etag": {
                      "type": "string"
                    },
                    "size_bytes": {
                      "type": "integer"
                    }
                  }
                }
              },
              "completed": {
                "type": "boolean",
                "description": "アップロードはすでに完了しています：completeを再度送信してください。"
              }
            }
          }
        }
      },
      "ImportVerification": {
        "type": "object",
        "description": "インポート時に記録された検証レポートです（ファイルの内容や自由入力の詳細は含まれません）。",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "kind": {
            "type": "string",
            "enum": [
              "web_capture_v21",
              "web_capture_legacy",
              "session",
              "file_certification_single",
              "file_certification_combined",
              "api_capture",
              "api_certify",
              "api_compare",
              "api_redaction"
            ]
          },
          "format": {
            "type": "string"
          },
          "kind_label_key": {
            "type": "string"
          },
          "evidence_id": {
            "type": "string",
            "description": "パッケージが保持するIDです（ps_...、FC-...、cap_...、cert_...、cmp_...、red_...）。"
          },
          "manifest_sha256": {
            "type": "string"
          },
          "zip_sha256": {
            "type": "string"
          },
          "anchor_sha256": {
            "type": "string",
            "description": "タイムスタンプの対象となるハッシュです：マニフェストのハッシュ、または単一ファイルの証明の場合は証明されたファイルのハッシュです。"
          },
          "anchor_source": {
            "type": "string",
            "enum": [
              "manifest",
              "certified_file"
            ]
          },
          "checks": {
            "type": "object",
            "description": "項目：structure、signature、files（listed、verified、presence_only、unhashed、os_junk_ignored）、custody、forensic_chain、ots、eidas、test_mode。",
            "additionalProperties": true
          },
          "summary": {
            "$ref": "#/components/schemas/ImportSummary"
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CaptureImport": {
        "type": "object",
        "description": "source \"import\"のキャプチャにのみ含まれます。",
        "properties": {
          "import_id": {
            "type": "string"
          },
          "package_kind": {
            "type": "string",
            "enum": [
              "web_capture_v21",
              "web_capture_legacy",
              "session",
              "file_certification_single",
              "file_certification_combined",
              "api_capture",
              "api_certify",
              "api_compare",
              "api_redaction"
            ]
          },
          "kind_label_key": {
            "type": "string"
          },
          "package_format": {
            "type": "string"
          },
          "original_evidence_id": {
            "type": "string"
          },
          "original_filename": {
            "type": "string",
            "nullable": true
          },
          "imported_at": {
            "type": "string",
            "format": "date-time"
          },
          "captured_at_basis": {
            "type": "string",
            "enum": [
              "package_claim"
            ],
            "description": "インポートされたパッケージの「captured_at」は、パッケージが示す時刻であり、ProofSnapが確認した時刻ではありません。"
          },
          "manifest_sha256": {
            "type": "string"
          },
          "zip_sha256": {
            "type": "string"
          },
          "summary": {
            "$ref": "#/components/schemas/ImportSummary"
          },
          "levels": {
            "type": "object",
            "properties": {
              "integrity": {
                "type": "string"
              },
              "time_anchor": {
                "type": "string"
              },
              "provenance": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "verification": {
            "$ref": "#/components/schemas/ImportVerification"
          },
          "provenance": {
            "type": "object",
            "properties": {
              "level": {
                "type": "string"
              },
              "source": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "api_ledger",
                  "extension_registry",
                  null
                ]
              },
              "issued_at": {
                "type": "string",
                "nullable": true
              },
              "registered_at": {
                "type": "string",
                "nullable": true
              },
              "reason": {
                "type": "string"
              }
            }
          }
        }
      },
      "Rule902DisabledWarnings": {
        "type": "array",
        "description": "テンプレートが無効な状態で、リクエストが証明書テンプレート（include_rule_902: true、またはキャプチャの場合は空でない「evidence_pack.custodian」）を要求した場合にのみ含まれます。リクエストは受け付けられ、フラグは無視されました：「rule_902_certification.pdf」は生成されません。",
        "items": {
          "type": "object",
          "properties": {
            "code": {
              "type": "string",
              "enum": [
                "RULE902_DISABLED"
              ]
            },
            "message": {
              "type": "string",
              "example": "The FRE 902 certification template (rule_902_certification.pdf) is currently disabled. include_rule_902 was accepted and ignored: the package does not contain the template."
            }
          },
          "required": [
            "code",
            "message"
          ]
        }
      }
    }
  }
}
