{
  "openapi": "3.1.0",
  "info": {
    "title": "AdKura External API",
    "version": "1.4.0-beta",
    "description": "契約組織への限定提供の連携API。クリエイティブ・レビューの取得と、配信システムからの作成・状態更新・コメント投稿。回数は組織全体（全キー・MCP を含む）で1分あたり・1日あたり（日本時間0時に戻る）の上限があり、標準は1分60回・1日10,000回。契約によって異なり、GET /me の rateLimits で確認できる。"
  },
  "servers": [
    {
      "url": "https://app.adkura.co.jp/api/v1"
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "getMe",
        "summary": "キーの範囲を取得",
        "description": "権限の指定なし（有効なキーなら利用できる）。応答は Cache-Control: no-store。連携の設定確認や、MCP の whoami と同じ内容を返す。",
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED: 組織で外部APIが無効 / KEY_ISSUER_INACTIVE: キーの発行者が退会・管理者ではなくなった",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR: 想定外の失敗。requestIdを添えて問い合わせる",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/projects": {
      "get": {
        "operationId": "listProjects",
        "summary": "対象プロジェクトの一覧",
        "description": "必要な権限: creatives:read。応答は Cache-Control: no-store。キーの対象プロジェクトのうち、発行者が現在の取引関係で閲覧できるものを返す。",
        "x-required-scope": "creatives:read",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "前のページのnextCursor。itemsが空でもnextCursorがnullになるまで取得を続ける。"
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectPage"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_LIMIT / INVALID_CURSOR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED: 組織で外部APIが無効 / KEY_ISSUER_INACTIVE: キーの発行者が退会・管理者ではなくなった / INSUFFICIENT_SCOPE: キーに必要な権限がない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE: 応答が2MiBを超えた。limitを減らす",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）を超えた。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR: 想定外のエラー。問い合わせ時はrequestIdを伝える",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIの停止中・メンテナンス中。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{id}": {
      "get": {
        "operationId": "getProject",
        "summary": "プロジェクトの詳細を取得",
        "description": "必要な権限: creatives:read。応答は Cache-Control: no-store。キーの対象外のプロジェクトは 404。",
        "x-required-scope": "creatives:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "プロジェクトのID"
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectDetail"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED: 組織で外部APIが無効 / KEY_ISSUER_INACTIVE: キーの発行者が退会・管理者ではなくなった / INSUFFICIENT_SCOPE: キーに必要な権限がない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR: 想定外の失敗。requestIdを添えて問い合わせる",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/creatives": {
      "get": {
        "operationId": "listCreatives",
        "summary": "クリエイティブ（版）の一覧",
        "description": "必要な権限: creatives:read。応答は Cache-Control: no-store。IDの昇順。絞り込みに一致しないページでもnextCursorが返ることがある。",
        "x-required-scope": "creatives:read",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "前のページのnextCursor。itemsが空でもnextCursorがnullになるまで取得を続ける。"
          },
          {
            "name": "projectId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "対象を1プロジェクトに絞る。キーの対象外なら403 PROJECT_FORBIDDEN。"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "waiting_review",
                "under_review",
                "approved",
                "correction_requested",
                "revised",
                "pending",
                "placed",
                "archived"
              ],
              "default": "all"
            }
          },
          {
            "name": "latestOnly",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "削除されていない最新版だけを対象にする。最新版を決めてから状態で絞るため、最新版が未承認なら旧承認版は返さない。"
          },
          {
            "name": "reviewStatus",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReviewStatus"
            },
            "description": "監修の生の状態で絞る。入稿候補は reviewStatus=approved&placed=false&archived=false&latestOnly=true"
          },
          {
            "name": "placed",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "出稿済みかどうかで絞る"
          },
          {
            "name": "archived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "pending",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "この日時以降に更新された版だけを返す（updatedAt >= updatedSince）。同時更新の取りこぼしは定期的な全件同期で収束させる"
          },
          {
            "name": "media",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Media"
            },
            "description": "想定媒体で絞る"
          },
          {
            "name": "system",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/PlatformSystem"
            },
            "description": "externalId と組で指定し、自組織が登録した広告IDからクリエイティブを逆引きする"
          },
          {
            "name": "externalId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "externalAccountId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "省略時はアカウントを問わない"
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreativePage"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_LIMIT / INVALID_CURSOR / INVALID_STATUS / INVALID_FILTER / INVALID_ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED: 組織で外部APIが無効 / KEY_ISSUER_INACTIVE: キーの発行者が退会・管理者ではなくなった / INSUFFICIENT_SCOPE: キーに必要な権限がない / PROJECT_FORBIDDEN: projectIdがキーの対象外",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE: 応答が2MiBを超えた。limitを減らす",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）を超えた。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR: 想定外のエラー。問い合わせ時はrequestIdを伝える",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIの停止中・メンテナンス中。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createCreatives",
        "summary": "クリエイティブを作成",
        "description": "必要な権限: creatives:write。応答は Cache-Control: no-store。source が files のときは POST /uploads で PUT を済ませた fileIds を渡す。text・youtube はこの要求だけで作成できる。作成はキー発行者名義で記録され、画面のアップロードと同じく監修の初期状態・通知・AIチェック・動画の変換が始まる。Idempotency-Key を付けると、同じ要求の再送は保存済みの応答を返す（24時間）",
        "x-required-scope": "creatives:write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "再送時に同じ値を付ける。本文やパスが違う再送は 422"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreativeCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "作成した版",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreativeCreateResult"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_INPUT / INVALID_IDEMPOTENCY_KEY / INVALID_TAGS: タグがプロジェクト所有組織のものでない、または必須・単一選択の制約に反する / INVALID_YOUTUBE_URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: creatives:write が必要 / FORBIDDEN / UPLOADER_NOT_ASSIGNABLE: このプロジェクトに作成できない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み / CREATIVE_REQUEST_NOT_FOUND / UPLOAD_NOT_FOUND: fileId が無い（別のキーの予約を含む）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_IN_PROGRESS: 同じキーの要求を処理中 / UPLOAD_ALREADY_CONSUMED: すでに登録済みの fileId / UPLOAD_TARGET_MISMATCH: 別のプロジェクト・依頼の予約 / UPLOAD_NOT_COMPLETED: PUT が完了していない / UPLOAD_SIZE_MISMATCH / UPLOAD_CONTENT_TYPE_MISMATCH: 申告と実体が違う",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "UPLOAD_EXPIRED: 予約が期限切れ（2時間）。POST /uploads からやり直す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "IDEMPOTENCY_MISMATCH: 同じキーで内容が違う",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/creatives/{id}": {
      "get": {
        "operationId": "getCreative",
        "summary": "クリエイティブ（版）の詳細",
        "description": "必要な権限: creatives:read。応答は Cache-Control: no-store。",
        "x-required-scope": "creatives:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreativeDetail"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED: 組織で外部APIが無効 / KEY_ISSUER_INACTIVE: キーの発行者が退会・管理者ではなくなった / INSUFFICIENT_SCOPE: キーに必要な権限がない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: 存在しない、またはキーの範囲で閲覧できない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）を超えた。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR: 想定外のエラー。問い合わせ時はrequestIdを伝える",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIの停止中・メンテナンス中。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/creatives/{id}/status": {
      "patch": {
        "operationId": "updateCreativeStatus",
        "summary": "出稿済み・アーカイブを更新",
        "description": "必要な権限: placements:write。応答は Cache-Control: no-store。クライアントは自組織がアップロードしたクリエイティブだけを更新できる。同じ要求を繰り返しても結果は同じ（Idempotency-Key は不要）。",
        "x-required-scope": "placements:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreativeStatusUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新後の状態",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreativeStatusResult"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID / INVALID_INPUT: 項目が無い、両方 true、形式不正",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: placements:write が必要 / FORBIDDEN: この組織の権限では操作できない（クライアントは自組織がアップロードしたクリエイティブだけ）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "INVALID_STATE_TRANSITION: 出稿済みとアーカイブは同時に有効にできない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/creatives/{id}/reviews": {
      "get": {
        "operationId": "listCreativeReviews",
        "summary": "人の監修・コメント・返信",
        "description": "必要な権限: reviews:read。応答は Cache-Control: no-store。作成日時の昇順（同時刻はID順）。日時のない監修は末尾。返信のparentIdはコメントのID。取得可能なクリエイティブでも、下位組織が上位組織に対して非公開にしたコメント・返信は除外する。取引関係を解除しても非公開は維持される。対象クリエイティブの取得範囲は現在の取引関係に限る。",
        "x-required-scope": "reviews:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "前のページのnextCursor。itemsが空でもnextCursorがnullになるまで取得を続ける。"
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPage"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID / INVALID_LIMIT / INVALID_CURSOR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED: 組織で外部APIが無効 / KEY_ISSUER_INACTIVE: キーの発行者が退会・管理者ではなくなった / INSUFFICIENT_SCOPE: キーに必要な権限がない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）を超えた。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR: 想定外のエラー。問い合わせ時はrequestIdを伝える",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIの停止中・メンテナンス中。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/creatives/{id}/comments": {
      "post": {
        "operationId": "createCreativeComment",
        "summary": "コメントを投稿",
        "description": "必要な権限: comments:write。応答は Cache-Control: no-store。API キーの発行者名義で投稿される。Idempotency-Key を付けると、同じ要求の再送は保存済みの応答を返す（24時間）。下位組織の確認が終わっていないクリエイティブには投稿できない（404）。",
        "x-required-scope": "comments:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "再送時に同じ値を付ける。本文やパスが違う再送は 422"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "投稿したコメント（kind は comment）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Review"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID / INVALID_INPUT / INVALID_IDEMPOTENCY_KEY",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: comments:write が必要 / FORBIDDEN: この組織の権限では操作できない（クライアントは自組織がアップロードしたクリエイティブだけ）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_IN_PROGRESS: 同じキーの要求を処理中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "IDEMPOTENCY_MISMATCH: 同じキーで内容が違う / EMPTY_CONTENT: 本文が空",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/creatives/{id}/download-urls": {
      "post": {
        "operationId": "createCreativeDownloadUrls",
        "summary": "保存済み素材の期限付きURLを発行",
        "description": "必要な権限: assets:download。応答は Cache-Control: no-store。URLは10分で失効する。1件でも不正な素材IDがあれば1件も発行しない。quality は動画の素材だけに指定でき、hd（720p）/ sd（480p）は変換済みの H.264 を .mp4 で返す。",
        "x-required-scope": "assets:download",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Download"
                      }
                    }
                  },
                  "required": ["items"],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID / INVALID_INPUT / INVALID_QUALITY: 動画以外に画質を指定した、または quality の値が不正",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED: 組織で外部APIが無効 / KEY_ISSUER_INACTIVE: キーの発行者が退会・管理者ではなくなった / INSUFFICIENT_SCOPE: キーに必要な権限がない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND / ASSET_NOT_FOUND: 素材IDが詳細のassetsにない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ASSET_UNAVAILABLE: ダウンロード対象外、または低温ストレージに移動済み / QUALITY_UNAVAILABLE: 指定した画質の変換済みファイルがない（原本には戻さない）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "REQUEST_TOO_LARGE: 本文が8KiBを超えた",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）を超えた。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR: 想定外のエラー。問い合わせ時はrequestIdを伝える",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIの停止中・メンテナンス中。Retry-Afterヘッダーの秒数後に再試行する",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "assetIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 64
                    }
                  },
                  "quality": {
                    "$ref": "#/components/schemas/VideoQuality"
                  }
                },
                "required": ["assetIds"],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/creatives/{id}/platform-references": {
      "get": {
        "operationId": "listCreativePlatformReferences",
        "summary": "配信プラットフォーム参照の一覧",
        "description": "必要な権限: creatives:read。自組織が登録した参照だけを返す。",
        "x-required-scope": "creatives:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          }
        ],
        "responses": {
          "200": {
            "description": "成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlatformReferencePage"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: creatives:read が必要 / FORBIDDEN: この組織の権限では操作できない（クライアントは自組織がアップロードしたクリエイティブだけ）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "upsertCreativePlatformReference",
        "summary": "配信プラットフォーム参照を登録・更新",
        "description": "必要な権限: placements:write。(system, externalAccountId, externalId) をキーに登録または更新する。同じ広告IDが同じ版系列の別の版に付いていれば、この版へ付け替える。別の版系列に付いていれば 409。",
        "x-required-scope": "placements:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlatformReferenceUpsert"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新（付け替えを含む）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlatformReference"
                }
              }
            }
          },
          "201": {
            "description": "作成",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlatformReference"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ID / INVALID_INPUT: externalId が空、dsp・other で externalAccountId が無い、形式不正",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: placements:write が必要 / FORBIDDEN: この組織の権限では操作できない（クライアントは自組織がアップロードしたクリエイティブだけ）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "EXTERNAL_REFERENCE_CONFLICT: 同じ広告IDが別の版系列のクリエイティブに登録されている",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteCreativePlatformReference",
        "summary": "配信プラットフォーム参照を削除",
        "description": "必要な権限: placements:write。自組織が登録した参照だけを削除できる。",
        "x-required-scope": "placements:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          },
          {
            "name": "system",
            "in": "query",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/PlatformSystem"
            }
          },
          {
            "name": "externalId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "externalAccountId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "登録時に指定した値。無いときは省略"
          }
        ],
        "responses": {
          "204": {
            "description": "削除した"
          },
          "400": {
            "description": "INVALID_ID / INVALID_INPUT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: placements:write が必要 / FORBIDDEN: この組織の権限では操作できない（クライアントは自組織がアップロードしたクリエイティブだけ）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/uploads": {
      "post": {
        "operationId": "createUploadSession",
        "summary": "アップロード先（署名付き PUT URL）を発行",
        "description": "必要な権限: creatives:write。応答は Cache-Control: no-store。画像・動画をクリエイティブとして登録する最初の手順。返された uploadUrl にファイルの実体を PUT し（headers の値をそのまま付ける。URL は発行から1時間有効）、fileIds を POST /creatives または POST /creatives/{id}/revisions に渡す。予約（fileId）は2時間で失効し、未使用の実体は削除される。revisionOf がアーカイブ済み・最新版でない版なら 409 NOT_LATEST_VERSION。キー発行者がプロジェクトのアップロード担当でなければ自動で加える（クライアントは自組織が所有する通常プロジェクトだけ。自組織内の依頼が無ければ作成する）。Idempotency-Key は受けても無視する",
        "x-required-scope": "creatives:write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "発行したアップロード先",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadSession"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_INPUT / INVALID_IDEMPOTENCY_KEY / UNSUPPORTED_CONTENT: 画像・動画以外、または MIME が拡張子と合わない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: creatives:write が必要 / FORBIDDEN: 修正版の元の版が自組織のアップロードではない / UPLOADER_NOT_ASSIGNABLE: このプロジェクトに作成できない（受けている依頼がない、所有していない）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み / CREATIVE_REQUEST_NOT_FOUND: 指定した依頼が候補にない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "NOT_LATEST_VERSION: revisionOf がアーカイブ済み、または最新の版ではない（Idempotency-Key は無視するので冪等の衝突は起きない）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "IDEMPOTENCY_MISMATCH: 同じキーで内容が違う",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ / UPLOAD_QUOTA_EXCEEDED: 未使用の予約が上限（200件・20GB）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/creatives/{id}/revisions": {
      "post": {
        "operationId": "createCreativeRevision",
        "summary": "修正版を登録",
        "description": "必要な権限: creatives:write。応答は Cache-Control: no-store。自組織がアップロードした最新の版にだけ登録できる。画面と同じく、修正依頼（却下・要修正）がある版に限る（セルフチェック組織は前の版のAIチェック完了が条件）。素材は元の版と同じ形式で、PDF・記事・スプレッドシートの版には登録できない。タグは元の版から引き継ぐ。Idempotency-Key を付けると、同じ要求の再送は保存済みの応答を返す（24時間）",
        "x-required-scope": "creatives:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "クリエイティブ（版）のID"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "再送時に同じ値を付ける。本文やパスが違う再送は 422"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevisionCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "登録した修正版（createdIds は1件。items は作成直後の読み直しに成功したときに1件で、失敗したときは空）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreativeCreateResult"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_INPUT / INVALID_IDEMPOTENCY_KEY / INVALID_ID / UNSUPPORTED_CONTENT: PDF・記事・スプレッドシートの版 / REVISION_CONTENT_TYPE_MISMATCH: 元の版と形式が違う / INVALID_YOUTUBE_URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: キーがない・形式不正・失効・期限切れ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API_DISABLED / KEY_ISSUER_INACTIVE / INSUFFICIENT_SCOPE: creatives:write が必要 / FORBIDDEN: 自組織のアップロードではない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND: キーの対象外、または削除済み / UPLOAD_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_IN_PROGRESS: 同じキーの要求を処理中 / NOT_LATEST_VERSION: 最新の版ではない、またはアーカイブ済み / REVISION_NOT_ALLOWED: 修正依頼がない / SELF_CHECK_NOT_READY: 前の版のAIチェックが未完了 / UPLOAD_ALREADY_CONSUMED / UPLOAD_TARGET_MISMATCH / UPLOAD_NOT_COMPLETED / UPLOAD_SIZE_MISMATCH / UPLOAD_CONTENT_TYPE_MISMATCH",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "UPLOAD_EXPIRED: 予約が期限切れ（2時間）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESPONSE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "IDEMPOTENCY_MISMATCH: 同じキーで内容が違う",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "RATE_LIMITED: 組織全体の回数上限（1分・1日。GET /me の rateLimits）。Retry-Afterの秒数だけ待つ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INTERNAL_ERROR",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "API_UNAVAILABLE: 外部APIを停止中",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "adk_…"
      }
    },
    "schemas": {
      "CreativeStatus": {
        "type": "string",
        "enum": [
          "waiting_review",
          "under_review",
          "approved",
          "correction_requested",
          "revised",
          "pending",
          "placed",
          "archived",
          "unknown"
        ],
        "description": "閲覧組織から見た状態。unknownは判定できない状態で、将来の値追加に備えて未知の値も扱えるようにする。"
      },
      "ContentType": {
        "type": "string",
        "enum": [
          "image",
          "video",
          "text",
          "article",
          "youtube",
          "spreadsheet",
          "pdf",
          "bundle"
        ]
      },
      "Project": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        },
        "required": ["id", "name"],
        "additionalProperties": false
      },
      "Creative": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "seriesId": {
            "type": "string",
            "format": "uuid",
            "description": "版系列のID（初版のID）"
          },
          "version": {
            "type": "integer",
            "description": "閲覧組織の画面表示と同じ版番号。クライアントは提出番号、代理店は内部版番号。"
          },
          "name": {
            "type": "string"
          },
          "contentType": {
            "$ref": "#/components/schemas/ContentType"
          },
          "status": {
            "$ref": "#/components/schemas/CreativeStatus"
          },
          "reviewStatus": {
            "$ref": "#/components/schemas/ReviewStatus"
          },
          "isPlaced": {
            "type": "boolean",
            "description": "出稿済み"
          },
          "isArchived": {
            "type": "boolean"
          },
          "isPending": {
            "type": "boolean",
            "description": "保留（クライアントが設定）"
          },
          "media": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Media"
            }
          },
          "deadline": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "project": {
            "$ref": "#/components/schemas/Project"
          },
          "creativeRequestId": {
            "type": "string",
            "format": "uuid",
            "description": "属する依頼のID。アップロード・修正版の保存先の確認に使う"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "本体・状態・出稿/アーカイブ・監修・コメント/返信/解決・レビュー段の状態・タグの変化で進む。updatedSince の基準"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "AdKuraのクリエイティブ画面"
          }
        },
        "required": [
          "id",
          "seriesId",
          "version",
          "name",
          "contentType",
          "status",
          "project",
          "createdAt",
          "url",
          "reviewStatus",
          "isPlaced",
          "isArchived",
          "isPending",
          "media",
          "deadline",
          "creativeRequestId",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "Asset": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "単一ファイルはprimary、複数ファイルは素材のUUID"
          },
          "name": {
            "type": "string"
          },
          "contentType": {
            "$ref": "#/components/schemas/ContentType"
          },
          "text": {
            "type": ["string", "null"]
          },
          "downloadable": {
            "type": "boolean"
          },
          "video": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AssetVideo"
              },
              {
                "type": "null"
              }
            ],
            "description": "動画以外は null"
          }
        },
        "required": [
          "id",
          "name",
          "contentType",
          "text",
          "downloadable",
          "video"
        ],
        "additionalProperties": false
      },
      "CreativeDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "seriesId": {
            "type": "string",
            "format": "uuid",
            "description": "版系列のID（初版のID）"
          },
          "version": {
            "type": "integer",
            "description": "閲覧組織の画面表示と同じ版番号。クライアントは提出番号、代理店は内部版番号。"
          },
          "name": {
            "type": "string"
          },
          "contentType": {
            "$ref": "#/components/schemas/ContentType"
          },
          "status": {
            "$ref": "#/components/schemas/CreativeStatus"
          },
          "reviewStatus": {
            "$ref": "#/components/schemas/ReviewStatus"
          },
          "isPlaced": {
            "type": "boolean",
            "description": "出稿済み"
          },
          "isArchived": {
            "type": "boolean"
          },
          "isPending": {
            "type": "boolean",
            "description": "保留（クライアントが設定）"
          },
          "media": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Media"
            }
          },
          "deadline": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "project": {
            "$ref": "#/components/schemas/Project"
          },
          "creativeRequestId": {
            "type": "string",
            "format": "uuid",
            "description": "属する依頼のID。アップロード・修正版の保存先の確認に使う"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "本体・状態・出稿/アーカイブ・監修・コメント/返信/解決・レビュー段の状態・タグの変化で進む。updatedSince の基準"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "AdKuraのクリエイティブ画面"
          },
          "description": {
            "type": ["string", "null"]
          },
          "text": {
            "type": ["string", "null"]
          },
          "sourceUrl": {
            "type": ["string", "null"]
          },
          "assets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Asset"
            }
          },
          "hasNewerVersion": {
            "type": "boolean",
            "description": "同じ版系列に新しい版があるか"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "platformReferences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlatformReference"
            },
            "description": "自組織が登録した配信プラットフォーム参照（他組織の参照は含まない）"
          }
        },
        "required": [
          "id",
          "seriesId",
          "version",
          "name",
          "contentType",
          "status",
          "project",
          "createdAt",
          "url",
          "description",
          "text",
          "sourceUrl",
          "assets",
          "reviewStatus",
          "isPlaced",
          "isArchived",
          "isPending",
          "media",
          "deadline",
          "creativeRequestId",
          "updatedAt",
          "hasNewerVersion",
          "tags",
          "platformReferences"
        ],
        "additionalProperties": false
      },
      "Review": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "review:<UUID> / comment:<UUID> / reply:<UUID>"
          },
          "kind": {
            "type": "string",
            "enum": ["review", "comment", "reply"]
          },
          "parentId": {
            "type": ["string", "null"]
          },
          "content": {
            "type": ["string", "null"]
          },
          "authorName": {
            "type": "string",
            "description": "公開設定で氏名を表示できない場合は空文字またはレビュー担当者"
          },
          "createdAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "status": {
            "type": ["string", "null"],
            "enum": [
              "in_review",
              "approved",
              "rejected",
              "open",
              "resolved",
              null
            ],
            "description": "review: in_review / approved / rejected、comment: open / resolved、reply: null"
          }
        },
        "required": [
          "id",
          "kind",
          "parentId",
          "content",
          "authorName",
          "createdAt",
          "status"
        ],
        "additionalProperties": false
      },
      "Download": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": ["id", "name", "url", "expiresAt"],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "エラーの種類。各応答の説明にある値を返す。"
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string",
                "format": "uuid"
              }
            },
            "required": ["code", "message", "requestId"],
            "additionalProperties": false
          }
        },
        "required": ["error"],
        "additionalProperties": false
      },
      "ProjectPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Project"
            }
          },
          "nextCursor": {
            "type": ["string", "null"]
          }
        },
        "required": ["items", "nextCursor"],
        "additionalProperties": false
      },
      "CreativePage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Creative"
            }
          },
          "nextCursor": {
            "type": ["string", "null"]
          }
        },
        "required": ["items", "nextCursor"],
        "additionalProperties": false
      },
      "ReviewPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Review"
            }
          },
          "nextCursor": {
            "type": ["string", "null"]
          }
        },
        "required": ["items", "nextCursor"],
        "additionalProperties": false
      },
      "ApiScope": {
        "type": "string",
        "enum": [
          "creatives:read",
          "reviews:read",
          "assets:download",
          "creatives:write",
          "placements:write",
          "comments:write"
        ],
        "description": "キーに付与できる権限。書き込み権限は対応する操作が公開された組織から順に発行できる。"
      },
      "Me": {
        "type": "object",
        "properties": {
          "organization": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": ["id", "name"],
            "additionalProperties": false
          },
          "key": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "prefix": {
                "type": "string",
                "description": "キーの先頭12文字。管理画面の一覧と同じ"
              },
              "scopes": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ApiScope"
                }
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": ["id", "name", "prefix", "scopes", "expiresAt"],
            "additionalProperties": false
          },
          "projects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Project"
            },
            "description": "このキーで取得できるプロジェクト（発行時の対象のうち、いまの取引関係で見られるもの）"
          },
          "rateLimits": {
            "type": "object",
            "description": "組織全体（全キー・API と MCP の合計）の回数上限。契約によって異なる。超えると 429 RATE_LIMITED",
            "properties": {
              "requestsPerMinute": {
                "type": "integer",
                "minimum": 1,
                "description": "1分あたりの上限"
              },
              "requestsPerDay": {
                "type": "integer",
                "minimum": 1,
                "description": "1日あたりの上限（日本時間0時に戻る）"
              }
            },
            "required": ["requestsPerMinute", "requestsPerDay"],
            "additionalProperties": false
          }
        },
        "required": ["organization", "key", "projects", "rateLimits"],
        "additionalProperties": false
      },
      "ProjectDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": ["string", "null"]
          },
          "canUpload": {
            "type": "boolean",
            "description": "キーの発行者がこのプロジェクトへクリエイティブを作成できるか（判定だけで、担当の割り当てや依頼の作成はしない）"
          }
        },
        "required": ["id", "name", "description", "canUpload"],
        "additionalProperties": false
      },
      "ReviewStatus": {
        "type": "string",
        "enum": ["in_review", "approved", "rejected", "correction_completed"],
        "description": "監修の生の状態。status（表示状態）は出稿済み・アーカイブ・保留が承認を隠すため、入稿可否の判定にはこちらと isPlaced / isArchived を使う。"
      },
      "Media": {
        "type": "string",
        "enum": [
          "x",
          "line",
          "meta",
          "youtube",
          "tiktok",
          "yahoo",
          "smartnews",
          "gunosy",
          "google",
          "other"
        ],
        "description": "アップロード時に選んだ想定媒体"
      },
      "VideoQuality": {
        "type": "string",
        "enum": ["original", "hd", "sd"],
        "description": "original=アップロードされた原本、hd=720p H.264、sd=480p H.264（変換済みの動画だけ）"
      },
      "TranscodeStatus": {
        "type": "string",
        "enum": ["queued", "processing", "completed", "not_required", "failed"]
      },
      "Tag": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        },
        "required": ["id", "name"],
        "additionalProperties": false
      },
      "AssetVideo": {
        "type": "object",
        "properties": {
          "transcodeStatus": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/TranscodeStatus"
              },
              {
                "type": "null"
              }
            ],
            "description": "null は変換の記録がない"
          },
          "qualities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VideoQuality"
            },
            "description": "download-urls で指定できる画質。original は常に含む"
          }
        },
        "required": ["transcodeStatus", "qualities"],
        "additionalProperties": false
      },
      "PlatformSystem": {
        "type": "string",
        "enum": [
          "google_ads",
          "meta",
          "yahoo_ads",
          "line_ads",
          "tiktok_ads",
          "x_ads",
          "dsp",
          "other"
        ],
        "description": "配信プラットフォーム。dsp / other は複数の基盤をまとめた値なので externalAccountId が必須"
      },
      "DeliveryState": {
        "type": "string",
        "enum": ["none", "scheduled", "active", "stopped", "rejected"],
        "description": "配信プラットフォーム側の配信状態（AdKura の出稿済みとは独立。出稿済みは PATCH /creatives/{id}/status で更新する）"
      },
      "PlatformReference": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "creativeId": {
            "type": "string",
            "format": "uuid"
          },
          "system": {
            "$ref": "#/components/schemas/PlatformSystem"
          },
          "externalAccountId": {
            "type": "string",
            "description": "広告アカウントID。無いときは空文字"
          },
          "externalId": {
            "type": "string",
            "description": "広告ID・クリエイティブIDなど、プラットフォーム側の識別子"
          },
          "externalParentId": {
            "type": ["string", "null"],
            "description": "キャンペーン・広告グループなど"
          },
          "deliveryState": {
            "$ref": "#/components/schemas/DeliveryState"
          },
          "deliveryStartedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "deliveryEndedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "任意の付加情報（20項目・各1000文字まで）"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "creativeId",
          "system",
          "externalAccountId",
          "externalId",
          "externalParentId",
          "deliveryState",
          "deliveryStartedAt",
          "deliveryEndedAt",
          "metadata",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "PlatformReferencePage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlatformReference"
            }
          }
        },
        "required": ["items"],
        "additionalProperties": false
      },
      "CreativeStatusUpdate": {
        "type": "object",
        "properties": {
          "isPlaced": {
            "type": "boolean",
            "description": "出稿済み"
          },
          "isArchived": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "少なくとも1つを指定する。両方 true は 400。アーカイブ済みの出稿、出稿済みのアーカイブは 409"
      },
      "CreativeStatusResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "isPlaced": {
            "type": "boolean"
          },
          "isArchived": {
            "type": "boolean"
          }
        },
        "required": ["id", "isPlaced", "isArchived"],
        "additionalProperties": false
      },
      "PlatformReferenceUpsert": {
        "type": "object",
        "properties": {
          "system": {
            "$ref": "#/components/schemas/PlatformSystem"
          },
          "externalAccountId": {
            "type": "string",
            "maxLength": 255
          },
          "externalId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "externalParentId": {
            "type": ["string", "null"],
            "maxLength": 255
          },
          "deliveryState": {
            "$ref": "#/components/schemas/DeliveryState"
          },
          "deliveryStartedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "deliveryEndedAt": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": ["system", "externalId"],
        "additionalProperties": false
      },
      "CommentCreate": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": ["text"]
              },
              "content": {
                "type": "string",
                "minLength": 1,
                "maxLength": 5000
              },
              "textRange": {
                "type": ["object", "null"],
                "properties": {
                  "start": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "end": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "text": {
                    "type": "string"
                  }
                },
                "required": ["start", "end", "text"],
                "additionalProperties": false
              }
            },
            "required": ["type", "content"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": ["image"]
              },
              "content": {
                "type": "string",
                "minLength": 1,
                "maxLength": 5000
              },
              "polygon": {
                "type": "object",
                "properties": {
                  "x": {
                    "type": "number"
                  },
                  "y": {
                    "type": "number"
                  },
                  "width": {
                    "type": "number"
                  },
                  "height": {
                    "type": "number"
                  }
                },
                "required": ["x", "y", "width", "height"],
                "additionalProperties": false,
                "description": "画像・動画の指摘範囲（画面と同じ座標系）"
              },
              "assetIndex": {
                "type": "integer",
                "minimum": 0,
                "description": "複数素材のときの素材の並び順"
              }
            },
            "required": ["type", "content", "polygon"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": ["video"]
              },
              "content": {
                "type": "string",
                "minLength": 1,
                "maxLength": 5000
              },
              "polygon": {
                "type": "object",
                "properties": {
                  "x": {
                    "type": "number"
                  },
                  "y": {
                    "type": "number"
                  },
                  "width": {
                    "type": "number"
                  },
                  "height": {
                    "type": "number"
                  }
                },
                "required": ["x", "y", "width", "height"],
                "additionalProperties": false,
                "description": "画像・動画の指摘範囲（画面と同じ座標系）"
              },
              "elapsedTime": {
                "type": "number",
                "minimum": 0,
                "description": "動画の再生位置（秒）"
              },
              "assetIndex": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": ["type", "content", "polygon", "elapsedTime"],
            "additionalProperties": false
          }
        ],
        "description": "コメントは API キーの発行者名義で投稿される。本文中の @メンションは画面と同じく通知される"
      },
      "UploadContentKind": {
        "type": "string",
        "enum": ["image", "video"]
      },
      "UploadRequestFile": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "ファイル名。拡張子で画像（apng/avif/jpg/jpeg/png/gif/bmp/webp）か動画（mp4/mov/webm/avi/wmv/flv/mkv）かを判定する"
          },
          "mimeType": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "PUT で送る Content-Type。拡張子の種類（image/* または video/*）と合わせる"
          },
          "size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1073741824,
            "description": "バイト数。1GBまで。PUT の Content-Length と一致させる"
          }
        },
        "required": ["name", "mimeType", "size"],
        "additionalProperties": false
      },
      "UploadRequest": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid",
            "description": "新規作成の保存先プロジェクト。revisionOf を指定するときは省略できる"
          },
          "creativeRequestId": {
            "type": "string",
            "format": "uuid",
            "description": "任意。代理店が同じプロジェクトで複数の依頼を受けているときに、どの依頼へ作成するかを指定する"
          },
          "revisionOf": {
            "type": "string",
            "format": "uuid",
            "description": "修正版の素材を上げるときの元の版のID。保存先はその版の依頼で決まる"
          },
          "files": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/UploadRequestFile"
            }
          }
        },
        "required": ["files"],
        "additionalProperties": false,
        "description": "projectId か revisionOf のどちらかを指定する"
      },
      "UploadFile": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string",
            "format": "uuid",
            "description": "POST /creatives / POST /creatives/{id}/revisions の fileIds に渡す値"
          },
          "name": {
            "type": "string"
          },
          "contentKind": {
            "$ref": "#/components/schemas/UploadContentKind"
          },
          "uploadUrl": {
            "type": "string",
            "format": "uri",
            "description": "ファイルの実体を PUT する署名付きURL（1時間）。本文はファイルそのもの"
          },
          "method": {
            "type": "string",
            "enum": ["PUT"]
          },
          "headers": {
            "type": "object",
            "properties": {
              "Content-Type": {
                "type": "string"
              },
              "Content-Length": {
                "type": "string"
              },
              "If-None-Match": {
                "type": "string",
                "enum": ["*"]
              }
            },
            "required": ["Content-Type", "Content-Length", "If-None-Match"],
            "additionalProperties": false,
            "description": "PUT に付けるヘッダー。署名に束縛されているので、この値以外では拒否される"
          }
        },
        "required": [
          "fileId",
          "name",
          "contentKind",
          "uploadUrl",
          "method",
          "headers"
        ],
        "additionalProperties": false
      },
      "UploadSession": {
        "type": "object",
        "properties": {
          "uploadId": {
            "type": "string",
            "format": "uuid"
          },
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "creativeRequestId": {
            "type": "string",
            "format": "uuid",
            "description": "作成先の依頼。POST /creatives に creativeRequestId として渡せる"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "予約の期限（発行から2時間）。uploadUrl への PUT は発行から1時間以内に行い、この期限までに POST /creatives で登録する"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UploadFile"
            }
          }
        },
        "required": [
          "uploadId",
          "projectId",
          "creativeRequestId",
          "expiresAt",
          "files"
        ],
        "additionalProperties": false
      },
      "CreativeSourceFiles": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["files"]
          },
          "fileIds": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "POST /uploads で得た fileId。PUT が完了しているもの"
          },
          "mode": {
            "type": "string",
            "enum": ["separate", "bundle"],
            "description": "separate はファイルごとに1件、bundle は画像・動画をまとめて1件"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "bundle のときの表示名"
          },
          "descriptions": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 2000
            },
            "description": "fileId ごとの説明"
          }
        },
        "required": ["kind", "fileIds", "mode"],
        "additionalProperties": false
      },
      "CreativeSourceText": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["text"]
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 20000
          },
          "description": {
            "type": "string",
            "maxLength": 2000
          }
        },
        "required": ["kind", "body"],
        "additionalProperties": false
      },
      "CreativeSourceYoutube": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["youtube"]
          },
          "url": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "YouTube の動画URL。タイトルとサムネイルは YouTube から取得する"
          },
          "description": {
            "type": "string",
            "maxLength": 2000
          }
        },
        "required": ["kind", "url"],
        "additionalProperties": false
      },
      "CreativeCreate": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "creativeRequestId": {
            "type": "string",
            "format": "uuid",
            "description": "任意。POST /uploads の応答の creativeRequestId と同じ値を渡す"
          },
          "source": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CreativeSourceFiles"
              },
              {
                "$ref": "#/components/schemas/CreativeSourceText"
              },
              {
                "$ref": "#/components/schemas/CreativeSourceYoutube"
              }
            ]
          },
          "media": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Media"
            },
            "description": "想定媒体"
          },
          "deadline": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "tagIds": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "プロジェクト所有組織のタグ。必須グループ・単一選択の制約は画面と同じ"
          }
        },
        "required": ["projectId", "source"],
        "additionalProperties": false
      },
      "CreativeCreateResult": {
        "type": "object",
        "properties": {
          "createdIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "作成した版の ID（常に全件）。bundle は1件、separate はファイルの順、修正版は1件"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreativeDetail"
            },
            "description": "作成した版の詳細。作成直後の読み直しに失敗した版は含まれないことがあるので、件数が createdIds と違うときは GET /creatives/{id} で取得する"
          }
        },
        "required": ["createdIds", "items"],
        "additionalProperties": false
      },
      "RevisionSourceFiles": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["files"]
          },
          "fileIds": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "POST /uploads（revisionOf 指定）で得た fileId"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "単体なら新しい版のファイル名、複数画像・まとめなら表示名"
          },
          "descriptions": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 2000
            }
          }
        },
        "required": ["kind", "fileIds"],
        "additionalProperties": false
      },
      "RevisionCreate": {
        "type": "object",
        "properties": {
          "source": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RevisionSourceFiles"
              },
              {
                "$ref": "#/components/schemas/CreativeSourceText"
              },
              {
                "$ref": "#/components/schemas/CreativeSourceYoutube"
              }
            ],
            "description": "元の版と同じ形式で指定する。画像は画像（複数なら1件のまとめ）、動画は動画1件、まとめは画像・動画、テキストはテキスト、YouTubeはYouTube。PDF・記事・スプレッドシートの版には登録できない"
          },
          "deadline": {
            "type": ["string", "null"],
            "format": "date-time"
          }
        },
        "required": ["source"],
        "additionalProperties": false
      }
    }
  }
}
