{
    "openapi": "3.1.0",
    "info": {
        "title": "AdGPT API",
        "version": "1.0.0",
        "description": "# AdGPT API\n\nGenerate ready-to-publish ad creatives programmatically: full campaigns, single assets (images, videos, UGC presenter and in-action videos, Google ad copy), post-generation edits, ad recreation, and publishing to your own connected social ad accounts — the same engine that powers [app.adgpt.com](https://app.adgpt.com).\n\n**Base URL:** `https://api.adgpt.com/api`\n\nAll endpoints live under `/v1`. Responses use a consistent envelope:\n\n```json\n{ \"success\": true, \"data\": { ... }, \"message\": \"...\" }\n```\n\nGeneration is **asynchronous**: a create call returns immediately with an id; you poll a status endpoint until completion (see *Async jobs* below). Every operation that spends credits declares its cost in this reference (`x-credit-cost`).\n\nThis document is generated from the committed API contract, which a CI gate keeps in sync with the routes and validation on every change — so the reference cannot silently drift from the implementation.\n\n## Authentication\n\nAuthenticate every request with an **API key** in the `Authorization` header:\n\n```\nAuthorization: Bearer adgpt_...\n```\n\nCreate and revoke keys from your account settings at app.adgpt.com (Settings → API Keys). The full key is shown **exactly once** at creation — store it securely. Keys inherit your account's permissions and spend your account's credits.\n\n**401 responses** carry a machine-readable `code`: `UNAUTHENTICATED` (missing/invalid/revoked/expired key), or for first-party JWTs `TOKEN_EXPIRED` (refresh and retry). Repeated failed authentication from one IP is throttled (`429`, code `TOO_MANY_ATTEMPTS`).\n\nKeys never work on the first-party web-app endpoints, and key management itself is only available from the logged-in web app — a leaked key cannot mint further keys.\n\nIf your organization has turned off publishing, share links and the social ad-account endpoints answer **`403` (`ORG_PUBLISHING_BLOCKED`)**.\n\n### You can only access your own resources\n\nEvery endpoint is scoped to the account that owns the key. A request for a campaign, asset, brand, catalogue or any other resource that belongs to a different account returns **`404` (`RESOURCE_NOT_FOUND`)** — the same response you get for an id that does not exist, so ids cannot be probed for existence. List endpoints only ever return your own account's resources. Build your integration against the ids you create and receive back from the API.\n\n## Connect from an AI assistant (MCP)\n\nEverything in this reference is also available as an **MCP (Model Context Protocol) server**, generated from the same API contract — so an AI assistant can drive AdGPT for you instead of you writing HTTP calls. Every operation documented here is an MCP tool with the same inputs, credit costs and async behaviour.\n\n**Endpoint:** `https://mcp.adgpt.com/mcp` (Streamable HTTP)\n\nConnecting needs no credentials. A session starts anonymous; sign in (or register) with the account tool inside the conversation, or seed the identity up front by sending `Authorization: Bearer <jwt>` on the `initialize` request. Credits bill the signed-in account. Sessions expire after **30 minutes idle** — sign in again afterwards.\n\n### Connecting a client\n\n- **Claude (web/desktop):** Customize → Connectors → Add custom connector → paste the endpoint URL. On Team and Enterprise plans an Owner adds it under Organization settings → Connectors.\n- **Claude Code:** `claude mcp add --transport http adgpt https://mcp.adgpt.com/mcp`\n- **Any other MCP client** that supports remote Streamable HTTP servers: point it at the same URL.\n\n### Discovery\n\nThe server publishes a server card at `https://mcp.adgpt.com/.well-known/mcp/server-card.json` and is listed in the official MCP registry as `com.adgpt/adgpt`.\n\n### Working with the tools\n\nStart with `adgpt_capabilities` to search the operation surface or describe one operation's schema. Charging operations require an explicit confirm before any credits are spent, and return a job handle you poll with `adgpt_job` — the same status lifecycle described under *Async jobs & polling* below.\n\n## Async jobs & polling\n\nGeneration endpoints return immediately with an id. Poll the operation's status endpoint (declared per-operation as `x-async.statusPath`, with a suggested interval in `x-async.pollHintSeconds`) until a terminal state.\n\nStatus values: `pending → processing → completed | failed` — plus **`awaiting_input`** on interactive flows (UGC and in-action), which means the API is waiting for your `confirm` call (script/character/template selections). Assets appear incrementally in the `assets` endpoints as they finish; failed items are refunded automatically.\n\nDo not poll faster than the hint. Never auto-retry a charging POST blindly — if a request times out, poll the resource's status/list to see whether it was actually created before retrying. (Bulk-generation orders additionally accept an `idempotency_key` so a safe retry returns the original order.)\n\n## Credits & costs\n\nGeneration is paid in **credits** from your AdGPT account (plan credits + add-on credits, spent add-on-first). Buying credits and managing your plan happen in the web app at [app.adgpt.com](https://app.adgpt.com), not through this API. Every charging operation in this reference declares its cost via `x-credit-cost`; pricing endpoints (`/v1/single-assets/pricing`, `/v1/bulk-generations/pricing`) return your tier-resolved numbers.\n\nWhen your balance is too low the API responds `402` with the required and available amounts. Failed generations are refunded automatically in the common paths (single-asset regenerate, bulk-generation items). Check your balance anytime with `GET /v1/me/credits`, and reconcile against the campaign's delivered assets rather than assuming a charge.\n\n## Idempotency\n\n`POST /v1/campaigns`, `POST /v1/single-assets`, and `POST /v1/single-assets/{id}/confirm` accept an optional `Idempotency-Key` header. The same three operations on the canonical `/api` routes accept it too. A missing header is unchanged: the request runs exactly as it does today.\n\nThe key is 8–128 characters matching `[A-Za-z0-9_-]` and is not trimmed. It is scoped to the authenticated account. A guest is scoped by IP, plus `X-Visitor-Fingerprint` or `visitor_fingerprint`, plus `X-Visitor-Token` (or the visitor cookie) when one is present. The slot also includes the controller action and the route parameters. Confirm of campaign A does not collide with confirm of campaign B. The canonical route and its `/v1` alias share one slot because they are the same action. The fingerprint is a hash of the query string and the JSON body, each with object keys sorted and array order preserved.\n\n| Situation | Result |\n| --- | --- |\n| Header missing or empty | Request runs. Nothing is stored. |\n| Invalid key, or more than one value | `422` `INVALID_IDEMPOTENCY_KEY`. Nothing is stored. |\n| Same key and same query and body, after the first request finished | The original status code and JSON body are returned with `Idempotent-Replayed: true`. The handler does not run and credits are not charged again. Stored for 24 hours. |\n| Same key and a different query or body | `422` `IDEMPOTENCY_KEY_REUSED`. The original record is kept. This 422 is computed from that record; it is not cached on its own. |\n| Same key while the first request still holds the lock | `409` `IDEMPOTENCY_IN_PROGRESS` and `Retry-After: 2`. The duplicate does not run. This response is not stored. |\n| The charge committed and the process died before a response was stored | `409` `IDEMPOTENCY_CHARGED`, with `campaign_id` when one was created. Stored for 24 hours. Retrying does not charge again. |\n\nWhat is stored for 24 hours:\n\n- `2xx` responses.\n- Any status, including `5xx`, once the credit charge has committed. A retry replays that response and does not charge again.\n- The `IDEMPOTENCY_CHARGED` marker written at commit time, until the real response overwrites it.\n\nWhat is not stored, so the same key can be retried after the situation changes:\n\n- Anything returned before a charge: `401`, `402`, `403`, `404`, `429`, and `5xx`.\n- Every `422`, including framework validation. Some validation reads live data (brand ownership, character readiness) and must not stick for 24 hours. `IDEMPOTENCY_KEY_REUSED` is the exception in behaviour only: it is answered from the original stored record and does not replace it.\n\nThe lock is non-blocking and is released when the first request finishes. A release failure is logged and does not change the response. If the process dies the lock expires after 10 minutes. The charged marker is already written by then, so the retry still does not charge.\n\n## Rate limits\n\nLimits are enforced **per API key** and declared per-operation in this reference (`x-rate-limit`): a general per-minute limit for reads and light writes, and a stricter limit for generation/charging operations. Exceeded limits return `429` with standard `X-RateLimit-*` and `Retry-After` headers — respect `Retry-After` before retrying.\n\nThese numbers come from the same configuration the API's limiters read, so the documented limits track what is actually enforced."
    },
    "servers": [
        {
            "url": "https://api.adgpt.com/api"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "tags": [
        {
            "name": "ad-recreation"
        },
        {
            "name": "add-brand"
        },
        {
            "name": "brand"
        },
        {
            "name": "brands"
        },
        {
            "name": "campaigns"
        },
        {
            "name": "catalog"
        },
        {
            "name": "catalogs"
        },
        {
            "name": "chat"
        },
        {
            "name": "creative"
        },
        {
            "name": "facebook"
        },
        {
            "name": "full-campaign"
        },
        {
            "name": "pipeline-voices"
        },
        {
            "name": "single-asset-campaign"
        },
        {
            "name": "social-ads-account"
        },
        {
            "name": "taboola"
        },
        {
            "name": "tiktok"
        },
        {
            "name": "ugc"
        },
        {
            "name": "user"
        },
        {
            "name": "user-creative-credits"
        },
        {
            "name": "user-details"
        },
        {
            "name": "v1"
        }
    ],
    "paths": {
        "/v1/ad-recreation/analyze": {
            "post": {
                "operationId": "post.ad-recreation.analyze",
                "tags": [
                    "ad-recreation"
                ],
                "summary": "Ad Recreation Analyze",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": [],
                                "required": [],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/ad-recreation/cancel": {
            "post": {
                "operationId": "post.ad-recreation.cancel",
                "tags": [
                    "ad-recreation"
                ],
                "summary": "Ad Recreation Cancel",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": [],
                                "required": [],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/ad-recreation/generate-from-prompt": {
            "post": {
                "operationId": "post.ad-recreation.generate-from-prompt",
                "tags": [
                    "ad-recreation"
                ],
                "summary": "Ad Clone prompt-first generate",
                "description": "One-shot Ad Clone: type the edit instruction and generate. Duration is derived from the FULL source length (capped, default 60s) — no duration choice, no analysis step (auto-analyzed server-side), captions off. Poll status for progress.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "instruction": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 500
                                    },
                                    "resolution": {
                                        "type": "string",
                                        "enum": [
                                            "720p",
                                            "1080p"
                                        ]
                                    }
                                },
                                "required": [
                                    "instruction"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "120 per started 10s of source video",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.ad-recreation.status",
                    "statusPath": "/v1/ad-recreation/status",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/ad-recreation/ingest-url": {
            "post": {
                "operationId": "post.ad-recreation.ingest-url",
                "tags": [
                    "ad-recreation"
                ],
                "summary": "Ingest ad video URL",
                "description": "Pull a source ad video from a URL (http/https).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2000
                                    }
                                },
                                "required": [
                                    "url"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/ad-recreation/status": {
            "get": {
                "operationId": "get.ad-recreation.status",
                "tags": [
                    "ad-recreation"
                ],
                "summary": "Ad Recreation Status",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/ad-recreation/upload": {
            "post": {
                "operationId": "post.ad-recreation.upload",
                "tags": [
                    "ad-recreation"
                ],
                "summary": "Ad Recreation Upload",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "video": {
                                        "type": "string",
                                        "format": "binary",
                                        "maxLength": 102400,
                                        "description": "Allowed types: mp4,mov,webm,avi,mkv,m4v."
                                    }
                                },
                                "required": [
                                    "video"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/ad-recreation/{assetId}/assets": {
            "get": {
                "operationId": "get.ad-recreation.assetId.assets",
                "tags": [
                    "ad-recreation"
                ],
                "summary": "Ad Recreation AssetId Assets",
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/brands": {
            "get": {
                "operationId": "brands",
                "tags": [
                    "brands"
                ],
                "summary": "Brands",
                "description": "List the account's brands, favourites first. additional_data.last_used_brand carries the brand choice from the most recent campaign — a brand_id, or no_brand: true when that campaign deliberately used none — so a client can pre-select it; null until a campaign has made a choice.",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "post": {
                "operationId": "add-brand-post",
                "tags": [
                    "add-brand"
                ],
                "summary": "Add Brand Post",
                "description": "Create a brand (multipart: name, website_url, tagline, description, colours as RGBA JSON, a logo via logo_image_file or scrape_logo_url). Fonts: a brand holds several — font_id adds a library font, custom_font_files[] uploads font files (ttf/otf/woff/woff2, max 5MB each; each stored under its file name) — and exactly ONE is the primary, the font campaign generation uses: primary_font_name names it (a library font, or an uploaded file's name without extension); omitted, a library font_id or else the first upload becomes primary. The response carries fonts[] with font_name and is_primary.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "website_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 255
                                    },
                                    "description": {
                                        "type": "string"
                                    },
                                    "tagline": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "font_color_rgba_json": {
                                        "type": "string"
                                    },
                                    "background_color_rgba_json": {
                                        "type": "string"
                                    },
                                    "background_color_two_rgba_json": {
                                        "type": "string"
                                    },
                                    "logo_image_file": {
                                        "type": "string",
                                        "format": "binary",
                                        "maxLength": 10240,
                                        "description": "Allowed types: jpeg,png,jpg,gif,bmp,webp."
                                    },
                                    "scrape_logo_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "product_catalog_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "font_id": {
                                        "type": "integer"
                                    },
                                    "primary_font_name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "custom_font_files": {
                                        "type": "array",
                                        "maxItems": 20,
                                        "items": {
                                            "type": "string",
                                            "format": "binary",
                                            "maxLength": 5120,
                                            "description": "Allowed types: font/*,application/vnd.ms-opentype,application/font-sfnt,application/x-font-ttf,application/x-font-otf,application/x-font-opentype,application/x-font-woff,application/font-woff,application/font-woff2."
                                        }
                                    }
                                },
                                "required": [
                                    "name"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/brands/fetch-details": {
            "post": {
                "operationId": "brand-fetch",
                "tags": [
                    "brand"
                ],
                "summary": "Auto-fetch brand details",
                "description": "Extract brand name/description/logo/colors from a website URL . Costs 5 credits — 402 with required-credits payload when short.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "website_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048
                                    },
                                    "brand_id": {
                                        "type": "integer",
                                        "description": "Existing brand to refresh."
                                    },
                                    "skip_ai_usage": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "website_url"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": 5,
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/brands/{brand_id}": {
            "delete": {
                "operationId": "delete-brand",
                "tags": [
                    "brand"
                ],
                "summary": "Delete Brand",
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "get": {
                "operationId": "show-brand",
                "tags": [
                    "brand"
                ],
                "summary": "Show Brand",
                "description": "GET /brand/{brand_id} — the brand with its fonts[] (font_name, is_primary — the primary is the font campaign generation uses, custom_font_path for uploads, font for library picks).",
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "put": {
                "operationId": "update-brand",
                "tags": [
                    "brand"
                ],
                "summary": "Update Brand",
                "description": "Update a brand (same multipart fields as create; name is required). Fonts APPEND: custom_font_files[] adds uploads and font_id adds a library font without dropping stored fonts; primary_font_name switches the primary (the font campaign generation uses) to any stored font, the library font or a file of this upload — an unknown name is a 422 and nothing is stored; with no font fields the fonts are untouched. The response carries fonts[] with font_name and is_primary.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "website_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 255
                                    },
                                    "description": {
                                        "type": "string"
                                    },
                                    "tagline": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "font_color_rgba_json": {
                                        "type": "string"
                                    },
                                    "background_color_rgba_json": {
                                        "type": "string"
                                    },
                                    "background_color_two_rgba_json": {
                                        "type": "string"
                                    },
                                    "logo_image_file": {
                                        "type": "string",
                                        "format": "binary",
                                        "maxLength": 10240,
                                        "description": "Allowed types: jpeg,png,jpg,gif,bmp,webp."
                                    },
                                    "scrape_logo_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "product_catalog_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "font_id": {
                                        "type": "integer"
                                    },
                                    "primary_font_name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "custom_font_files": {
                                        "type": "array",
                                        "maxItems": 20,
                                        "items": {
                                            "type": "string",
                                            "format": "binary",
                                            "maxLength": 5120,
                                            "description": "Allowed types: font/*,application/vnd.ms-opentype,application/font-sfnt,application/x-font-ttf,application/x-font-otf,application/x-font-opentype,application/x-font-woff,application/font-woff,application/font-woff2."
                                        }
                                    }
                                },
                                "required": [
                                    "name"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/bulk-generations": {
            "post": {
                "operationId": "v1.bulk-generations.store",
                "tags": [
                    "v1"
                ],
                "summary": "Create bulk order",
                "description": "Order N assets of ONE type in a single request (asset_type + quantity up to the per-type cap; product_url OR user_instructions). Credits are charged upfront; failed items auto-refund. Poll with the bulk order status operation.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "image",
                                            "video",
                                            "ugc_video",
                                            "ugc_action",
                                            "google_ads"
                                        ]
                                    },
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 1
                                    },
                                    "product_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 10000,
                                        "description": "Conditionally required (required_without: user_instructions)."
                                    },
                                    "user_instructions": {
                                        "type": "array"
                                    },
                                    "brand_id": {
                                        "type": "integer",
                                        "description": "References brands,id,user_id,\"NULL\"."
                                    },
                                    "no_brand": {
                                        "type": "boolean"
                                    },
                                    "aspect_ratio": {
                                        "type": "string",
                                        "maxLength": 10
                                    },
                                    "video_duration": {
                                        "type": "string",
                                        "maxLength": 5
                                    },
                                    "ugc_video_duration": {
                                        "type": "integer",
                                        "enum": [
                                            "15",
                                            "30",
                                            "60"
                                        ]
                                    },
                                    "idempotency_key": {
                                        "type": "string",
                                        "maxLength": 64
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "quantity"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "per item by asset_type (see v1/bulk-generations/pricing); charged upfront, failed items auto-refund",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "v1.bulk-generations.show",
                    "statusPath": "/v1/bulk-generations/{id}",
                    "pollHintSeconds": 15
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/bulk-generations/pricing": {
            "get": {
                "operationId": "v1.bulk-generations.pricing",
                "tags": [
                    "v1"
                ],
                "summary": "Bulk pricing",
                "description": "Per-asset-type bulk pricing: credit cost per item and the max quantity per order.",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/bulk-generations/{id}": {
            "get": {
                "operationId": "v1.bulk-generations.show",
                "tags": [
                    "v1"
                ],
                "summary": "Bulk order status",
                "description": "Status of a bulk-generation order: per-item progress counts, credits charged and auto-refunded.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/bulk-generations/{id}/assets": {
            "get": {
                "operationId": "v1.bulk-generations.assets",
                "tags": [
                    "v1"
                ],
                "summary": "Bulk order assets",
                "description": "List the delivered assets of a bulk-generation order (download URLs per completed item).",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/bulk-generations/{id}/cancel": {
            "post": {
                "operationId": "v1.bulk-generations.cancel",
                "tags": [
                    "v1"
                ],
                "summary": "Cancel bulk order",
                "description": "Cancel the un-started remainder of a bulk-generation order; credits for never-started items auto-refund.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": [],
                                "additionalProperties": false
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/campaigns": {
            "post": {
                "operationId": "full-campaign.create",
                "tags": [
                    "full-campaign"
                ],
                "summary": "Create Full Campaign",
                "description": "Generate a full multi-asset campaign. Per campaign (platform defaults): 6 image ads (every one with a text overlay; 3 additional text-free variants are rendered behind the scenes solely for the editorial article and are not presented), 4 video ads, 3 UGC presenter videos, 12 Google ad copy variations, 10 keywords, plus social captions. Tier (base/pro/premium) changes price and UGC render quality — NOT asset counts. Product input — exactly ONE mode: (1) crawl: product_url (+optional alternative_product_url fallback); (2) manual: user_instructions.product_name + product_description + ≥1 uploaded_images; (3) text-only: product_name + product_description with no URL and no images. Otherwise 422 MISSING_PRODUCT_INPUT. Upload local product photos first with the adgpt_upload_product_image tool — it returns the S3 url for uploaded_images. brand_id must be a brand you own (auth required) and is never auto-created from the crawled site — create the brand first or pass no_brand. First campaign is free + watermarked. Async — poll with adgpt_job. Optional Idempotency-Key header (8-128 of [A-Za-z0-9_-]): a retry with the same key, query string, and body replays the stored response and does not charge again. A response after a committed charge is stored whatever its status. A 422 is not stored.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "product_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 10000,
                                        "description": "Product page URL (crawl mode)."
                                    },
                                    "alternative_product_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 10000,
                                        "description": "Fallback URL retried if the primary crawl fails."
                                    },
                                    "visitor_fingerprint": {
                                        "type": "string",
                                        "maxLength": 128,
                                        "description": "Guest dedup fingerprint (unauthenticated flows)."
                                    },
                                    "brand_id": {
                                        "type": "integer",
                                        "description": "ID of a brand you own."
                                    },
                                    "no_brand": {
                                        "type": "boolean",
                                        "description": "Skip brand auto-detection from the URL."
                                    },
                                    "campaign_kind": {
                                        "type": "string",
                                        "enum": [
                                            "standard",
                                            "performance"
                                        ],
                                        "description": "Funnel variant. Omit (or standard) for the classic flow; performance adds 3 × 30s commercial videos (currently admin-only while it rolls out)."
                                    },
                                    "industry": {
                                        "type": "string",
                                        "enum": [
                                            "books",
                                            "wellness",
                                            "general",
                                            "coaches",
                                            "online_course"
                                        ],
                                        "description": "Landing-page industry hint that pins the go-live routing bucket (media_industry) for this campaign. Omit to have it derived from the crawl classifier."
                                    },
                                    "user_instructions": {
                                        "type": "object",
                                        "properties": {
                                            "general": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "Shared creative brief applied across assets."
                                            },
                                            "general_english": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "English translation of the general brief."
                                            },
                                            "original_language": {
                                                "type": "string",
                                                "maxLength": 10,
                                                "description": "ISO language code of the original brief."
                                            },
                                            "product_name": {
                                                "type": "string",
                                                "maxLength": 120,
                                                "description": "Product name (manual / text-only input modes)."
                                            },
                                            "product_description": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "Product description (manual / text-only input modes)."
                                            },
                                            "per_asset": {
                                                "type": "object",
                                                "properties": {
                                                    "image": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "instruction": {
                                                                    "type": "string",
                                                                    "maxLength": 2000,
                                                                    "description": "Scene/visual direction for this image slot."
                                                                },
                                                                "instruction_original": {
                                                                    "type": "string",
                                                                    "maxLength": 2000
                                                                },
                                                                "copy": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "title": {
                                                                            "type": "string",
                                                                            "maxLength": 25,
                                                                            "description": "On-image overlay title."
                                                                        },
                                                                        "subtitle": {
                                                                            "type": "string",
                                                                            "maxLength": 35
                                                                        },
                                                                        "cta": {
                                                                            "type": "string",
                                                                            "maxLength": 12
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 20,
                                                        "description": "Per-image-slot direction. copy = on-image text (videos have NO copy)."
                                                    },
                                                    "video": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "instruction": {
                                                                    "type": "string",
                                                                    "maxLength": 5000,
                                                                    "description": "Scene direction for this video slot."
                                                                },
                                                                "instruction_original": {
                                                                    "type": "string",
                                                                    "maxLength": 5000
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 10
                                                    },
                                                    "ugc": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "script": {
                                                                    "type": "string",
                                                                    "maxLength": 5000,
                                                                    "description": "UGC presenter script (required within an entry)."
                                                                },
                                                                "script_original": {
                                                                    "type": "string",
                                                                    "maxLength": 5000
                                                                },
                                                                "language": {
                                                                    "type": "string",
                                                                    "maxLength": 10
                                                                },
                                                                "target_duration_sec": {
                                                                    "type": "integer",
                                                                    "description": "Target spoken duration.",
                                                                    "minimum": 5,
                                                                    "maximum": 180
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 10
                                                    }
                                                }
                                            },
                                            "uploaded_images": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string",
                                                    "format": "uri",
                                                    "maxLength": 2048
                                                },
                                                "maxItems": 5,
                                                "description": "Product image URLs. MUST be S3 chat-upload URLs from AdGPT uploads (…/uploads/chat-product-images/…) — arbitrary external URLs are rejected."
                                            }
                                        },
                                        "description": "Optional customization payload shared by FC and SAC."
                                    }
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Optional. 8-128 characters of [A-Za-z0-9_-]. The same key, query string, and JSON body replay the stored response for 24 hours and do not charge again. A different query or body is 422 IDEMPOTENCY_KEY_REUSED. A duplicate while the first request is still running is 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Once a charge has committed, the response is stored whatever its status, including 5xx. If the process dies after the charge, a retry receives 409 IDEMPOTENCY_CHARGED and does not charge again. A replay includes Idempotent-Replayed: true. Responses returned before a charge, and every 422, are not stored.",
                        "schema": {
                            "type": "string",
                            "minLength": 8,
                            "maxLength": 128,
                            "pattern": "^[A-Za-z0-9_-]{8,128}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Either this Idempotency-Key is already in progress (IDEMPOTENCY_IN_PROGRESS, Retry-After, not stored) or the charge already committed and no final response was stored (IDEMPOTENCY_CHARGED, stored for 24 hours; do not charge again).",
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds to wait before retrying this key.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "config:full_campaign.user_credit_cost (500 standard / 750 pro / 1500 premium)",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "full-campaign.status",
                    "statusPath": "/v1/campaigns/{id}/status",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/campaigns/eligibility": {
            "get": {
                "operationId": "full-campaign.eligibility",
                "tags": [
                    "full-campaign"
                ],
                "summary": "Full Campaign Eligibility",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/campaigns/{id}/assets": {
            "get": {
                "operationId": "full-campaign.assets",
                "tags": [
                    "full-campaign"
                ],
                "summary": "Full Campaign Assets",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "grouped",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "description": "Group assets by type."
                        }
                    },
                    {
                        "name": "partial",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/campaigns/{id}/download-all": {
            "get": {
                "operationId": "full-campaign.download-all",
                "tags": [
                    "full-campaign"
                ],
                "summary": "Full Campaign Download All",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/campaigns/{id}/status": {
            "get": {
                "operationId": "full-campaign.status",
                "tags": [
                    "full-campaign"
                ],
                "summary": "Full Campaign Status",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/catalogs": {
            "get": {
                "operationId": "get.catalogs",
                "tags": [
                    "catalogs"
                ],
                "summary": "Catalogs",
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "description": "References brands,id."
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100
                        }
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "min_price",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "number",
                            "minimum": 0,
                            "description": "Conditionally required (required_with: max_price)."
                        }
                    },
                    {
                        "name": "max_price",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "number",
                            "minimum": 0,
                            "description": "Conditionally required (required_with: min_price)."
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "post": {
                "operationId": "post.catalog",
                "tags": [
                    "catalog"
                ],
                "summary": "Catalog",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "brand_id": {
                                        "type": "integer",
                                        "description": "References brands,id."
                                    },
                                    "0": [],
                                    "product_catalog_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "source_type": {
                                        "type": "string",
                                        "enum": [
                                            "xml",
                                            "shopify"
                                        ]
                                    }
                                },
                                "required": [
                                    "brand_id",
                                    "product_catalog_url",
                                    "source_type"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/catalogs/{brand_id}/import-status": {
            "get": {
                "operationId": "get.catalogs.brand_id.import-status",
                "tags": [
                    "catalogs"
                ],
                "summary": "Catalogs Brand Id Import Status",
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/catalogs/{id}": {
            "get": {
                "operationId": "get.catalog.id",
                "tags": [
                    "catalog"
                ],
                "summary": "Catalog Id",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "post": {
                "operationId": "post.catalog.id",
                "tags": [
                    "catalog"
                ],
                "summary": "Catalog Id",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Path parameter."
                                    }
                                },
                                "required": [
                                    "id"
                                ],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/creatives/ad-view/{platform_name}/{asset_id}": {
            "get": {
                "operationId": "get.creative.social-media.ad-view.platform_name.asset_id",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Social Media Ad View Platform Name Asset Id",
                "parameters": [
                    {
                        "name": "platform_name",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "asset_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "ad_type",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "image",
                                "video",
                                "ugc_video",
                                "grid_image"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/creatives/share-link": {
            "post": {
                "operationId": "creative.get-share-link",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Get Share Link",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "creative_request_item_id": {
                                        "description": "References creative_request_items,id."
                                    },
                                    "asset_id": {
                                        "description": "References assets,id."
                                    },
                                    "asset_source": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "description": {
                                        "type": "string"
                                    },
                                    "adType": {
                                        "type": "string",
                                        "enum": [
                                            "static",
                                            "video"
                                        ]
                                    }
                                },
                                "required": [
                                    "adType"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/creatives/{assetId}/translate": {
            "post": {
                "operationId": "post.creative.commercial.assets.assetId.translate",
                "tags": [
                    "creative"
                ],
                "summary": "Translate a commercial",
                "description": "Re-narrate a finished COMMERCIAL video ad in other languages — one new video version per language, each with a native voiceover and the caption to match. The picture is untouched: same cut, same product, same timing, only the voice and copy change. Commercial video ads ONLY (409 on any other ad type — a presenter's lip-sync is never re-cut). `languages` are 2–3 letter codes from the supported catalogue (the same 34 languages as static-ad translate), up to the whole catalogue in one request. Each language is billed at most once per ad: duplicates collapse, and the ad's own language, a language the ad already has (finished or still rendering) and an unsupported code are skipped without charge while the rest still go. Only when nothing billable is left is the request refused (422, with the reason) — nothing is charged. A language whose earlier render failed (refunded) may be ordered again. Charge is per language actually started and quoted back as credits_charged; a language that fails to render refunds only its own credits. Async — each version starts PROCESSING; resolve via the asset's versions.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "languages": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 34,
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "required": [
                                    "languages"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "10 per language started (config:creative_edit.commercial_translate_credit_cost); skipped languages are not charged",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.creative.edit-in-action.assets.assetId.versions",
                    "statusPath": "/v1/edits/in-action/assets/{assetId}/versions",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/creatives/{asset_id}/caption": {
            "patch": {
                "operationId": "patch.creative.edit-asset.asset_id",
                "tags": [
                    "creative"
                ],
                "summary": "Edit asset caption",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "caption": {
                                        "type": "string",
                                        "minLength": 1
                                    },
                                    "platform": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "caption",
                                    "platform"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "asset_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/image/assets/{assetType}/{assetId}/versions": {
            "get": {
                "operationId": "get.creative.edit-creative.assets.assetType.assetId.versions",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Assets AssetType AssetId Versions",
                "parameters": [
                    {
                        "name": "assetType",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/image/overlay": {
            "post": {
                "operationId": "post.creative.edit-creative.overlay",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Overlay",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "overlay_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "x": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "y": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "width": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "height": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "rotation": {
                                        "type": "number",
                                        "minimum": -360,
                                        "maximum": 360
                                    },
                                    "feather": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "harmonize": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "overlay_url",
                                    "x",
                                    "y",
                                    "width",
                                    "height"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/image/prompt": {
            "post": {
                "operationId": "post.creative.edit-creative.prompt",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Prompt",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "prompt": {
                                        "type": "string",
                                        "maxLength": 2000
                                    },
                                    "reference_images": {
                                        "type": "array",
                                        "maxItems": 5,
                                        "items": {
                                            "type": "string",
                                            "format": "uri"
                                        }
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "prompt"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/image/revert": {
            "post": {
                "operationId": "post.creative.edit-creative.revert",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Revert",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/image/translate": {
            "post": {
                "operationId": "post.creative.edit-creative.translate",
                "tags": [
                    "creative"
                ],
                "summary": "Translate a static ad",
                "description": "Re-render a finished STATIC IMAGE ad with its copy in other languages — one new version per language, same photograph, product, layout and colours. Only the advertiser's own words change: brand marks and logo lockups, text printed on the product or its packaging (a book cover included), prices, numbers and dates all come back untouched. Works on both `single_asset` and `full_campaign` image ads. `languages` are 2–3 letter codes, at most 12 per request (config:creative_edit.image_translate_max_languages) — a longer list is refused (422) before the ad is read or anything is charged, never truncated. The ad's own language, duplicates, unsupported scripts and languages it already has (finished or still rendering) are skipped without charge; only an empty result is rejected (422, with the reason). A TEXT-FREE variant of an ad has nothing to translate and is refused (422) before anything is charged, as is an ad whose copy cannot be read. Charge is per language, quoted back as credits_charged; a language that fails to render refunds only its own credits. Async — each version starts PROCESSING and lands as a CANDIDATE alongside the original, which stays the live ad until you keep one.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "languages": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 12,
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "languages"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "25 per language started (config:creative_edit.image_translate_credit_cost); skipped languages are not charged",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.creative.edit-creative.assets.assetType.assetId.versions",
                    "statusPath": "/v1/edits/image/assets/{assetType}/{assetId}/versions",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/image/upload-overlay": {
            "post": {
                "operationId": "post.creative.edit-creative.upload-overlay",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Upload Overlay",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "overlay": {
                                        "type": "string",
                                        "format": "binary",
                                        "maxLength": 10240,
                                        "description": "Allowed types: jpeg,png,jpg,webp."
                                    }
                                },
                                "required": [
                                    "overlay"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/image/versions/{version}/discard": {
            "post": {
                "operationId": "post.creative.edit-creative.versions.version.discard",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Versions Version Discard",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "version": {
                                        "type": "integer",
                                        "description": "Path parameter."
                                    }
                                },
                                "required": [
                                    "version"
                                ],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "version",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/image/versions/{version}/keep": {
            "post": {
                "operationId": "post.creative.edit-creative.versions.version.keep",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Versions Version Keep",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "version": {
                                        "type": "integer",
                                        "description": "Path parameter."
                                    }
                                },
                                "required": [
                                    "version"
                                ],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "version",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/music": {
            "post": {
                "operationId": "post.creative.edit-in-action.assets.assetId.music",
                "tags": [
                    "creative"
                ],
                "summary": "In-action music change",
                "description": "Swap/remove background music (free, pure re-stitch). track_key from the music catalog; remove=true (or null track_key) → voiceover-only.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assetId": {
                                        "type": "integer"
                                    },
                                    "track_key": {
                                        "type": "string",
                                        "maxLength": 1024,
                                        "description": "Catalog s3_key; null/omitted with remove → no music."
                                    },
                                    "bucket": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "volume": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "remove": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "assetId"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/prompt": {
            "post": {
                "operationId": "post.creative.edit-in-action.assets.assetId.prompt",
                "tags": [
                    "creative"
                ],
                "summary": "In-action prompt edit",
                "description": "Natural-language change routed to the affected scene(s) (scene router); charge = 100 credits × scenes affected. Async candidate — resolve via versions.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assetId": {
                                        "type": "integer",
                                        "description": "Asset id (path)."
                                    },
                                    "instruction": {
                                        "type": "string",
                                        "maxLength": 2000
                                    },
                                    "reference_images": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "uri"
                                        },
                                        "maxItems": 5,
                                        "description": "Product photos used as generation reference images."
                                    }
                                },
                                "required": [
                                    "assetId",
                                    "instruction"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "100 per scene affected",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.creative.edit-in-action.assets.assetId.versions",
                    "statusPath": "/v1/edits/in-action/assets/{assetId}/versions",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/revert": {
            "post": {
                "operationId": "post.creative.edit-in-action.assets.assetId.revert",
                "tags": [
                    "creative"
                ],
                "summary": "Revert in-action edits",
                "description": "Restore the asset to its original render.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assetId": {
                                        "type": "integer"
                                    }
                                },
                                "required": [
                                    "assetId"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/state": {
            "get": {
                "operationId": "get.creative.edit-in-action.assets.assetId.state",
                "tags": [
                    "creative"
                ],
                "summary": "In-action editor state",
                "description": "Post-generation editor state for a completed UGC-in-Action or COMMERCIAL video ad: is_editable, video_url, duration, script (text/tagged/voice/language), music (track_key/removed/volume), product_images, versions, and voice_picker {enabled, language} (narrator swap — commercial ads only).",
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/tag-script": {
            "post": {
                "operationId": "post.creative.edit-in-action.assets.assetId.tag-script",
                "tags": [
                    "creative"
                ],
                "summary": "In-action tag script",
                "description": "Insert whitelisted expression tags into a script (word-preserving). Free.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assetId": {
                                        "type": "integer"
                                    },
                                    "script_text": {
                                        "type": "string",
                                        "minLength": 5,
                                        "maxLength": 5000
                                    }
                                },
                                "required": [
                                    "assetId",
                                    "script_text"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/versions": {
            "get": {
                "operationId": "get.creative.edit-in-action.assets.assetId.versions",
                "tags": [
                    "creative"
                ],
                "summary": "In-action versions",
                "description": "Version history + current narration + edit context for a UGC-in-Action or Commercial video ad.",
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/voiceover": {
            "post": {
                "operationId": "post.creative.edit-in-action.assets.assetId.voiceover",
                "tags": [
                    "creative"
                ],
                "summary": "In-action voiceover edit",
                "description": "Re-dub the narration (pure re-stitch, no video regen). delivery 0=Natural…1=Expressive (0.5 = production default). niqqud_text is dubbed verbatim when given. 40 credits.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assetId": {
                                        "type": "integer",
                                        "description": "Asset id (path)."
                                    },
                                    "script": {
                                        "type": "string",
                                        "maxLength": 5000,
                                        "description": "May carry inline expression tags. Required unless niqqud_text is set."
                                    },
                                    "niqqud_text": {
                                        "type": "string",
                                        "maxLength": 5000,
                                        "description": "Vowel-pointed Hebrew, dubbed verbatim."
                                    },
                                    "voice_id": {
                                        "type": "integer",
                                        "description": "Narrator voice swap — honored for COMMERCIAL video ads only (dropped for UGC-in-Action, whose presenter lip-sync is never re-cut); defaults to the ad's current voice. Valid ids come from the voices catalog; the state operation's voice_picker says whether swapping is enabled for this asset."
                                    },
                                    "emotion": {
                                        "type": "string",
                                        "maxLength": 200
                                    },
                                    "addressee_gender": {
                                        "type": "string",
                                        "enum": [
                                            "female",
                                            "male",
                                            "neutral"
                                        ]
                                    },
                                    "narrator_gender": {
                                        "type": "string",
                                        "enum": [
                                            "female",
                                            "male",
                                            "neutral"
                                        ]
                                    },
                                    "delivery": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    }
                                },
                                "required": [
                                    "assetId"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": 40,
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/in-action/assets/{assetId}/voiceover/preview": {
            "post": {
                "operationId": "post.creative.edit-in-action.assets.assetId.voiceover.preview",
                "tags": [
                    "creative"
                ],
                "summary": "In-action voiceover preview",
                "description": "Hear the line before committing. niqqud_only=true returns the niqqud text with no audio and no charge.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assetId": {
                                        "type": "integer"
                                    },
                                    "script": {
                                        "type": "string",
                                        "maxLength": 5000
                                    },
                                    "niqqud_text": {
                                        "type": "string",
                                        "maxLength": 5000
                                    },
                                    "voice_id": {
                                        "type": "integer",
                                        "description": "Preview with a different narrator — honored for COMMERCIAL video ads only (see voice_picker on the state operation)."
                                    },
                                    "emotion": {
                                        "type": "string",
                                        "maxLength": 200
                                    },
                                    "delivery": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "niqqud_only": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "assetId"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/in-action/music-tracks": {
            "get": {
                "operationId": "get.creative.edit-in-action.music-tracks",
                "tags": [
                    "creative"
                ],
                "summary": "In-action music catalog",
                "description": "Usable music tracks (≤200): key (s3), bucket, title, mood, preview_url, duration. Dynamic — read before changing music.",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/versions/{version}/discard": {
            "post": {
                "operationId": "post.creative.edit-in-action.versions.version.discard",
                "tags": [
                    "creative"
                ],
                "summary": "Discard in-action version",
                "description": "Discard a candidate version.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "version": {
                                        "type": "integer"
                                    }
                                },
                                "required": [
                                    "version"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "version",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/in-action/versions/{version}/keep": {
            "post": {
                "operationId": "post.creative.edit-in-action.versions.version.keep",
                "tags": [
                    "creative"
                ],
                "summary": "Keep in-action version",
                "description": "Promote a candidate version to live (kept edits compose).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "version": {
                                        "type": "integer",
                                        "description": "Version id (path)."
                                    }
                                },
                                "required": [
                                    "version"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "version",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/subtitles/assets/{assetType}/{assetId}": {
            "get": {
                "operationId": "subtitle-edit.state",
                "tags": [
                    "creative"
                ],
                "summary": "Subtitle editor state",
                "description": "The editable caption lines of a finished UGC presenter video ad (assetType single_asset): supported (false when the ad has no editable captions or the editor is not open to the account), enabled, rendering (a new subtitle version is being rendered; lines then shows what it will show), video_url (the video in use — it changes when the new version is delivered), lines [{text, start, end, timed}] in seconds sorted by start (timed = the line shows exactly over [start, end); an untimed line keeps the original caption pacing), duration (the video length in seconds = the latest end a line may have), language, dir (rtl|ltr), has_original, credit_cost, renders_left, last_error (the last subtitle re-render's failure, if any), failed_lines (the lines of a re-render that failed — send them again to retry; null otherwise) and version (send it back on apply; a changed state answers 409 stale). Poll it after apply until rendering is false.",
                "parameters": [
                    {
                        "name": "assetType",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "post": {
                "operationId": "subtitle-edit.apply",
                "tags": [
                    "creative"
                ],
                "summary": "Edit subtitles",
                "description": "Fix, retime, add, remove or hide the burned-in caption lines of a finished UGC presenter video ad (assetType single_asset; read the state op first and send its version back). lines = the FULL set of caption lines to show, each {text, start, end} in seconds (the server sorts them by start); a line left out is removed. A line whose start and end match a current line (state lines[]) keeps its timing and look, and only its text is checked (trimmed, 1-200 characters). A new or retimed line must last at least 0.3s, end by the state op's duration and not overlap its neighbours (0.01s tolerance); it then shows exactly over [start, end). enabled=false hides the captions (lines, if sent, are kept as the draft); reset=true restores the original captions and turns them on (lines is ignored) — instantly, with no render, when the ad's original is on file. Every other apply renders a NEW VERSION of the ad: the ad keeps its current video while it renders, and the delivered render becomes the ad's video (video_url) and current version; earlier versions stay restorable. Free by default (credit_cost in the state). 409 with reason rendering (a render is in flight), unsupported (not a composited UGC ad) or stale (the subtitles changed since the state was read — read it again), 429 with reason render_cap (per-ad re-render limit), 402 when a set credit cost exceeds the balance, 403 for an ad the account does not own or an account the editor is not open to, 422 with errors keyed lines.N.text|start|end. Async — poll the state op until rendering is false; a failed render leaves the ad's video unchanged, sets last_error and returns your lines as failed_lines.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assetType": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset"
                                        ],
                                        "description": "single_asset only for now (full_campaign answers 422)."
                                    },
                                    "assetId": {
                                        "type": "integer",
                                        "description": "ugc_video asset id (path)."
                                    },
                                    "enabled": {
                                        "type": "boolean",
                                        "description": "false hides the captions (lines, if sent, are kept as the draft); true shows them."
                                    },
                                    "lines": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 300,
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "text": {
                                                    "type": "string",
                                                    "minLength": 1,
                                                    "maxLength": 200,
                                                    "description": "The caption line as it should appear (trimmed)."
                                                },
                                                "start": {
                                                    "type": "number",
                                                    "minimum": 0,
                                                    "description": "Seconds from the start of the video."
                                                },
                                                "end": {
                                                    "type": "number",
                                                    "minimum": 0,
                                                    "description": "Seconds; at most the state op's duration. Keep start and end of an untouched line as read to keep its timing."
                                                }
                                            },
                                            "required": [
                                                "text",
                                                "start",
                                                "end"
                                            ]
                                        },
                                        "description": "The FULL set of caption lines to show. Required while the captions are shown (enabled=true without reset)."
                                    },
                                    "reset": {
                                        "type": "boolean",
                                        "description": "Restore the original captions and turn them on (lines is ignored)."
                                    },
                                    "version": {
                                        "type": "string",
                                        "maxLength": 64,
                                        "description": "The state op's version token. Always send it: when the subtitles changed since you read them the apply answers 409 with reason stale instead of overwriting the newer edit — read the state again."
                                    }
                                },
                                "required": [
                                    "assetType",
                                    "assetId",
                                    "enabled"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "assetType",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "subtitle-edit.state",
                    "statusPath": "/v1/edits/subtitles/assets/{assetType}/{assetId}",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/video/assets/{assetType}/{assetId}/versions": {
            "get": {
                "operationId": "get.creative.edit-creative.video.assets.assetType.assetId.versions",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Video Assets AssetType AssetId Versions",
                "parameters": [
                    {
                        "name": "assetType",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "assetId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/video/narration": {
            "post": {
                "operationId": "post.creative.edit-creative.video.narration",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Video Narration",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "voiceover": {
                                        "type": "string",
                                        "maxLength": 2000
                                    },
                                    "addressee_gender": {
                                        "type": "string",
                                        "enum": [
                                            "female",
                                            "male",
                                            "neutral"
                                        ]
                                    },
                                    "pronunciation_notes": {
                                        "type": "string",
                                        "maxLength": 500
                                    },
                                    "niqqud_text": {
                                        "type": "string",
                                        "maxLength": 4000
                                    },
                                    "narrator_gender": {
                                        "type": "string",
                                        "enum": [
                                            "female",
                                            "male"
                                        ]
                                    },
                                    "emotion": {
                                        "type": "string",
                                        "maxLength": 100
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "voiceover"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.creative.edit-creative.video.assets.assetType.assetId.versions",
                    "statusPath": "/v1/edits/video/assets/{assetType}/{assetId}/versions",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/video/narration/preview": {
            "post": {
                "operationId": "post.creative.edit-creative.video.narration.preview",
                "tags": [
                    "creative"
                ],
                "summary": "Preview edited-video narration",
                "description": "Synthesize a preview of a re-dubbed video narration (charges a small preview fee).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "voiceover": {
                                        "type": "string",
                                        "maxLength": 2000
                                    },
                                    "addressee_gender": {
                                        "type": "string",
                                        "enum": [
                                            "female",
                                            "male",
                                            "neutral"
                                        ]
                                    },
                                    "pronunciation_notes": {
                                        "type": "string",
                                        "maxLength": 500
                                    },
                                    "niqqud_text": {
                                        "type": "string",
                                        "maxLength": 4000
                                    },
                                    "narrator_gender": {
                                        "type": "string",
                                        "enum": [
                                            "female",
                                            "male"
                                        ]
                                    },
                                    "emotion": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "niqqud_only": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "voiceover"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/video/overlay": {
            "post": {
                "operationId": "post.creative.edit-creative.video.overlay",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Video Overlay",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "overlay_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "x": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "y": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "width": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "height": {
                                        "type": "number",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "rotation": {
                                        "type": "number",
                                        "minimum": -360,
                                        "maximum": 360
                                    },
                                    "start_seconds": {
                                        "type": "number",
                                        "minimum": 0
                                    },
                                    "end_seconds": {
                                        "type": "number",
                                        "minimum": 0
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "overlay_url",
                                    "x",
                                    "y",
                                    "width",
                                    "height"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.creative.edit-creative.video.assets.assetType.assetId.versions",
                    "statusPath": "/v1/edits/video/assets/{assetType}/{assetId}/versions",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/video/prompt": {
            "post": {
                "operationId": "post.creative.edit-creative.video.prompt",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Video Prompt",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "prompt": {
                                        "type": "string",
                                        "maxLength": 2000
                                    },
                                    "reference_images": {
                                        "type": "array",
                                        "maxItems": 5,
                                        "items": {
                                            "type": "string",
                                            "format": "uri"
                                        }
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "prompt"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.creative.edit-creative.video.assets.assetType.assetId.versions",
                    "statusPath": "/v1/edits/video/assets/{assetType}/{assetId}/versions",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/edits/video/revert": {
            "post": {
                "operationId": "post.creative.edit-creative.video.revert",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Video Revert",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/video/versions/{version}/discard": {
            "post": {
                "operationId": "post.creative.edit-creative.video.versions.version.discard",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Video Versions Version Discard",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "version": {
                                        "type": "integer",
                                        "description": "Path parameter."
                                    }
                                },
                                "required": [
                                    "version"
                                ],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "version",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/edits/video/versions/{version}/keep": {
            "post": {
                "operationId": "post.creative.edit-creative.video.versions.version.keep",
                "tags": [
                    "creative"
                ],
                "summary": "Creative Edit Creative Video Versions Version Keep",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "version": {
                                        "type": "integer",
                                        "description": "Path parameter."
                                    }
                                },
                                "required": [
                                    "version"
                                ],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "version",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/library/{type}/{id}": {
            "delete": {
                "operationId": "delete.campaigns.type.id",
                "tags": [
                    "campaigns"
                ],
                "summary": "Delete campaign from library",
                "description": "Soft-delete (hide from library) a full or single-asset campaign you own.",
                "parameters": [
                    {
                        "name": "type",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/me": {
            "get": {
                "operationId": "user.details",
                "tags": [
                    "user-details"
                ],
                "summary": "User Details",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "put": {
                "operationId": "user.profile.update",
                "tags": [
                    "user-details"
                ],
                "summary": "User Profile Update",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "profile_picture": {
                                        "type": "string",
                                        "format": "binary",
                                        "maxLength": 10240,
                                        "description": "Allowed types: jpeg,png,jpg,webp."
                                    },
                                    "show_in_ad_gallery": {
                                        "type": "boolean"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/me/active-generations": {
            "get": {
                "operationId": "user.active-generations",
                "tags": [
                    "user"
                ],
                "summary": "User Active Generations",
                "description": "List every generation currently running for the authenticated user — the same feed that seeds the in-app generation tracker. Items carry a `type` of `single_asset` (with `asset_type`: image|video|ugc_video|google_ads|ugc_action|commercial_video), `full_campaign`, or `ad_clone`, plus `id`, `status` (pending|processing|awaiting_input), a `progress` block ({total, completed, failed, pending, percentage, phase_message}), `product` ({title, image, url}), the Pusher `channel` broadcasting live updates, and `created_at`. Clone items report segment-based progress capped at 95% until assembly finishes. Use to check what is still in flight before starting new work or polling a specific campaign.",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/me/credits": {
            "get": {
                "operationId": "user.creative-credits",
                "tags": [
                    "user-creative-credits"
                ],
                "summary": "User Creative Credits",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/me/recent-actions": {
            "get": {
                "operationId": "user.recent-actions",
                "tags": [
                    "user"
                ],
                "summary": "User Recent Actions",
                "description": "The authenticated user's recent actions — the history feed shown under the in-app generation tracker: up to 10 IN-PROGRESS actions (edits, translations and editor regenerations still rendering, smart resizes still running; newest first) followed by the last 10 completed actions (newest first). In-flight campaign generations are not listed here. Each item carries a `status` (in_progress|completed), an `action` (generation|edit|translate|resize|regenerate|animate), `media` (image|video|ugc_video|google_ads|ugc_action|commercial_video|article|full_campaign|ad_clone|clip), optional `title` and `thumbnail`, `created_at`, an optional `meta` block ({language_count} for collapsed multi-language translations, {progress: {done, total}} on in-progress multi-part actions and resizes, {destination} for animations), and a nullable `target` block ({kind: single_asset_campaign|full_campaign|ad_clone|gif_it, campaign_id, asset_type, campaign_kind, asset_id}) that locates the resulting asset inside its parent campaign. Use to see what the user recently produced and to link back to those results.",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets": {
            "post": {
                "operationId": "post.single-asset-campaign.create",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Create Single-Asset Campaign",
                "description": "Generate a BATCH of premium creatives of ONE asset type — image: 6 image ads, every one with a text overlay · video: 4 video ads · ugc_video: 3 UGC presenter videos · google_ads: 24 ad variations · ugc_action: 3 UGC in-action videos. For image and video the caller may set asset_count (image 1-12, video 1-6) and credits scale pro rata; the other counts are platform defaults. Product input — exactly ONE mode: (1) crawl: product_url (+optional alternative_product_url fallback); (2) manual: user_instructions.product_name + product_description + ≥1 uploaded_images; (3) text-only: product_name + product_description with no URL and no images. Otherwise 422 MISSING_PRODUCT_INPUT. Upload local product photos first with the adgpt_upload_product_image tool — it returns the S3 url for uploaded_images. text-only is NOT allowed for google_ads. brand_id (optional) must be a brand you own and is never auto-created from the crawl. Aspect ratios per type — image: 1:1,9:16,16:9,2:3,3:2,3:4,4:3,4:5,5:4,21:9 · video: 9:16,16:9 · ugc_video: 1:1,9:16,16:9 · ugc_action: 9:16,16:9 (no square). interactive=true (ugc_video/ugc_action) defers credit charge to confirm. Async — poll with adgpt_job. Optional Idempotency-Key header (8-128 of [A-Za-z0-9_-]): a retry with the same key, query string, and body replays the stored response and does not charge again. A response after a committed charge is stored whatever its status. A 422 is not stored.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "image",
                                            "video",
                                            "ugc_video",
                                            "google_ads",
                                            "ugc_action",
                                            "commercial_video",
                                            "article"
                                        ],
                                        "description": "Drives all downstream options."
                                    },
                                    "product_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 10000
                                    },
                                    "aspect_ratio": {
                                        "type": "string",
                                        "maxLength": 10,
                                        "description": "Must be in the per-type allow-list (see tool description); 422 INVALID_ASPECT_RATIO otherwise."
                                    },
                                    "video_duration": {
                                        "type": "integer",
                                        "enum": [
                                            10
                                        ],
                                        "description": "Seconds; only for asset_type=video (10)."
                                    },
                                    "ugc_video_duration": {
                                        "type": "integer",
                                        "enum": [
                                            15,
                                            30,
                                            45,
                                            60
                                        ],
                                        "description": "15|30|45|60 — only for ugc_video and ugc_action."
                                    },
                                    "brand_id": {
                                        "type": "integer"
                                    },
                                    "no_brand": {
                                        "type": "boolean"
                                    },
                                    "interactive": {
                                        "type": "boolean",
                                        "description": "Defer generation until confirm (choose scripts/avatars/characters first)."
                                    },
                                    "override_scripts": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "maxLength": 5000
                                        },
                                        "maxItems": 3
                                    },
                                    "override_avatar_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "uuid"
                                        },
                                        "maxItems": 3,
                                        "description": "Presenter avatar UUIDs (template flow)."
                                    },
                                    "character_count": {
                                        "type": "integer",
                                        "description": "1-8; only honored for ugc_video.",
                                        "minimum": 1,
                                        "maximum": 8
                                    },
                                    "asset_count": {
                                        "type": "integer",
                                        "description": "How many creatives to generate. PER-TYPE CEILING: image 1-12, video 1-6 — the maximum below is the surface-wide max, so asset_count above the ceiling FOR THIS asset_type is rejected 422. Only honored for image (default 6) and video (default 4); other types keep their own default. Credits scale pro rata with the count.",
                                        "minimum": 1,
                                        "maximum": 12
                                    },
                                    "user_instructions": {
                                        "type": "object",
                                        "properties": {
                                            "general": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "Shared creative brief applied across assets."
                                            },
                                            "general_english": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "English translation of the general brief."
                                            },
                                            "original_language": {
                                                "type": "string",
                                                "maxLength": 10,
                                                "description": "ISO language code of the original brief."
                                            },
                                            "product_name": {
                                                "type": "string",
                                                "maxLength": 120,
                                                "description": "Product name (manual / text-only input modes)."
                                            },
                                            "product_description": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "Product description (manual / text-only input modes)."
                                            },
                                            "per_asset": {
                                                "type": "object",
                                                "properties": {
                                                    "image": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "instruction": {
                                                                    "type": "string",
                                                                    "maxLength": 2000,
                                                                    "description": "Scene/visual direction for this image slot."
                                                                },
                                                                "instruction_original": {
                                                                    "type": "string",
                                                                    "maxLength": 2000
                                                                },
                                                                "copy": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "title": {
                                                                            "type": "string",
                                                                            "maxLength": 25,
                                                                            "description": "On-image overlay title."
                                                                        },
                                                                        "subtitle": {
                                                                            "type": "string",
                                                                            "maxLength": 35
                                                                        },
                                                                        "cta": {
                                                                            "type": "string",
                                                                            "maxLength": 12
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 20,
                                                        "description": "Per-image-slot direction. copy = on-image text (videos have NO copy)."
                                                    },
                                                    "video": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "instruction": {
                                                                    "type": "string",
                                                                    "maxLength": 5000,
                                                                    "description": "Scene direction for this video slot."
                                                                },
                                                                "instruction_original": {
                                                                    "type": "string",
                                                                    "maxLength": 5000
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 10
                                                    },
                                                    "ugc": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "script": {
                                                                    "type": "string",
                                                                    "maxLength": 5000,
                                                                    "description": "UGC presenter script (required within an entry)."
                                                                },
                                                                "script_original": {
                                                                    "type": "string",
                                                                    "maxLength": 5000
                                                                },
                                                                "language": {
                                                                    "type": "string",
                                                                    "maxLength": 10
                                                                },
                                                                "target_duration_sec": {
                                                                    "type": "integer",
                                                                    "description": "Target spoken duration.",
                                                                    "minimum": 5,
                                                                    "maximum": 180
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 10
                                                    }
                                                }
                                            },
                                            "uploaded_images": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string",
                                                    "format": "uri",
                                                    "maxLength": 2048
                                                },
                                                "maxItems": 5,
                                                "description": "Product image URLs. MUST be S3 chat-upload URLs from AdGPT uploads (…/uploads/chat-product-images/…) — arbitrary external URLs are rejected."
                                            }
                                        },
                                        "description": "Optional customization payload shared by FC and SAC."
                                    }
                                },
                                "required": [
                                    "asset_type"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Optional. 8-128 characters of [A-Za-z0-9_-]. The same key, query string, and JSON body replay the stored response for 24 hours and do not charge again. A different query or body is 422 IDEMPOTENCY_KEY_REUSED. A duplicate while the first request is still running is 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Once a charge has committed, the response is stored whatever its status, including 5xx. If the process dies after the charge, a retry receives 409 IDEMPOTENCY_CHARGED and does not charge again. A replay includes Idempotent-Replayed: true. Responses returned before a charge, and every 422, are not stored.",
                        "schema": {
                            "type": "string",
                            "minLength": 8,
                            "maxLength": 128,
                            "pattern": "^[A-Za-z0-9_-]{8,128}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Either this Idempotency-Key is already in progress (IDEMPOTENCY_IN_PROGRESS, Retry-After, not stored) or the charge already committed and no final response was stored (IDEMPOTENCY_CHARGED, stored for 24 hours; do not charge again).",
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds to wait before retrying this key.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "per asset_type at the default count: image 140 (6 images), video 300 (4 videos), ugc_video 200 (tiered for pro/premium), google_ads 20, ugc_action deferred to confirm. A non-default asset_count is charged pro rata — round(bundle x count / default), e.g. 3 images = 70, 6 videos = 450.",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.single-asset-campaign.id.status",
                    "statusPath": "/v1/single-assets/{id}/status",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/eligibility": {
            "get": {
                "operationId": "get.single-asset-campaign.eligibility",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Eligibility",
                "description": "GET /single-asset-campaign/eligibility — the credit cost and whether the caller can afford it. Pass asset_count to price a non-default batch size (image/video). For ugc_video pass interactive=true to quote the interactive flow (one video at the chosen duration, what /confirm bills per pick) instead of the auto bundle.",
                "parameters": [
                    {
                        "name": "asset_type",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "image",
                                "video",
                                "ugc_video",
                                "google_ads",
                                "ugc_action",
                                "commercial_video",
                                "article"
                            ]
                        }
                    },
                    {
                        "name": "video_duration",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "enum": [
                                10
                            ],
                            "description": "Seconds. video: 10."
                        }
                    },
                    {
                        "name": "ugc_video_duration",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "interactive",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "description": "ugc_video only: quote the INTERACTIVE flow — one video at ugc_video_duration's custom unit cost (what /confirm charges per picked presenter). Omit or false for the AUTO bundle price that a non-interactive create bills. Ignored for every other asset_type."
                        }
                    },
                    {
                        "name": "asset_count",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "description": "How many creatives. PER-TYPE CEILING: image 1-12, video 1-6 — the maximum below is the surface-wide max, so asset_count above the ceiling FOR THIS asset_type is rejected 422. Only affects image and video; the quoted credit_cost scales pro rata with it.",
                            "minimum": 1,
                            "maximum": 12
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/pricing": {
            "get": {
                "operationId": "get.single-asset-campaign.pricing",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Pricing",
                "description": "GET /single-asset-campaign/pricing — credit prices per asset type.",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/assets": {
            "get": {
                "operationId": "get.single-asset-campaign.id.assets",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Id Assets",
                "description": "Assets of a single-asset campaign. Each asset carries detected_lang_code (the ad's language) and download availability per media type.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/cancel": {
            "post": {
                "operationId": "post.single-asset-campaign.id.cancel",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Id Cancel",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Path parameter."
                                    }
                                },
                                "required": [
                                    "id"
                                ],
                                "additionalProperties": true,
                                "description": "Minimal schema (path/query params); the backend validates the full payload."
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/commercial/concepts": {
            "post": {
                "operationId": "post.single-asset-campaign.id.generate-commercial-concepts",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Generate commercial video concepts",
                "description": "Propose N (default 8) creative directions for a commercial-video campaign. Each direction returns a stable `concept_id`, a short name, a rationale, a `style` (look / camera / energy / palette) and a `strategy` (viewer insight, emotion, angle, hook, curiosity gap, payoff). A direction replaces the presenter for this product type: `concept_id` is the key you pass to generate-commercial-plan and to confirm. Free — the charge happens once at confirm, for the directions you keep. BETA — commercial videos are a gated rollout (default off); on a non-enrolled account these endpoints return 422.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "count": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 8,
                                        "description": "How many directions to propose. Default 8."
                                    },
                                    "replace_concept_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "maxLength": 40
                                        },
                                        "maxItems": 8,
                                        "description": "Re-direct: the concept_id each fresh direction replaces, in order. Each fresh direction comes back UNDER the concept_id it replaces (confirm it with that id) and is written in the same audio style (narrated or music-only) as the direction it replaces, so the ad renders the way its card reads. Directions beyond this list (or for a blank or repeated id) come back under new ids. Omit for a fresh proposal."
                                    }
                                },
                                "required": [
                                    "id"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/{id}/commercial/plan": {
            "post": {
                "operationId": "post.single-asset-campaign.id.generate-commercial-plan",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Generate commercial video plans (async)",
                "description": "Write the per-direction plan — the narration script plus the binding scene storyboard (role, label, on-screen action, length, spoken line) — so it can be reviewed and edited before confirming. Returns 202 immediately; each plan streams back on the campaign channel and is also readable via the commercial-plans action, which is the poll fallback. Send `force: true` to bypass the plan cache and rewrite a direction from scratch. Free — no credits. BETA — commercial videos are a gated rollout (default off); on a non-enrolled account these endpoints return 422.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "selections": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "concept_id": {
                                                    "type": "string",
                                                    "maxLength": 40,
                                                    "description": "Creative-direction id from generate-commercial-concepts. Unique within the request."
                                                },
                                                "style": {
                                                    "type": "object",
                                                    "properties": {
                                                        "look": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "camera": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "energy": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "palette": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        }
                                                    },
                                                    "description": "The art direction, as proposed or as edited by the user."
                                                },
                                                "creative_strategy": {
                                                    "type": "object",
                                                    "properties": {
                                                        "target_insight": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "main_emotion": {
                                                            "type": "string",
                                                            "enum": [
                                                                "curiosity",
                                                                "surprise",
                                                                "aspiration",
                                                                "relief",
                                                                "fomo",
                                                                "status",
                                                                "humor",
                                                                "belonging",
                                                                "desire",
                                                                "transformation"
                                                            ],
                                                            "description": "Closed set; unknown values are dropped server-side."
                                                        },
                                                        "creative_angle": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "pattern_interrupt": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "visual_hook": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "curiosity_gap": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "emotional_payoff": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "desired_reaction": {
                                                            "type": "string",
                                                            "maxLength": 300
                                                        },
                                                        "archetype": {
                                                            "type": "string",
                                                            "maxLength": 60
                                                        }
                                                    }
                                                },
                                                "product_refs": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "format": "uri",
                                                        "maxLength": 2048
                                                    },
                                                    "maxItems": 6,
                                                    "description": "Product image URLs to anchor the film on."
                                                },
                                                "direction_note": {
                                                    "type": "string",
                                                    "maxLength": 2000
                                                },
                                                "target_duration": {
                                                    "type": "integer",
                                                    "enum": [
                                                        15,
                                                        30,
                                                        45,
                                                        60
                                                    ]
                                                }
                                            },
                                            "required": [
                                                "concept_id"
                                            ]
                                        },
                                        "minItems": 1,
                                        "maxItems": 8
                                    },
                                    "force": {
                                        "type": "boolean",
                                        "description": "Bypass the plan cache and rewrite."
                                    }
                                },
                                "required": [
                                    "id",
                                    "selections"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.single-asset-campaign.id.commercial-plans",
                    "statusPath": "/v1/single-assets/{id}/commercial/plans",
                    "pollHintSeconds": 6
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/{id}/commercial/plans": {
            "get": {
                "operationId": "get.single-asset-campaign.id.commercial-plans",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Get commercial video plans",
                "description": "Poll/rehydrate the async commercial-video plans for a campaign: returns `plans` (each with the narration script and the scene storyboard), `pending` (requested directions still being written) and `failed` (directions that could not be planned, with a reason). Pass concept_ids[] to scope it to the directions you are waiting on — otherwise every cached plan is returned. Pair with the generate-commercial-plan action. A plan carries `script_adapts_scenes: true` when an edited narration will have the scenes adapted to it at render (gated rollout; absent otherwise). BETA — commercial videos are a gated rollout (default off); on a non-enrolled account these endpoints return 422.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "concept_ids",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string",
                                "maxLength": 40
                            },
                            "maxItems": 8,
                            "description": "Creative-direction ids to scope the result to (from generate-commercial-concepts)."
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/commercial/wizard-state": {
            "get": {
                "operationId": "get.single-asset-campaign.id.commercial-wizard-state",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Get commercial video wizard state",
                "description": "Read the saved commercial-video wizard snapshot for reload recovery, plus the creative directions most recently proposed for the campaign. Returns `state: null` when nothing was saved. BETA — commercial videos are a gated rollout (default off); on a non-enrolled account these endpoints return 422.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "post": {
                "operationId": "post.single-asset-campaign.id.commercial-wizard-state",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Save commercial video wizard state",
                "description": "Persist the in-progress commercial-video wizard snapshot (picked creative directions, per-direction voice/script/storyboard/style edits, ad length, current step) so a page reload restores it instead of starting over. The snapshot is opaque to the server and is keyed internally by creative-direction id. Free — no credits. BETA — commercial videos are a gated rollout (default off); on a non-enrolled account these endpoints return 422.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "state": {
                                        "type": "object",
                                        "properties": [],
                                        "additionalProperties": true,
                                        "description": "Opaque wizard snapshot, keyed by creative-direction id. Max ~256KB serialized."
                                    }
                                },
                                "required": [
                                    "id",
                                    "state"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/confirm": {
            "post": {
                "operationId": "post.single-asset-campaign.id.confirm",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Confirm Single-Asset Campaign",
                "description": "Resume an awaiting_input interactive campaign: locks choices, charges credits, dispatches generation. SIX mutually-exclusive sub-payloads — send exactly one: (a) template flow (video_style + selected_template_ids [+template_params]); (b) pipeline_selections (talking-head; entry count overrides variant count); (c) brief (review-gate; flag-gated; not with pipeline_selections); (d) in_action_brief (single-host native in-action); (e) in_action_selections (multi-character native; not with b/d); (f) commercial_selections (commercial videos — required for a commercial_video campaign, and rejected with 422 on any other campaign or on an account off that rollout; not with b/c/e). Read adgpt://pipeline/characters and adgpt://pipeline/voices for valid integer IDs. Async — poll with adgpt_job. NOTE: the native in-action payloads (d)/(e) apply only to accounts enrolled in the native rollout (default off) — otherwise ugc_action REQUIRES selected_template_ids (template flow) and (d)/(e) are ignored. Optional Idempotency-Key header (8-128 of [A-Za-z0-9_-]): a retry with the same key, query string, and body replays the stored response and does not charge again. A response after a committed charge is stored whatever its status. A 422 is not stored.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "override_scripts": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "maxLength": 5000
                                        },
                                        "maxItems": 3
                                    },
                                    "override_avatar_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "uuid"
                                        },
                                        "maxItems": 3
                                    },
                                    "video_style": {
                                        "type": "string",
                                        "enum": [
                                            "avatar_ugc",
                                            "product_template"
                                        ],
                                        "description": "Template flow."
                                    },
                                    "selected_template_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "uuid"
                                        },
                                        "maxItems": 3,
                                        "description": "Required for template-path ugc_action."
                                    },
                                    "template_params": {
                                        "type": "object",
                                        "properties": [],
                                        "description": "Keyed by template UUID (keys must match selected_template_ids).",
                                        "additionalProperties": true
                                    },
                                    "pipeline_selections": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "character_id": {
                                                    "type": "integer",
                                                    "description": "pipeline_characters id (status=ready)."
                                                },
                                                "voice_id": {
                                                    "type": "integer",
                                                    "description": "pipeline_voices id."
                                                },
                                                "script_text": {
                                                    "type": "string",
                                                    "maxLength": 1200,
                                                    "description": "Plain caps by duration: 210 (15s) / 420 (30s) / 630 (45s) / 840 (60s); 1200 is the tagged-wire ceiling."
                                                },
                                                "script_text_tagged": {
                                                    "type": "string",
                                                    "maxLength": 1200
                                                }
                                            },
                                            "required": [
                                                "character_id",
                                                "voice_id",
                                                "script_text"
                                            ]
                                        },
                                        "maxItems": 8
                                    },
                                    "brief": {
                                        "type": "object",
                                        "properties": {
                                            "preset": {
                                                "type": "string",
                                                "enum": [
                                                    "auto",
                                                    "review",
                                                    "custom"
                                                ]
                                            },
                                            "locks": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                },
                                                "description": "Allow-listed lock paths (slots.*.character_id|voice_id|script_text|script_text_tagged; +layout_family/arc/archetype/chapters/treatment/music_mood when structure locks enabled)."
                                            },
                                            "fields": {
                                                "type": "object",
                                                "properties": {
                                                    "arc": {
                                                        "type": "string",
                                                        "enum": [
                                                            "problem_solution",
                                                            "demo_first",
                                                            "social_proof",
                                                            "price_punch"
                                                        ]
                                                    },
                                                    "layout_family": {
                                                        "type": "string",
                                                        "enum": [
                                                            "product_showcase",
                                                            "kinetic",
                                                            "spotlight",
                                                            "gallery",
                                                            "hot_take"
                                                        ]
                                                    },
                                                    "duration_seconds": {
                                                        "type": "integer",
                                                        "enum": [
                                                            15,
                                                            30,
                                                            60
                                                        ]
                                                    },
                                                    "slots": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "character_id": {
                                                                    "type": "integer"
                                                                },
                                                                "voice_id": {
                                                                    "type": "integer"
                                                                },
                                                                "script_text": {
                                                                    "type": "string",
                                                                    "maxLength": 1200
                                                                },
                                                                "script_text_tagged": {
                                                                    "type": "string",
                                                                    "maxLength": 1200
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 8
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "in_action_brief": {
                                        "type": "object",
                                        "properties": {
                                            "host": {
                                                "type": "object",
                                                "properties": {
                                                    "character_id": {
                                                        "type": "integer",
                                                        "description": "Ready pipeline character."
                                                    }
                                                }
                                            },
                                            "voice_id": {
                                                "type": "integer"
                                            },
                                            "script_text": {
                                                "type": "string",
                                                "maxLength": 5000
                                            },
                                            "interaction_type": {
                                                "type": "string",
                                                "enum": [
                                                    "try_on",
                                                    "handheld",
                                                    "unboxing",
                                                    "showcase"
                                                ],
                                                "description": "How the host physically interacts with the product."
                                            },
                                            "product_refs": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string",
                                                    "format": "uri",
                                                    "maxLength": 2048
                                                },
                                                "maxItems": 6
                                            },
                                            "direction_note": {
                                                "type": "string",
                                                "maxLength": 2000
                                            },
                                            "target_duration": {
                                                "type": "integer",
                                                "enum": [
                                                    15,
                                                    30
                                                ]
                                            }
                                        }
                                    },
                                    "in_action_selections": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "character_id": {
                                                    "type": "integer"
                                                },
                                                "second_character_id": {
                                                    "type": "integer",
                                                    "description": "Optional SECOND speaker (TWO_SPEAKERS_2026_10): another ready presenter id, different from character_id. Only accepted on accounts the feature admits (otherwise 422 with code TWO_SPEAKERS_UNAVAILABLE). The two speakers are never on screen at the same time — a change of speaker is a cut to a new scene."
                                                },
                                                "voice_id": {
                                                    "type": "integer"
                                                },
                                                "script_text": {
                                                    "type": "string",
                                                    "maxLength": 5000
                                                },
                                                "lines": {
                                                    "type": "array",
                                                    "maxItems": 40,
                                                    "description": "Optional ordered per-speaker script (TWO_SPEAKERS_2026_10, gated per account — see the brief's `two_speakers` flag). When present it REPLACES script_text as the pinned, verbatim copy. `second` lines (and `voice_of: second`) need `second_character_id`; total text at most 5000 characters; at most 8 changes of speaker per ad.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "speaker": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "host",
                                                                    "second",
                                                                    "narrator"
                                                                ]
                                                            },
                                                            "voice_of": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "host",
                                                                    "second"
                                                                ],
                                                                "description": "Which cast member reads a narrator line (default host)."
                                                            },
                                                            "text": {
                                                                "type": "string",
                                                                "maxLength": 1000
                                                            },
                                                            "source": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "customer",
                                                                    "authored"
                                                                ],
                                                                "description": "Who wrote the line: the customer's own words (the default when omitted) or a drafted line left untouched. A forced regenerate keeps `customer` lines verbatim and writes `authored` ones again; a plain re-plan keeps every line as sent. The review plan echoes each line's source."
                                                            }
                                                        },
                                                        "required": [
                                                            "speaker",
                                                            "text"
                                                        ]
                                                    }
                                                },
                                                "interaction_type": {
                                                    "type": "string",
                                                    "enum": [
                                                        "try_on",
                                                        "handheld",
                                                        "unboxing",
                                                        "showcase"
                                                    ],
                                                    "description": "How the host physically interacts with the product."
                                                },
                                                "product_refs": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "format": "uri",
                                                        "maxLength": 2048
                                                    },
                                                    "maxItems": 6
                                                },
                                                "direction_note": {
                                                    "type": "string",
                                                    "maxLength": 2000
                                                },
                                                "plan_fingerprint": {
                                                    "type": "string",
                                                    "maxLength": 128,
                                                    "description": "The fingerprint of the plan adopted for this slot (from the generate-in-action-plan 202 / the in-action-plans poll). Pins the paid-length check and the render to THAT plan when several were generated for the same character; omit to use the latest plan."
                                                },
                                                "target_duration": {
                                                    "type": "integer",
                                                    "enum": [
                                                        15,
                                                        30
                                                    ]
                                                },
                                                "creative_strategy": {
                                                    "type": "object",
                                                    "properties": {
                                                        "target_insight": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "main_emotion": {
                                                            "type": "string",
                                                            "enum": [
                                                                "curiosity",
                                                                "surprise",
                                                                "aspiration",
                                                                "relief",
                                                                "fomo",
                                                                "status",
                                                                "humor",
                                                                "belonging",
                                                                "desire",
                                                                "transformation"
                                                            ],
                                                            "description": "Closed set; unknown values are dropped server-side."
                                                        },
                                                        "creative_angle": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "pattern_interrupt": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "visual_hook": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "curiosity_gap": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "emotional_payoff": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "desired_reaction": {
                                                            "type": "string",
                                                            "maxLength": 300
                                                        },
                                                        "archetype": {
                                                            "type": "string",
                                                            "maxLength": 60
                                                        }
                                                    }
                                                },
                                                "scenes": {
                                                    "type": "array",
                                                    "description": "Optional user-EDITED scene storyboard for this slot (the editable form of the `scenes` returned by generate-in-action-plan / in-action-plans). Omit to render the AI-authored plan as-is. Supports add / remove / reorder: scenes are matched to the planned ones by `n` and renumbered in the submitted order; a scene with no `n` is treated as newly added. The spoken narration becomes the concatenation of the scenes' `vo`.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "n": {
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "description": "The planned scene this entry edits (carries that scene's technical direction forward). Omit for a newly added scene."
                                                            },
                                                            "role": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "hook",
                                                                    "demo",
                                                                    "benefit",
                                                                    "payoff",
                                                                    "showcase",
                                                                    "lifestyle",
                                                                    "unit"
                                                                ],
                                                                "description": "Beat role; carry the planned value through unless deliberately changing it."
                                                            },
                                                            "scene": {
                                                                "type": "string",
                                                                "maxLength": 200,
                                                                "description": "Short human scene label."
                                                            },
                                                            "summary": {
                                                                "type": "string",
                                                                "maxLength": 300,
                                                                "description": "Display-only campaign-language caption shown in the wizard; never rendered."
                                                            },
                                                            "action": {
                                                                "type": "string",
                                                                "maxLength": 1000,
                                                                "description": "The ENGLISH render direction for this shot (what the engine renders from), regardless of the ad's spoken language."
                                                            },
                                                            "duration": {
                                                                "type": "integer",
                                                                "minimum": 3,
                                                                "maximum": 10,
                                                                "description": "Whole seconds. 10s is the render engine's hard per-scene ceiling — out-of-window values are rejected, not clamped."
                                                            },
                                                            "vo": {
                                                                "type": "string",
                                                                "maxLength": 600,
                                                                "description": "This scene's segment of the voiceover, in the ad's spoken language."
                                                            },
                                                            "on_screen": {
                                                                "type": "string",
                                                                "maxLength": 120,
                                                                "description": "On-screen text chip burned into the frame."
                                                            },
                                                            "speaker": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "host",
                                                                    "second",
                                                                    "narrator",
                                                                    "none"
                                                                ],
                                                                "description": "Two-speaker plans only: who says this scene's line."
                                                            },
                                                            "on_camera": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "host",
                                                                    "second",
                                                                    "none"
                                                                ],
                                                                "description": "Two-speaker plans only: the one cast member on screen (never both)."
                                                            },
                                                            "voice_of": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "host",
                                                                    "second"
                                                                ],
                                                                "description": "Two-speaker plans only: the member whose voice reads a narrator scene."
                                                            }
                                                        }
                                                    },
                                                    "maxItems": 8
                                                }
                                            },
                                            "required": [
                                                "character_id"
                                            ]
                                        },
                                        "maxItems": 8
                                    },
                                    "commercial_selections": {
                                        "type": "array",
                                        "description": "Commercial videos (no presenter). One entry per creative direction kept — 1-8 entries produce 1-8 videos, and the entry count sets the variant count and the charge. Mutually exclusive with pipeline_selections / brief / in_action_selections. Rejected with 422 unless the campaign is asset_type=commercial_video on an enrolled account.",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "concept_id": {
                                                    "type": "string",
                                                    "maxLength": 40,
                                                    "description": "Creative-direction id from generate-commercial-concepts. Unique within the request."
                                                },
                                                "voice_id": {
                                                    "type": "integer",
                                                    "description": "pipeline_voices id. Absent ⇒ resolved from the campaign language."
                                                },
                                                "script_text": {
                                                    "type": "string",
                                                    "maxLength": 1200,
                                                    "description": "The narration. Blank ⇒ server-authored. 1200 is the tagged-wire ceiling (inline expression tags count)."
                                                },
                                                "scenes": {
                                                    "type": "array",
                                                    "description": "The edited storyboard, BINDING when sent. Validated at confirm: each scene 3-10s, the scene lengths must sum to within 2s of the ad length, and every demo/benefit/payoff/showcase scene must keep at least one product reference — otherwise 422 with a human-readable message (never a silent repair).",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "n": {
                                                                "type": "integer",
                                                                "minimum": 1,
                                                                "maximum": 12,
                                                                "description": "1-based scene number."
                                                            },
                                                            "role": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "hook",
                                                                    "demo",
                                                                    "benefit",
                                                                    "payoff",
                                                                    "showcase",
                                                                    "lifestyle"
                                                                ]
                                                            },
                                                            "scene": {
                                                                "type": "string",
                                                                "maxLength": 200,
                                                                "description": "Short label, e.g. \"The reveal\"."
                                                            },
                                                            "summary": {
                                                                "type": "string",
                                                                "maxLength": 500,
                                                                "description": "Display caption in the campaign language."
                                                            },
                                                            "action": {
                                                                "type": "string",
                                                                "maxLength": 2000,
                                                                "description": "What happens on screen (English render direction)."
                                                            },
                                                            "duration": {
                                                                "type": "integer",
                                                                "description": "Seconds. Engine window 3-10."
                                                            },
                                                            "vo": {
                                                                "type": "string",
                                                                "maxLength": 2000,
                                                                "description": "This scene's spoken line."
                                                            },
                                                            "on_screen": {
                                                                "type": "string",
                                                                "maxLength": 200,
                                                                "description": "Optional on-screen text."
                                                            },
                                                            "product_refs": {
                                                                "type": "array",
                                                                "items": {
                                                                    "type": "string",
                                                                    "format": "uri",
                                                                    "maxLength": 2048
                                                                },
                                                                "maxItems": 6,
                                                                "description": "Optional per-scene product references. Sending an EMPTY array on a product-showing role is rejected."
                                                            }
                                                        },
                                                        "required": [
                                                            "role",
                                                            "action",
                                                            "duration"
                                                        ]
                                                    },
                                                    "maxItems": 12
                                                },
                                                "style": {
                                                    "type": "object",
                                                    "properties": {
                                                        "look": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "camera": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "energy": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "palette": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        }
                                                    }
                                                },
                                                "creative_strategy": {
                                                    "type": "object",
                                                    "properties": {
                                                        "target_insight": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "main_emotion": {
                                                            "type": "string",
                                                            "enum": [
                                                                "curiosity",
                                                                "surprise",
                                                                "aspiration",
                                                                "relief",
                                                                "fomo",
                                                                "status",
                                                                "humor",
                                                                "belonging",
                                                                "desire",
                                                                "transformation"
                                                            ],
                                                            "description": "Closed set; unknown values are dropped server-side."
                                                        },
                                                        "creative_angle": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "pattern_interrupt": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "visual_hook": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "curiosity_gap": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "emotional_payoff": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "desired_reaction": {
                                                            "type": "string",
                                                            "maxLength": 300
                                                        },
                                                        "archetype": {
                                                            "type": "string",
                                                            "maxLength": 60
                                                        }
                                                    }
                                                },
                                                "product_refs": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "format": "uri",
                                                        "maxLength": 2048
                                                    },
                                                    "maxItems": 6
                                                },
                                                "direction_note": {
                                                    "type": "string",
                                                    "maxLength": 2000
                                                },
                                                "target_duration": {
                                                    "type": "integer",
                                                    "enum": [
                                                        15,
                                                        30,
                                                        45,
                                                        60
                                                    ],
                                                    "description": "Prices this direction on its own length (240/490/740/990)."
                                                }
                                            },
                                            "required": [
                                                "concept_id"
                                            ]
                                        },
                                        "minItems": 1,
                                        "maxItems": 8
                                    },
                                    "user_instructions": {
                                        "type": "object",
                                        "properties": {
                                            "general": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "Shared creative brief applied across assets."
                                            },
                                            "general_english": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "English translation of the general brief."
                                            },
                                            "original_language": {
                                                "type": "string",
                                                "maxLength": 10,
                                                "description": "ISO language code of the original brief."
                                            },
                                            "product_name": {
                                                "type": "string",
                                                "maxLength": 120,
                                                "description": "Product name (manual / text-only input modes)."
                                            },
                                            "product_description": {
                                                "type": "string",
                                                "maxLength": 5000,
                                                "description": "Product description (manual / text-only input modes)."
                                            },
                                            "per_asset": {
                                                "type": "object",
                                                "properties": {
                                                    "image": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "instruction": {
                                                                    "type": "string",
                                                                    "maxLength": 2000,
                                                                    "description": "Scene/visual direction for this image slot."
                                                                },
                                                                "instruction_original": {
                                                                    "type": "string",
                                                                    "maxLength": 2000
                                                                },
                                                                "copy": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "title": {
                                                                            "type": "string",
                                                                            "maxLength": 25,
                                                                            "description": "On-image overlay title."
                                                                        },
                                                                        "subtitle": {
                                                                            "type": "string",
                                                                            "maxLength": 35
                                                                        },
                                                                        "cta": {
                                                                            "type": "string",
                                                                            "maxLength": 12
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 20,
                                                        "description": "Per-image-slot direction. copy = on-image text (videos have NO copy)."
                                                    },
                                                    "video": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "instruction": {
                                                                    "type": "string",
                                                                    "maxLength": 5000,
                                                                    "description": "Scene direction for this video slot."
                                                                },
                                                                "instruction_original": {
                                                                    "type": "string",
                                                                    "maxLength": 5000
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 10
                                                    },
                                                    "ugc": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "script": {
                                                                    "type": "string",
                                                                    "maxLength": 5000,
                                                                    "description": "UGC presenter script (required within an entry)."
                                                                },
                                                                "script_original": {
                                                                    "type": "string",
                                                                    "maxLength": 5000
                                                                },
                                                                "language": {
                                                                    "type": "string",
                                                                    "maxLength": 10
                                                                },
                                                                "target_duration_sec": {
                                                                    "type": "integer",
                                                                    "description": "Target spoken duration.",
                                                                    "minimum": 5,
                                                                    "maximum": 180
                                                                }
                                                            }
                                                        },
                                                        "maxItems": 10
                                                    }
                                                }
                                            },
                                            "uploaded_images": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string",
                                                    "format": "uri",
                                                    "maxLength": 2048
                                                },
                                                "maxItems": 5,
                                                "description": "Product image URLs. MUST be S3 chat-upload URLs from AdGPT uploads (…/uploads/chat-product-images/…) — arbitrary external URLs are rejected."
                                            }
                                        },
                                        "description": "Optional customization payload shared by FC and SAC."
                                    }
                                },
                                "required": [
                                    "id"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Optional. 8-128 characters of [A-Za-z0-9_-]. The same key, query string, and JSON body replay the stored response for 24 hours and do not charge again. A different query or body is 422 IDEMPOTENCY_KEY_REUSED. A duplicate while the first request is still running is 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Once a charge has committed, the response is stored whatever its status, including 5xx. If the process dies after the charge, a retry receives 409 IDEMPOTENCY_CHARGED and does not charge again. A replay includes Idempotent-Replayed: true. Responses returned before a charge, and every 422, are not stored.",
                        "schema": {
                            "type": "string",
                            "minLength": 8,
                            "maxLength": 128,
                            "pattern": "^[A-Za-z0-9_-]{8,128}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Either this Idempotency-Key is already in progress (IDEMPOTENCY_IN_PROGRESS, Retry-After, not stored) or the charge already committed and no final response was stored (IDEMPOTENCY_CHARGED, stored for 24 hours; do not charge again).",
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds to wait before retrying this key.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "ugc pricing matrix (tier × auto/custom × duration); template flow: per-template (~40 credits × template multiplier). Native in-action (UGC Pro) per-variant 240/490/740/990 for 15/30/45/60s — 1.5x when the campaign language is Hebrew (360/735/1110/1485), every other language unchanged — applies ONLY to accounts enrolled in the native rollout. Commercial videos: the same 240/490/740/990 ladder for 15/30/45/60s, charged per kept creative direction.",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.single-asset-campaign.id.status",
                    "statusPath": "/v1/single-assets/{id}/status",
                    "pollHintSeconds": 10
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/{id}/download-all": {
            "get": {
                "operationId": "get.single-asset-campaign.id.download-all",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Id Download All",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/in-action/plan": {
            "post": {
                "operationId": "post.single-asset-campaign.id.generate-in-action-plan",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Generate in-action plans (async)",
                "description": "Per-character script + shot plan. Returns 202; plans stream via Pusher — poll the plans action for results. BETA — native in-action rendering is a gated rollout (default off); for non-enrolled accounts ugc_action renders via the template flow and these inputs are ignored.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "selections": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "character_id": {
                                                    "type": "integer"
                                                },
                                                "second_character_id": {
                                                    "type": "integer",
                                                    "description": "Optional SECOND speaker (TWO_SPEAKERS_2026_10): another ready presenter id, different from character_id. Only accepted on accounts the feature admits (otherwise 422 with code TWO_SPEAKERS_UNAVAILABLE). The two speakers are never on screen at the same time — a change of speaker is a cut to a new scene."
                                                },
                                                "voice_id": {
                                                    "type": "integer"
                                                },
                                                "lines": {
                                                    "type": "array",
                                                    "maxItems": 40,
                                                    "description": "Optional ordered per-speaker script (TWO_SPEAKERS_2026_10, gated per account — see the brief's `two_speakers` flag). When present it REPLACES script_text as the pinned, verbatim copy. `second` lines (and `voice_of: second`) need `second_character_id`; total text at most 5000 characters; at most 8 changes of speaker per ad.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "speaker": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "host",
                                                                    "second",
                                                                    "narrator"
                                                                ]
                                                            },
                                                            "voice_of": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "host",
                                                                    "second"
                                                                ],
                                                                "description": "Which cast member reads a narrator line (default host)."
                                                            },
                                                            "text": {
                                                                "type": "string",
                                                                "maxLength": 1000
                                                            },
                                                            "source": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "customer",
                                                                    "authored"
                                                                ],
                                                                "description": "Who wrote the line: the customer's own words (the default when omitted) or a drafted line left untouched. A forced regenerate keeps `customer` lines verbatim and writes `authored` ones again; a plain re-plan keeps every line as sent. The review plan echoes each line's source."
                                                            }
                                                        },
                                                        "required": [
                                                            "speaker",
                                                            "text"
                                                        ]
                                                    }
                                                },
                                                "interaction_type": {
                                                    "type": "string",
                                                    "enum": [
                                                        "try_on",
                                                        "handheld",
                                                        "unboxing",
                                                        "showcase"
                                                    ],
                                                    "description": "How the host physically interacts with the product."
                                                },
                                                "creative_strategy": {
                                                    "type": "object",
                                                    "properties": {
                                                        "target_insight": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "main_emotion": {
                                                            "type": "string",
                                                            "enum": [
                                                                "curiosity",
                                                                "surprise",
                                                                "aspiration",
                                                                "relief",
                                                                "fomo",
                                                                "status",
                                                                "humor",
                                                                "belonging",
                                                                "desire",
                                                                "transformation"
                                                            ],
                                                            "description": "Closed set; unknown values are dropped server-side."
                                                        },
                                                        "creative_angle": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "pattern_interrupt": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "visual_hook": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "curiosity_gap": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "emotional_payoff": {
                                                            "type": "string",
                                                            "maxLength": 500
                                                        },
                                                        "desired_reaction": {
                                                            "type": "string",
                                                            "maxLength": 300
                                                        },
                                                        "archetype": {
                                                            "type": "string",
                                                            "maxLength": 60
                                                        }
                                                    }
                                                },
                                                "target_duration": {
                                                    "type": "integer",
                                                    "enum": [
                                                        15,
                                                        30
                                                    ]
                                                },
                                                "direction_note": {
                                                    "type": "string",
                                                    "maxLength": 2000,
                                                    "description": "Optional free-text creative direction for this slot (scene/setting/emphasis/tone). Subordinate to product-fidelity rules; a changed note regenerates the plan."
                                                }
                                            },
                                            "required": [
                                                "character_id"
                                            ]
                                        },
                                        "minItems": 1,
                                        "maxItems": 8
                                    },
                                    "force": {
                                        "type": "boolean",
                                        "description": "Bypass the plan cache."
                                    }
                                },
                                "required": [
                                    "id",
                                    "selections"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.single-asset-campaign.id.in-action-plans",
                    "statusPath": "/v1/single-assets/{id}/in-action/plans",
                    "pollHintSeconds": 6
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/{id}/in-action/plans": {
            "get": {
                "operationId": "get.single-asset-campaign.id.in-action-plans",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Id In Action Plans",
                "description": "GET /single-asset-campaign/{id}/in-action-plans — one plan per character (the latest) by default, each carrying its `fingerprint`; pass `all_fingerprints=1` to list every plan still stored for a character (latest first) and match on the fingerprint the generate call answered. A plan carries `script_adapts_scenes: true` when an edited script will have the scenes adapted to it at render (gated rollout; absent otherwise). BETA — native in-action rendering is a gated rollout (default off); for non-enrolled accounts ugc_action renders via the template flow and these inputs are ignored.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "character_ids",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "integer"
                            },
                            "description": "Only these characters (omit for every character the campaign planned)."
                        }
                    },
                    {
                        "name": "all_fingerprints",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "enum": [
                                0,
                                1
                            ],
                            "description": "1 lists every stored plan per character (latest first); 0 (default) one per character, the latest."
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/in-action/strategies": {
            "post": {
                "operationId": "post.single-asset-campaign.id.generate-in-action-strategies",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Generate in-action strategies",
                "description": "N distinct creative strategies for the in-action picker (editable cards). Returns {strategies, enabled}.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "count": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 8
                                    }
                                },
                                "required": [
                                    "id",
                                    "count"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/{id}/in-action/wizard-state": {
            "get": {
                "operationId": "get.single-asset-campaign.id.in-action-wizard-state",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Id In Action Wizard State",
                "description": "GET /single-asset-campaign/{id}/in-action-wizard-state BETA — native in-action rendering is a gated rollout (default off); for non-enrolled accounts ugc_action renders via the template flow and these inputs are ignored.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            },
            "post": {
                "operationId": "post.single-asset-campaign.id.in-action-wizard-state",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Save in-action wizard state",
                "description": "Persist the in-progress wizard snapshot (picks, per-slot voice/script/interaction, duration, step) for reload recovery. BETA — native in-action rendering is a gated rollout (default off); for non-enrolled accounts ugc_action renders via the template flow and these inputs are ignored.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "state": {
                                        "type": "object",
                                        "properties": [],
                                        "additionalProperties": true
                                    }
                                },
                                "required": [
                                    "id",
                                    "state"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/regenerate-asset": {
            "post": {
                "operationId": "post.single-asset-campaign.id.regenerate-asset",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Regenerate one SAC asset",
                "description": "Edit the brief/copy of ONE slot and re-render it in place (image/video campaigns only; campaign must be completed). Cost = campaign cost / the picked asset_count for image/video (the per-asset price), refunded on failure. Async — poll with adgpt_job.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "task_index": {
                                        "type": "integer",
                                        "description": "Slot to regenerate.",
                                        "minimum": 0
                                    },
                                    "instruction": {
                                        "type": "string",
                                        "maxLength": 5000,
                                        "description": "Edited scene/visual direction."
                                    },
                                    "copy": {
                                        "type": "object",
                                        "properties": {
                                            "mode": {
                                                "type": "string",
                                                "enum": [
                                                    "structured",
                                                    "general"
                                                ],
                                                "description": "Required when copy is present."
                                            },
                                            "title": {
                                                "type": "string",
                                                "maxLength": 25
                                            },
                                            "subtitle": {
                                                "type": "string",
                                                "maxLength": 35
                                            },
                                            "cta": {
                                                "type": "string",
                                                "maxLength": 12
                                            },
                                            "text": {
                                                "type": "string",
                                                "maxLength": 150,
                                                "description": "General free-text headline (mode=general)."
                                            }
                                        },
                                        "description": "On-image text override — image assets only; ignored for video."
                                    }
                                },
                                "required": [
                                    "id",
                                    "task_index"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "round(campaign cost / asset_count) for image/video; round(campaign cost / regen_cost_divisor) for other asset types",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.single-asset-campaign.id.status",
                    "statusPath": "/v1/single-assets/{id}/status",
                    "pollHintSeconds": 8
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/{id}/scripts": {
            "post": {
                "operationId": "post.single-asset-campaign.id.generate-pipeline-scripts",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Generate pipeline scripts",
                "description": "Character-tailored ad scripts in the campaign language for the custom talking-head flow.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "character_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        },
                                        "minItems": 1,
                                        "maxItems": 8,
                                        "description": "Ready pipeline character ids."
                                    }
                                },
                                "required": [
                                    "id",
                                    "character_ids"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/single-assets/{id}/status": {
            "get": {
                "operationId": "get.single-asset-campaign.id.status",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Single Asset Campaign Id Status",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/tag-script": {
            "post": {
                "operationId": "post.single-asset-campaign.id.tag-script",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Tag a script with expressions",
                "description": "Insert whitelisted expression audio tags into a user-written script (word-preserving).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "script_text": {
                                        "type": "string",
                                        "minLength": 5,
                                        "maxLength": 1200
                                    },
                                    "character_id": {
                                        "type": "integer"
                                    }
                                },
                                "required": [
                                    "id",
                                    "script_text"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/voice-preview": {
            "post": {
                "operationId": "post.single-asset-campaign.id.voice-preview",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Preview a pipeline voice",
                "description": "Hear a voice speak a script line before committing (async submit → poll status), synthesized with the same voice_settings the pipeline applies for the default Tone (as of 2026-09-17). Free, throttled 20/min.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Campaign id (path)."
                                    },
                                    "voice_id": {
                                        "type": "integer"
                                    },
                                    "script_text": {
                                        "type": "string",
                                        "minLength": 5
                                    }
                                },
                                "required": [
                                    "id",
                                    "voice_id",
                                    "script_text"
                                ]
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "get.single-asset-campaign.id.voice-preview.status",
                    "statusPath": "/v1/single-assets/{id}/voice-preview/status",
                    "pollHintSeconds": 3
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/single-assets/{id}/voice-preview/status": {
            "get": {
                "operationId": "get.single-asset-campaign.id.voice-preview.status",
                "tags": [
                    "single-asset-campaign"
                ],
                "summary": "Voice preview status",
                "description": "Poll an async voice preview by sha.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "sha",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "description": "Preview hash from the submit response."
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/smart-resize/batches": {
            "post": {
                "operationId": "smart-resize.store",
                "tags": [
                    "creative"
                ],
                "summary": "Create a Smart Resize batch",
                "description": "Resize a generated asset into selected platform sizes without cropping the subject. Images are re-laid-out per format. Videos use ONE engine per batch: `blur` (standard — the whole frame fitted over a blurred fill), `ai` (premium — the new edges are generated so the frame is full-bleed while the original pixels are kept), or `spec` (a native re-compose of a Product Boost ad from its storyboard at 1:1 / 4:5 / 16:9). Pick sizes from the presets operation. Credits are charged UPFRONT, per size, when the batch is submitted — the whole batch must be affordable (402 otherwise) — and a size that fails is refunded in full. Price per size: image, blur and spec = 25 credits; ai = 5 credits per second of source video, rounded up, clamped to 25–600 (a 10s video = 50 per size, a 60s one = 300 per size). The ai engine also needs a Premium or Enterprise plan (403 PLAN_UPGRADE_REQUIRED), takes at most 4 sizes per batch and a source of at most 90 seconds (422 before any charge otherwise). An ai size whose on-screen text still fails the fidelity check after one free retry is delivered with the standard engine instead, and everything above the standard 25-credit price is refunded. Async — poll the batch status operation.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "asset_type": {
                                        "type": "string",
                                        "enum": [
                                            "single_asset",
                                            "full_campaign"
                                        ]
                                    },
                                    "asset_id": {
                                        "type": "integer",
                                        "minimum": 1
                                    },
                                    "media_kind": {
                                        "type": "string",
                                        "enum": [
                                            "image",
                                            "video"
                                        ]
                                    },
                                    "engine": {
                                        "type": "string",
                                        "enum": [
                                            "blur",
                                            "ai",
                                            "spec"
                                        ]
                                    },
                                    "preset_keys": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 25,
                                        "items": {
                                            "type": "string",
                                            "enum": [
                                                "social_square",
                                                "social_portrait",
                                                "social_story",
                                                "social_landscape",
                                                "social_linkedin",
                                                "social_x",
                                                "social_youtube",
                                                "social_pinterest",
                                                "display_medium_rectangle",
                                                "display_large_rectangle",
                                                "display_square_1200",
                                                "display_square_250",
                                                "display_square_200",
                                                "display_half_page",
                                                "display_vertical_rect",
                                                "display_mobile_interstitial",
                                                "display_interstitial_landscape",
                                                "display_netboard",
                                                "banner_leaderboard",
                                                "banner_mobile",
                                                "banner_skyscraper",
                                                "v_social_story",
                                                "v_social_square",
                                                "v_social_portrait",
                                                "v_social_landscape",
                                                "v_ctv_1080p",
                                                "v_ctv_720p",
                                                "v_native_landscape",
                                                "v_native_square",
                                                "v_native_vertical"
                                            ]
                                        }
                                    }
                                },
                                "required": [
                                    "asset_type",
                                    "asset_id",
                                    "preset_keys"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Insufficient credits",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-credit-cost": "Per size, charged upfront at submit; failed sizes refunded. Image, blur video and spec video: 25 per size (config:smart_resize.credit_cost_per_size, smart_resize.video.credit_cost_per_size, smart_resize.video.spec.credit_cost_per_size). AI video engine: 5 per second of source, rounded up, clamped 25–600 per size (config:smart_resize.video.ai.credit_cost_per_second, smart_resize.video.ai.min_credit_cost_per_size, smart_resize.video.ai.max_credit_cost_per_size); a fallback to the standard engine refunds everything above 25 (config:smart_resize.video.ai.verify.fallback_credit_cost_per_size)",
                "x-async": {
                    "mode": "poll",
                    "statusOperationId": "smart-resize.show",
                    "statusPath": "/v1/smart-resize/batches/{batch}",
                    "pollHintSeconds": 6
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/smart-resize/batches/{batch}": {
            "get": {
                "operationId": "smart-resize.show",
                "tags": [
                    "creative"
                ],
                "summary": "Smart Resize batch status",
                "description": "Status of a resize batch with its per-size renditions (completed renditions carry download URLs).",
                "parameters": [
                    {
                        "name": "batch",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/smart-resize/presets": {
            "get": {
                "operationId": "smart-resize.presets",
                "tags": [
                    "creative"
                ],
                "summary": "Smart Resize presets",
                "description": "The resize size catalog for one media kind (`kind=image|video`) and, for video, one engine (`engine=blur|ai|spec`): platform presets with dimensions, the per-batch size limit (`max_presets_per_batch`) and engine availability (`ai_enabled`, `ai_available`, `ai_max_source_seconds`, `spec_available`). `credit_cost_per_size` is returned only for the flat-priced engines — image, standard (blur) video and spec video, 25 credits per size. It is deliberately ABSENT for `engine=ai`, whose price depends on the source length: 5 credits per second of source video (rounded up), per size, clamped to 25–600 per size (config:smart_resize.video.ai.credit_cost_per_second / min_credit_cost_per_size / max_credit_cost_per_size) — see the batch create operation. Video presets appear only while video resize is enabled.",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/accounts": {
            "post": {
                "operationId": "post.social-ads-account",
                "tags": [
                    "social-ads-account"
                ],
                "summary": "Social Ads Account",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "facebook",
                                            "google",
                                            "tiktok",
                                            "meta"
                                        ]
                                    },
                                    "brand_id": {
                                        "type": "integer",
                                        "description": "References brands,id."
                                    },
                                    "ad_account_id": [],
                                    "ad_account_name": {
                                        "type": "string"
                                    },
                                    "currency": {
                                        "type": "string"
                                    },
                                    "token": {
                                        "description": "Conditionally required (required_if: type,facebook,meta)."
                                    }
                                },
                                "required": [
                                    "type",
                                    "ad_account_id",
                                    "ad_account_name"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/accounts/check-connection": {
            "post": {
                "operationId": "post.social-ads-account.check-connection",
                "tags": [
                    "social-ads-account"
                ],
                "summary": "Check ad-account connection",
                "description": "Whether a brand has a connected ad account of the given type.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "brand_id": {
                                        "type": "integer"
                                    },
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "facebook",
                                            "google",
                                            "tiktok",
                                            "meta"
                                        ]
                                    }
                                },
                                "required": [
                                    "brand_id",
                                    "type"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/facebook/exchange-token": {
            "post": {
                "operationId": "post.facebook.exchange-token",
                "tags": [
                    "facebook"
                ],
                "summary": "Facebook Exchange Token",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "short_lived_token": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "short_lived_token"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/taboola/ads": {
            "post": {
                "operationId": "post.taboola.create-ads",
                "tags": [
                    "taboola"
                ],
                "summary": "Create Taboola ad",
                "description": "Publish one image or video creative into the customer's own Taboola account as a campaign item. campaignOption existing (existingCampaignId) or new — a new campaign (campaignName, brandingText ≤25 chars, cpc, spendingLimit + spendingLimitModel ENTIRE|MONTHLY, marketingObjective) is ALWAYS created paused; Taboola enforces an account-level minimum spending limit (~$93 on some accounts) and its exact refusal message is passed through on a 424. The item: title ≤100, description ≤250, landingUrl, and mediaType image (imageUrl) or video (videoUrl MP4-only + fallbackImageUrl JPG/PNG). Items land in Taboola review as PENDING_APPROVAL — nothing delivers immediately.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "brand_id": {
                                        "type": "integer",
                                        "description": "References brands,id."
                                    },
                                    "campaignOption": {
                                        "type": "string",
                                        "enum": [
                                            "new",
                                            "existing"
                                        ]
                                    },
                                    "existingCampaignId": {
                                        "type": "string",
                                        "maxLength": 64
                                    },
                                    "campaignName": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "brandingText": {
                                        "type": "string",
                                        "maxLength": 25
                                    },
                                    "cpc": {
                                        "type": "number",
                                        "minimum": 0.01,
                                        "maximum": 10
                                    },
                                    "spendingLimit": {
                                        "type": "number",
                                        "minimum": 1
                                    },
                                    "spendingLimitModel": {
                                        "type": "string",
                                        "enum": [
                                            "ENTIRE",
                                            "MONTHLY"
                                        ]
                                    },
                                    "marketingObjective": {
                                        "type": "string",
                                        "enum": [
                                            "BRAND_AWARENESS",
                                            "LEADS_GENERATION",
                                            "ONLINE_PURCHASES",
                                            "DRIVE_WEBSITE_TRAFFIC"
                                        ]
                                    },
                                    "title": {
                                        "type": "string",
                                        "maxLength": 100
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 250
                                    },
                                    "landingUrl": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048
                                    },
                                    "mediaType": {
                                        "type": "string",
                                        "enum": [
                                            "image",
                                            "video"
                                        ]
                                    },
                                    "imageUrl": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048
                                    },
                                    "videoUrl": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048
                                    },
                                    "fallbackImageUrl": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048
                                    }
                                },
                                "required": [
                                    "campaignOption",
                                    "existingCampaignId",
                                    "campaignName",
                                    "brandingText",
                                    "cpc",
                                    "spendingLimit",
                                    "spendingLimitModel",
                                    "marketingObjective",
                                    "title",
                                    "landingUrl",
                                    "mediaType",
                                    "imageUrl",
                                    "videoUrl",
                                    "fallbackImageUrl"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/social/taboola/campaigns": {
            "get": {
                "operationId": "get.taboola.campaigns",
                "tags": [
                    "taboola"
                ],
                "summary": "Taboola Campaigns",
                "description": "List the campaigns in the connected Taboola ad account for a brand (brand_id). Requires the brand to have a Taboola connection (see the app UI or POST v1/social/taboola/connect); answers 404 not_connected otherwise, 423 while the feature flag is off, and 424 with Taboola's own message on upstream errors.",
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "description": "References brands,id."
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/tiktok/ad-groups": {
            "get": {
                "operationId": "get.tiktok.ad-groups",
                "tags": [
                    "tiktok"
                ],
                "summary": "Tiktok Ad Groups",
                "parameters": [
                    {
                        "name": "brandId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "campaignId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "adsAccountId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/tiktok/ads": {
            "post": {
                "operationId": "post.tiktok.create-ads",
                "tags": [
                    "tiktok"
                ],
                "summary": "Create TikTok ads",
                "description": "Create a TikTok campaign/ad group/ad. bid_type, billing_event, and optimization_goal are DERIVED from campaign.objective (TRAFFIC→CPC/CLICK, REACH→CPM/REACH, VIDEO_VIEWS→CPV, WEB_CONVERSIONS/LEAD_GENERATION→OCPM). Min budgets: CBO daily ≥ $50, ad-group daily ≥ $20. Ages are 18+ (AGE_13_17 stripped). Fetch location/language ids via tiktokRegions/tiktokLanguages actions first.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "brandId": {
                                        "type": "integer",
                                        "description": "Brand owning the connected ad account."
                                    },
                                    "ads_account_id": {
                                        "type": "string",
                                        "maxLength": 64,
                                        "description": "Override the connected ad account."
                                    },
                                    "campaign": {
                                        "type": "object",
                                        "properties": {
                                            "option": {
                                                "type": "string",
                                                "enum": [
                                                    "new",
                                                    "existing"
                                                ]
                                            },
                                            "existing_resource": {
                                                "type": "string",
                                                "maxLength": 64,
                                                "description": "Campaign id when option=existing."
                                            },
                                            "name": {
                                                "type": "string",
                                                "maxLength": 255
                                            },
                                            "objective": {
                                                "type": "string",
                                                "enum": [
                                                    "TRAFFIC",
                                                    "REACH",
                                                    "VIDEO_VIEWS",
                                                    "WEB_CONVERSIONS",
                                                    "LEAD_GENERATION",
                                                    "APP_PROMOTION",
                                                    "PRODUCT_SALES"
                                                ]
                                            },
                                            "is_campaign_budget_optimization": {
                                                "type": "boolean",
                                                "description": "CBO."
                                            },
                                            "budget_mode": {
                                                "type": "string",
                                                "enum": [
                                                    "BUDGET_MODE_DAY",
                                                    "BUDGET_MODE_TOTAL",
                                                    "BUDGET_MODE_DYNAMIC_DAILY_BUDGET"
                                                ],
                                                "description": "DYNAMIC only for APP_PROMOTION/PRODUCT_SALES CBO."
                                            },
                                            "budget": {
                                                "type": "number",
                                                "description": "USD. CBO daily ≥ 50."
                                            },
                                            "status": {
                                                "type": "string",
                                                "maxLength": 32
                                            }
                                        }
                                    },
                                    "ad_group": {
                                        "type": "object",
                                        "properties": {
                                            "option": {
                                                "type": "string",
                                                "enum": [
                                                    "new",
                                                    "existing"
                                                ]
                                            },
                                            "existing_resource": {
                                                "type": "string",
                                                "maxLength": 64
                                            },
                                            "name": {
                                                "type": "string",
                                                "maxLength": 255
                                            },
                                            "status": {
                                                "type": "string",
                                                "maxLength": 32
                                            },
                                            "budget_mode": {
                                                "type": "string",
                                                "maxLength": 40
                                            },
                                            "budget": {
                                                "type": "number",
                                                "description": "Daily ≥ 20 USD."
                                            },
                                            "optimization_goal": {
                                                "type": "string",
                                                "maxLength": 40
                                            },
                                            "targeting": {
                                                "type": "object",
                                                "properties": {
                                                    "locations": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string"
                                                        },
                                                        "minItems": 1,
                                                        "description": "TikTok location IDs (required). Fetch via tiktokRegions."
                                                    },
                                                    "languages": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "ages": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string",
                                                            "enum": [
                                                                "AGE_18_24",
                                                                "AGE_25_34",
                                                                "AGE_35_44",
                                                                "AGE_45_54",
                                                                "AGE_55_100"
                                                            ]
                                                        },
                                                        "description": "Default: all 18+."
                                                    },
                                                    "gender": {
                                                        "type": "string",
                                                        "maxLength": 20
                                                    }
                                                }
                                            },
                                            "schedule": {
                                                "type": "object",
                                                "properties": {
                                                    "start": {
                                                        "type": "string",
                                                        "maxLength": 32
                                                    },
                                                    "end": {
                                                        "type": "string",
                                                        "maxLength": 32
                                                    },
                                                    "timezone": {
                                                        "type": "string",
                                                        "maxLength": 64
                                                    },
                                                    "windows": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": [],
                                                            "additionalProperties": true
                                                        }
                                                    }
                                                }
                                            },
                                            "bidding": {
                                                "type": "object",
                                                "properties": {
                                                    "bid_price": {
                                                        "type": "number"
                                                    },
                                                    "conversion_bid_price": {
                                                        "type": "number"
                                                    },
                                                    "frequency": {
                                                        "type": "integer",
                                                        "description": "REACH objective only."
                                                    },
                                                    "frequency_schedule": {
                                                        "type": "integer",
                                                        "description": "REACH objective only."
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "ad": {
                                        "type": "object",
                                        "properties": {
                                            "creatives": {
                                                "type": "array",
                                                "items": {
                                                    "type": "object",
                                                    "properties": {
                                                        "video_url": {
                                                            "type": "string",
                                                            "format": "uri",
                                                            "maxLength": 2048,
                                                            "description": "Required — uploaded via UPLOAD_BY_URL."
                                                        },
                                                        "cover_image_url": {
                                                            "type": "string",
                                                            "format": "uri",
                                                            "maxLength": 2048
                                                        },
                                                        "ad_name": {
                                                            "type": "string",
                                                            "maxLength": 255
                                                        },
                                                        "ad_text": {
                                                            "type": "string",
                                                            "maxLength": 1000
                                                        },
                                                        "call_to_action": {
                                                            "type": "string",
                                                            "maxLength": 40,
                                                            "description": "Default LEARN_MORE."
                                                        },
                                                        "landing_page_url": {
                                                            "type": "string",
                                                            "format": "uri",
                                                            "maxLength": 2048
                                                        },
                                                        "operation_status": {
                                                            "type": "string",
                                                            "maxLength": 20
                                                        },
                                                        "disclaimer_type": {
                                                            "type": "string",
                                                            "maxLength": 20
                                                        },
                                                        "disclaimer_text": {
                                                            "type": "object",
                                                            "properties": {
                                                                "text": {
                                                                    "type": "string",
                                                                    "maxLength": 500
                                                                }
                                                            }
                                                        }
                                                    },
                                                    "required": [
                                                        "video_url"
                                                    ]
                                                },
                                                "minItems": 1,
                                                "maxItems": 1
                                            }
                                        }
                                    }
                                },
                                "required": [
                                    "brandId",
                                    "campaign",
                                    "ad_group",
                                    "ad"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "generate",
                    "requests_per_minute": 10
                }
            }
        },
        "/v1/social/tiktok/campaigns": {
            "get": {
                "operationId": "get.tiktok.campaigns",
                "tags": [
                    "tiktok"
                ],
                "summary": "Tiktok Campaigns",
                "parameters": [
                    {
                        "name": "brandId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "adsAccountId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page_size",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/tiktok/languages": {
            "get": {
                "operationId": "get.tiktok.languages",
                "tags": [
                    "tiktok"
                ],
                "summary": "Tiktok Languages",
                "parameters": [
                    {
                        "name": "brandId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "adsAccountId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/social/tiktok/regions": {
            "get": {
                "operationId": "get.tiktok.regions",
                "tags": [
                    "tiktok"
                ],
                "summary": "Tiktok Regions",
                "parameters": [
                    {
                        "name": "brandId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "adsAccountId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/ugc/avatars/paginated": {
            "get": {
                "operationId": "ugc.avatars.paginated",
                "tags": [
                    "ugc"
                ],
                "summary": "Ugc Avatars Paginated",
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "page_size",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100
                        }
                    },
                    {
                        "name": "age_range",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "child",
                                "teen",
                                "adult",
                                "senior"
                            ]
                        }
                    },
                    {
                        "name": "gender",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "m",
                                "f",
                                "nb"
                            ]
                        }
                    },
                    {
                        "name": "location",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "outdoor",
                                "fantasy",
                                "indoor",
                                "other"
                            ]
                        }
                    },
                    {
                        "name": "style",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "selfie",
                                "presenter",
                                "other"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/ugc/voices": {
            "get": {
                "operationId": "ugc.voices",
                "tags": [
                    "ugc"
                ],
                "summary": "Ugc Voices",
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/uploads/product-image": {
            "post": {
                "operationId": "chat.upload-product-image",
                "tags": [
                    "chat"
                ],
                "summary": "Upload a product image",
                "description": "Upload a product photo from the local machine (the MCP server reads the file and performs the multipart POST — use the adgpt_upload_product_image tool, not JSON dispatch). Validates the image is a usable product photo (min 100×100px, aspect between 1:4 and 4:1), stores it, returns {url, width, height}; pass the url in user_instructions.uploaded_images at campaign create (up to 5). jpeg/png/jpg/webp/gif/bmp, max 10MB. Optional auth — works for visitors too.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "file_path": {
                                        "type": "string",
                                        "description": "Absolute path to the image on the machine running the MCP server (preferred)."
                                    },
                                    "data_base64": {
                                        "type": "string",
                                        "description": "Raw base64 image data — alternative to file_path."
                                    },
                                    "filename": {
                                        "type": "string",
                                        "description": "Filename for data_base64 uploads (extension sets the type)."
                                    }
                                },
                                "additionalProperties": false
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        },
        "/v1/voices": {
            "get": {
                "operationId": "get.pipeline-voices",
                "tags": [
                    "pipeline-voices"
                ],
                "summary": "List in-action voices",
                "description": "Narrator voice catalog (dynamic; lang en|he, gender filter). Read before referencing a voice_id. The shared catalog plus the caller's own private voices (is_mine=true, listed first); another account's private voices are never returned.",
                "parameters": [
                    {
                        "name": "lang",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "en",
                                "he"
                            ]
                        }
                    },
                    {
                        "name": "gender",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "male",
                                "female",
                                "non_binary"
                            ],
                            "description": "Hard filter; language is a soft (ordering) preference."
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Envelope"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked credentials",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded (see Retry-After header)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "x-rate-limit": {
                    "class": "general",
                    "requests_per_minute": 60
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "AdGPT API key (`adgpt_…`), created from your account settings. First-party JWTs are also accepted."
            }
        },
        "schemas": {
            "Envelope": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean"
                    },
                    "data": true,
                    "message": {
                        "type": "string"
                    }
                }
            },
            "Error": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean"
                    },
                    "message": {
                        "type": "string"
                    },
                    "code": {
                        "type": "string"
                    }
                }
            }
        }
    }
}
