{
  "openapi": "3.1.0",
  "info": {
    "title": "Reviral Media API",
    "version": "1.0.0",
    "description": "Create an image or video with a currently listed model. The model catalog, reference limits, and credit prices are dynamic.",
    "contact": {
      "email": "support@reviral.ai",
      "url": "https://reviral.ai"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://reviral.ai/terms"
    }
  },
  "servers": [
    {
      "url": "https://reviral.ai",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/v1/models": {
      "get": {
        "summary": "List available models",
        "description": "Returns current visible, priced models and live prices. Limited to 60 requests per minute per trusted platform client address, or one global bucket when unavailable.",
        "responses": {
          "200": {
            "description": "Current dynamic model catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelsResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/v1/generate-media": {
      "get": {
        "summary": "Describe the generation contract",
        "responses": {
          "200": {
            "description": "Human-readable field and polling summary"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "post": {
        "summary": "Start a media job",
        "description": "Limited to 10 requests per minute and 200 per day per key. Video also has an account cap: 10 per hour and 100 per day until the account has paid history; 200 per day after. Reference counts and limits come from the selected model. Image credits are per image and count multiplies the charge.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateMediaRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job accepted or the original job returned when the same Idempotency-Key and request body are repeated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedJobResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadJson"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/GenerationFailed"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/Timeout"
          }
        },
        "callbacks": {
          "jobTerminal": {
            "{$request.body#/webhookUrl}": {
              "post": {
                "summary": "Best-effort terminal callback",
                "description": "Sent at most once with no retries. Delivery failure does not change the job.",
                "requestBody": {
                  "required": true,
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/WebhookPayload"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Callback received"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/uploads": {
      "post": {
        "summary": "Upload a photo, video, or audio reference",
        "description": "Store one magic-byte-checked JPG, PNG, or WebP image under the API-key account. The direct request-body cap is 4 MB; use sign, PUT, and verify for larger images, MP4, MP3, or WAV. Limited to 10 uploads per minute and 500 per day per key.",
        "security": [
          { "ApiKeyHeader": [] },
          { "ApiKeyAuthorization": [] },
          { "ApiKeyXReviral": [] },
          { "ApiKeyShort": [] }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "kind": { "type": "string", "enum": ["image", "video", "audio"], "default": "image" },
                  "file": { "type": "string", "format": "binary", "description": "JPG, PNG, or WebP image at most 4 MB. Video and audio use the signed-upload flow." }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": ["base64"],
                "properties": {
                  "kind": { "const": "image", "default": "image" },
                  "base64": { "type": "string", "description": "Raw base64 image bytes or an image data URL, at most 4 MB after decoding." }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Owned reference stored",
            "headers": {
              "Location": { "schema": { "type": "string", "format": "uri" } },
              "X-RateLimit-Limit": { "schema": { "type": "integer" } },
              "X-RateLimit-Remaining": { "schema": { "type": "integer" } },
              "X-RateLimit-Reset": { "schema": { "type": "integer" } }
            },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProductPhotoUploadResponse" } } }
          },
          "400": { "$ref": "#/components/responses/BadJson" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "413": { "$ref": "#/components/responses/ValidationError" },
          "415": { "$ref": "#/components/responses/ValidationError" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/GenerationFailed" },
          "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/uploads/sign": {
      "post": {
        "summary": "Create a signed reference-media upload",
        "description": "Create a two-hour signed staging PUT target for JPG, PNG, WebP, MP4, MP3, or WAV. The staging id cannot be used as a reference until uploads/verify succeeds; unverified objects are removed within the hourly sweep interval after expiry. The returned headers object is empty; do not forward a caller-chosen Content-Type. Shares the upload rate limit.",
        "security": [{ "ApiKeyAuthorization": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SignedUploadRequest" } } } },
        "responses": {
          "200": { "description": "Signed PUT target", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SignedUploadResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "413": { "$ref": "#/components/responses/ValidationError" },
          "415": { "$ref": "#/components/responses/ValidationError" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/uploads/verify": {
      "post": {
        "summary": "Verify uploaded reference media",
        "description": "Checks the stored size and magic bytes, probes media, rewrites the detected Content-Type, and promotes an owned staging upload to the final reference path.",
        "security": [{ "ApiKeyAuthorization": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "required": ["id"], "properties": { "id": { "type": "string" } } } } } },
        "responses": {
          "200": { "description": "Verified owned reference", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifiedUploadResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "413": { "$ref": "#/components/responses/ValidationError" },
          "415": { "$ref": "#/components/responses/ValidationError" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/v1/image-ads": {
      "post": {
        "summary": "Generate an image ad",
        "description": "Build one template-based product image and charge exactly the same credits as the web app. Poll the returned job with GET /api/v1/jobs/{id}.",
        "security": [
          { "ApiKeyHeader": [] },
          { "ApiKeyAuthorization": [] },
          { "ApiKeyXReviral": [] },
          { "ApiKeyShort": [] }
        ],
        "parameters": [
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ImageAdRequest" }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Image-ad job accepted",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageAdAcceptedResponse" } } }
          },
          "400": { "$ref": "#/components/responses/BadJson" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/GenerationFailed" },
          "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/image-ads/templates": {
      "get": {
        "summary": "List image-ad templates",
        "description": "Returns all 40 templates, their required fields, example pictures, and exact current web-app credit prices.",
        "security": [],
        "responses": {
          "200": {
            "description": "Current image-ad template catalog",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImageAdTemplatesResponse" } } }
          },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/director/chat": {
      "post": {
        "summary": "Chat with Director",
        "description": "Writes one Cinema planning reply. Free during launch. Send Accept: text/event-stream for the streaming form.",
        "security": [{ "ApiKeyHeader": [] }, { "ApiKeyAuthorization": [] }, { "ApiKeyXReviral": [] }, { "ApiKeyShort": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DirectorChatRequest" } } } },
        "responses": {
          "200": { "description": "Director reply", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DirectorChatResponse" } }, "text/event-stream": { "schema": { "type": "string" } } } },
          "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/Unauthorized" },
          "413": { "$ref": "#/components/responses/ValidationError" }, "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/GenerationFailed" },
          "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/ugc-ad": {
      "post": {
        "summary": "Start a UGC ad",
        "description": "Requires Idempotency-Key, quotes with the account's current rate, enforces maxCredits, then starts the shared UGC workflow. After a timeout, retry with the same Idempotency-Key.",
        "security": [{ "ApiKeyHeader": [] }, { "ApiKeyAuthorization": [] }, { "ApiKeyXReviral": [] }, { "ApiKeyShort": [] }],
        "parameters": [{ "name": "Idempotency-Key", "in": "header", "required": true, "description": "1-128 characters. Retry timeouts with the same value and request body.", "schema": { "type": "string", "minLength": 1, "maxLength": 128 } }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UgcAdRequest" } } } },
        "responses": {
          "202": { "description": "UGC ad accepted or idempotently replayed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UgcAdAcceptedResponse" } } } },
          "400": { "$ref": "#/components/responses/BadJson" }, "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/InsufficientCredits" }, "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/ValidationError" }, "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/GenerationFailed" }, "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/ugc-ad/options": {
      "get": {
        "summary": "List UGC ad options",
        "description": "Lists every accepted angle, creator, scene, mode, duration, resolution, and aspect value.",
        "security": [{ "ApiKeyHeader": [] }, { "ApiKeyAuthorization": [] }, { "ApiKeyXReviral": [] }, { "ApiKeyShort": [] }],
        "responses": {
          "200": { "description": "UGC option catalog", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UgcAdOptionsResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" }, "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/stitch": {
      "post": {
        "summary": "Stitch owned video jobs",
        "description": "Combines two to eight ready, same-aspect video jobs owned by the API-key account. Stitching is free.",
        "security": [{ "ApiKeyHeader": [] }, { "ApiKeyAuthorization": [] }, { "ApiKeyXReviral": [] }, { "ApiKeyShort": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StitchRequest" } } } },
        "responses": {
          "200": { "description": "An existing stitched video is ready", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StitchResponse" } } } },
          "202": { "description": "Stitch accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StitchResponse" } } } },
          "401": { "$ref": "#/components/responses/Unauthorized" }, "409": { "$ref": "#/components/responses/Conflict" },
          "422": { "$ref": "#/components/responses/ValidationError" }, "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/GenerationFailed" }, "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/script": {
      "post": {
        "summary": "Write a script", "description": "Uses the same moderated free script writer as the product.",
        "security": [{ "ApiKeyHeader": [] }, { "ApiKeyAuthorization": [] }, { "ApiKeyXReviral": [] }, { "ApiKeyShort": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ScriptWriterRequest" } } } },
        "responses": { "200": { "description": "Script response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WriterResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "422": { "$ref": "#/components/responses/ValidationError" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/GenerationFailed" }, "503": { "$ref": "#/components/responses/ServiceUnavailable" } }
      }
    },
    "/api/v1/hooks": {
      "post": {
        "summary": "Write hooks", "description": "Uses the same moderated free hook writer as the product.",
        "security": [{ "ApiKeyHeader": [] }, { "ApiKeyAuthorization": [] }, { "ApiKeyXReviral": [] }, { "ApiKeyShort": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HookWriterRequest" } } } },
        "responses": { "200": { "description": "Hook response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WriterResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "422": { "$ref": "#/components/responses/ValidationError" }, "429": { "$ref": "#/components/responses/RateLimited" }, "500": { "$ref": "#/components/responses/GenerationFailed" }, "502": { "$ref": "#/components/responses/GenerationFailed" }, "503": { "$ref": "#/components/responses/ServiceUnavailable" } }
      }
    },
    "/api/v1/prompt-builder": {
      "post": {
        "summary": "Build a video prompt", "description": "Uses the same moderated free structured prompt writer as the product.",
        "security": [{ "ApiKeyHeader": [] }, { "ApiKeyAuthorization": [] }, { "ApiKeyXReviral": [] }, { "ApiKeyShort": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PromptBuilderRequest" } } } },
        "responses": { "200": { "description": "Prompt response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WriterResponse" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "422": { "$ref": "#/components/responses/ValidationError" }, "429": { "$ref": "#/components/responses/RateLimited" }, "502": { "$ref": "#/components/responses/GenerationFailed" }, "503": { "$ref": "#/components/responses/ServiceUnavailable" } }
      }
    },
    "/api/v1/render": {
      "get": {
        "summary": "Describe the full render contract",
        "description": "Returns the current field, workflow, pricing, rate-limit, and response summary for the full short-form video endpoint.",
        "responses": {
          "200": {
            "description": "Human-readable full render contract"
          }
        }
      },
      "post": {
        "summary": "Start a full short-form video render",
        "description": "Starts a complete video workflow with script, voice, scenes, captions, and optional music.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Render accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request validation failed (forwarded from the render pipeline)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderPipelineError"
                }
              }
            }
          },
          "401": {
            "description": "Key is missing, revoked, or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "402": {
            "description": "Account needs more credits (forwarded from the render pipeline)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderPipelineError"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (forwarded from the render pipeline)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderPipelineError"
                }
              }
            }
          },
          "500": {
            "description": "The render could not be started (forwarded from the render pipeline; a rarer auth-layer failure instead returns LegacyErrorEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderPipelineError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs/{id}": {
      "get": {
        "summary": "Get job status",
        "description": "Limited to 120 requests per minute per key. Image creditsCharged is net of refunds.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Owned API job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/StatusFailed"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/v1/calculate-credits": {
      "get": {
        "summary": "Describe the credit estimate contract",
        "security": [],
        "responses": {
          "200": {
            "description": "Credit estimate contract"
          }
        }
      },
      "post": {
        "summary": "Estimate render or UGC-ad credits",
        "description": "Validates and estimates without a database write or credit debit. kind=ugc-ad requires an API key so the quote uses that account's rate; existing render and image-ad quotes remain public.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalculateCreditsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estimated credits and customer-safe breakdown"
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/ServiceUnavailable" }
        }
      }
    },
    "/api/v1/credit-costs": {
      "get": {
        "summary": "Get the credit cost reference",
        "security": [],
        "responses": {
          "200": {
            "description": "Current credit rate card"
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "summary": "Get the authenticated account",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "responses": {
          "200": {
            "description": "Account profile, plan, and credit balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Profile not found"
          },
          "502": {
            "description": "Account lookup unavailable"
          }
        }
      }
    },
    "/api/v1/characters": {
      "get": {
        "summary": "List saved characters",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "responses": {
          "200": {
            "description": "Owned active characters"
          },
          "401": {
            "description": "Key is missing, revoked, or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Character list unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a character",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CharacterRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Character created"
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Key is missing, revoked, or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Character save unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "501": {
            "description": "Requested character source is not implemented",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/characters/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Get one saved character",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "responses": {
          "200": {
            "description": "Owned active character"
          },
          "401": {
            "description": "Key is missing, revoked, or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Character not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Character lookup unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Soft-delete a saved character",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "responses": {
          "200": {
            "description": "Character deleted"
          },
          "400": {
            "description": "Invalid character ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Key is missing, revoked, or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Character delete unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/discover": {
      "get": {
        "summary": "List the public Discover feed",
        "description": "Returns the same trending topics and public video metadata as the public Discover page for the same source snapshot; refresh times can differ. Sources are YouTube, Hacker News, Wikipedia, Google Trends, and TikTok. Third-party titles and URLs are preserved. Internal descriptions and model metadata are excluded. Filter titles with q or select one visible source with tag. Requests are limited to 60 per minute per API key; invalid queries count toward this limit. This endpoint requires a configured, available rate-limit store. If it is unavailable, requests return 503 rate_limit_unavailable with Retry-After: 60 to keep throttling enforced.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "One-based result page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Items per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 24
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Case-insensitive title filter, matching the public page search box.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Visible source tag from the public page.",
            "schema": {
              "type": "string",
              "enum": [
                "youtube",
                "hackernews",
                "wikipedia",
                "google_trends",
                "tiktok"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated Discover page feed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscoverResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "description": "Discover feed unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/v1/media-search": {
      "get": {
        "summary": "Describe media search",
        "security": [],
        "responses": {
          "200": {
            "description": "Media search contract"
          }
        }
      },
      "post": {
        "summary": "Search available media",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "ApiKeyAuthorization": []
          },
          {
            "ApiKeyXReviral": []
          },
          {
            "ApiKeyShort": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MediaSearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ranked matching media"
          },
          "400": {
            "description": "Invalid body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "Key is missing, revoked, or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LegacyErrorEnvelope"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key in x-api-key header."
      },
      "ApiKeyAuthorization": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rvr_<hex>",
        "description": "API key in Authorization: Bearer header."
      },
      "ApiKeyXReviral": {
        "type": "apiKey",
        "in": "header",
        "name": "x-reviral-api-key",
        "description": "API key in x-reviral-api-key header."
      },
      "ApiKeyShort": {
        "type": "apiKey",
        "in": "header",
        "name": "key",
        "description": "API key in key header."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "1-128 characters. Reuse the same value only with the same request body. A different body returns 409 idempotency_key_reuse.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        }
      }
    },
    "schemas": {
      "DurationRange": {
        "type": "object",
        "required": [
          "kind",
          "min",
          "max"
        ],
        "properties": {
          "kind": {
            "const": "range"
          },
          "min": {
            "type": "integer"
          },
          "max": {
            "type": "integer"
          }
        }
      },
      "DurationEnum": {
        "type": "object",
        "required": [
          "kind",
          "values"
        ],
        "properties": {
          "kind": {
            "const": "enum"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        }
      },
      "CreditPrice": {
        "type": "object",
        "properties": {
          "perSecond": {
            "type": "number",
            "description": "Published to four decimal places."
          },
          "creditsAtDefaultDuration": {
            "type": "integer",
            "description": "Real rounded charge at the model default duration."
          },
          "perVideo": {
            "type": "integer"
          },
          "perImage": {
            "type": "integer",
            "description": "Credits per image; count multiplies."
          },
          "byDuration": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "ModelDefaults": {
        "type": "object",
        "required": [
          "resolution",
          "aspectRatio"
        ],
        "properties": {
          "durationSec": {
            "type": "integer"
          },
          "resolution": {
            "type": "string"
          },
          "aspectRatio": {
            "type": "string"
          },
          "count": {
            "type": "integer",
            "minimum": 1
          }
        }
      },
      "ModelReferences": {
        "type": "object",
        "required": ["images", "videos", "audio"],
        "properties": {
          "images": {
            "type": "object",
            "required": ["max"],
            "properties": { "max": { "type": "integer", "minimum": 0 } }
          },
          "videos": {
            "type": "object",
            "required": ["max", "maxSeconds", "maxBytes"],
            "properties": {
              "max": { "type": "integer", "minimum": 0 },
              "maxSeconds": { "type": ["number", "null"], "minimum": 0, "description": "null means the registry has no published duration limit; max 0 means video references are unsupported." },
              "maxBytes": { "type": "integer", "minimum": 0 }
            }
          },
          "audio": {
            "type": "object",
            "required": ["max", "maxBytes", "needsVisual"],
            "properties": {
              "max": { "type": "integer", "minimum": 0 },
              "maxBytes": { "type": "integer", "minimum": 0 },
              "needsVisual": { "type": "boolean" }
            }
          }
        }
      },
      "Model": {
        "type": "object",
        "required": [
          "id",
          "kind",
          "label",
          "family",
          "maker",
          "billing",
          "durations",
          "resolutions",
          "aspects",
          "credits",
          "references",
          "defaults"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable public alias."
          },
          "kind": {
            "enum": [
              "video",
              "image"
            ]
          },
          "label": {
            "type": "string"
          },
          "family": {
            "type": "string"
          },
          "maker": {
            "type": "string"
          },
          "billing": {
            "enum": [
              "per_second",
              "per_request"
            ]
          },
          "durations": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DurationRange"
              },
              {
                "$ref": "#/components/schemas/DurationEnum"
              }
            ]
          },
          "resolutions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "aspects": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "credits": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/CreditPrice"
            }
          },
          "references": {
            "$ref": "#/components/schemas/ModelReferences"
          },
          "defaults": {
            "$ref": "#/components/schemas/ModelDefaults"
          }
        }
      },
      "ModelsResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "description": "Dynamic; only models available at request time.",
            "items": {
              "$ref": "#/components/schemas/Model"
            }
          }
        }
      },
      "GenerateMediaRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "model",
          "prompt"
        ],
        "description": "Reference arrays are ordered for @image1, @video1, and @audio1 tags and are limited by the selected model's references block.",
        "properties": {
          "model": {
            "type": "string"
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100000
          },
          "durationSec": {
            "type": "integer",
            "minimum": 1
          },
          "resolution": {
            "type": "string"
          },
          "aspectRatio": {
            "type": "string"
          },
          "generateAudio": {
            "type": "boolean"
          },
          "referenceImageUrls": {
            "type": "array",
            "maxItems": 50,
            "items": { "type": "string", "format": "uri" }
          },
          "referenceVideoUrls": {
            "type": "array",
            "maxItems": 50,
            "items": { "type": "string", "format": "uri" }
          },
          "referenceAudioUrls": {
            "type": "array",
            "maxItems": 50,
            "items": { "type": "string", "format": "uri" }
          },
          "size": {
            "type": "string"
          },
          "count": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4,
            "description": "Image count; multiplies perImage credits."
          },
          "maxCredits": {
            "type": "integer",
            "minimum": 0,
            "description": "Price lock. A different live charge returns 409 price_changed."
          },
          "webhookUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "UploadResponse": {
        "type": "object",
        "required": ["data"],
        "properties": {
          "data": {
            "type": "object",
            "required": ["url", "kind", "bytes"],
            "properties": {
              "url": { "type": "string", "format": "uri", "description": "HTTPS URL owned by the API-key account." },
              "kind": { "type": "string", "enum": ["image", "video", "audio"] },
              "bytes": { "type": "integer", "minimum": 1 },
              "durationSec": { "type": "number", "minimum": 0 }
            }
          }
        }
      },
      "ProductPhotoUploadResponse": {
        "type": "object",
        "required": ["ok", "data"],
        "properties": {
          "ok": { "const": true },
          "data": {
            "type": "object",
            "required": ["id", "url", "kind", "width", "height", "bytes"],
            "properties": {
              "id": { "type": "string", "description": "Owned upload id accepted by the UGC API." },
              "url": { "type": "string", "format": "uri" },
              "kind": { "const": "product_photo" },
              "width": { "type": "integer", "minimum": 1 },
              "height": { "type": "integer", "minimum": 1 },
              "bytes": { "type": "integer", "minimum": 1 }
            }
          }
        }
      },
      "SignedUploadRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["kind", "contentType", "bytes", "filename"],
        "properties": {
          "kind": { "type": "string", "enum": ["image", "video", "audio"] },
          "contentType": { "type": "string", "enum": ["image/jpeg", "image/png", "image/webp", "video/mp4", "audio/mpeg", "audio/wav"] },
          "bytes": { "type": "integer", "minimum": 1, "maximum": 67108864 },
          "filename": { "type": "string", "minLength": 1, "maxLength": 255 }
        }
      },
      "SignedUploadResponse": {
        "type": "object",
        "required": ["data"],
        "properties": { "data": { "type": "object", "required": ["id", "uploadUrl", "method", "headers", "expiresInSec"], "properties": {
          "id": { "type": "string" }, "uploadUrl": { "type": "string", "format": "uri" }, "method": { "const": "PUT" },
          "headers": { "type": "object", "additionalProperties": { "type": "string" } }, "expiresInSec": { "type": "integer", "minimum": 1 }
        } } }
      },
      "VerifiedUploadResponse": {
        "type": "object",
        "required": ["data"],
        "properties": { "data": { "type": "object", "required": ["id", "url", "kind", "bytes"], "properties": {
          "id": { "type": "string" }, "url": { "type": "string", "format": "uri" }, "kind": { "type": "string", "enum": ["image", "video", "audio"] },
          "bytes": { "type": "integer", "minimum": 1 }, "width": { "type": "integer", "minimum": 1 }, "height": { "type": "integer", "minimum": 1 }, "durationSec": { "type": "number", "exclusiveMinimum": 0 }
        } } }
      },
      "ImageAdProduct": {
        "type": "object",
        "additionalProperties": false,
        "required": ["title", "bullets", "price", "photos", "rating", "reviews", "brand"],
        "properties": {
          "title": { "type": "string", "minLength": 1, "maxLength": 200 },
          "bullets": { "type": "array", "minItems": 1, "maxItems": 20, "items": { "type": "string", "minLength": 1, "maxLength": 300 } },
          "price": { "type": "string", "minLength": 1, "maxLength": 80 },
          "photos": { "type": "array", "maxItems": 16, "items": { "type": "string", "format": "uri", "description": "HTTPS URL for an upload owned by the API-key account." } },
          "rating": { "type": "number", "minimum": 0, "maximum": 5 },
          "reviewCount": { "type": "integer", "minimum": 0, "maximum": 1000000000 },
          "reviews": { "type": "array", "maxItems": 20, "items": { "type": "string", "minLength": 1, "maxLength": 600 } },
          "brand": { "type": "string", "minLength": 1, "maxLength": 120 }
        }
      },
      "ImageAdBrand": {
        "type": "object",
        "additionalProperties": false,
        "required": ["colors", "fonts", "voice", "neverSay", "logoUrl"],
        "properties": {
          "colors": { "type": "array", "minItems": 1, "maxItems": 8, "items": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" } },
          "fonts": { "type": "array", "minItems": 1, "maxItems": 6, "items": { "type": "string", "minLength": 1, "maxLength": 100 } },
          "voice": { "type": "array", "minItems": 1, "maxItems": 12, "items": { "type": "string", "minLength": 1, "maxLength": 40 } },
          "neverSay": { "type": "array", "maxItems": 30, "items": { "type": "string", "minLength": 1, "maxLength": 100 } },
          "logoUrl": { "type": ["string", "null"], "format": "uri", "description": "Owned upload URL, or null." }
        }
      },
      "ImageAdRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["templateId", "product", "brand", "copy"],
        "example": {
          "templateId": "headline",
          "product": {
            "title": "Trail shoe",
            "bullets": ["Grippy rubber outsole"],
            "price": "$89",
            "photos": ["$PRODUCT_URL"],
            "rating": 4.7,
            "reviewCount": 92,
            "reviews": ["Held up on wet trails"],
            "brand": "North"
          },
          "brand": {
            "colors": ["#112233", "#DDEEFF", "#F4F4F4"],
            "fonts": ["Inter"],
            "voice": ["direct"],
            "neverSay": [],
            "logoUrl": null
          },
          "copy": {
            "headline": "Move beyond the pavement",
            "subhead": "Grip wet trails with confidence."
          },
          "creative": { "surface": "light stone studio surface" }
        },
        "properties": {
          "templateId": { "type": "string", "description": "ID returned by GET /api/v1/image-ads/templates." },
          "sizeId": { "type": "string", "description": "Optional web-app size ID; the template default is used when omitted." },
          "product": { "$ref": "#/components/schemas/ImageAdProduct" },
          "brand": { "$ref": "#/components/schemas/ImageAdBrand" },
          "copy": { "type": "object", "additionalProperties": { "type": "string", "maxLength": 400 }, "description": "Template text slots listed in requiredFields." },
          "creative": { "type": "object", "additionalProperties": { "type": "string", "maxLength": 400 }, "description": "Scene details listed as creative.* paths by the selected template's requiredFields and fields table." },
          "background": { "type": "string", "maxLength": 400 },
          "mood": { "type": "array", "maxItems": 12, "items": { "type": "string", "maxLength": 60 } },
          "finish": { "type": "string", "maxLength": 400 },
          "offerAvailable": { "type": "boolean" },
          "maxCredits": { "type": "integer", "minimum": 0, "description": "Exact price lock; a different current web-app price returns 409." },
          "webhookUrl": { "type": "string", "format": "uri" }
        }
      },
      "ImageAdAcceptedResponse": {
        "type": "object",
        "required": ["ok", "data"],
        "properties": {
          "ok": { "const": true },
          "data": {
            "type": "object",
            "required": ["jobId", "status", "credits", "statusUrl"],
            "properties": {
              "jobId": { "type": "string", "format": "uuid" },
              "status": { "const": "queued" },
              "credits": { "type": "integer", "minimum": 0 },
              "statusUrl": { "type": "string" }
            }
          }
        }
      },
      "ImageAdTemplateField": {
        "type": "object",
        "additionalProperties": false,
        "required": ["path", "type", "description", "example"],
        "properties": {
          "path": { "type": "string", "description": "Request-body path required by this template." },
          "type": { "type": "string", "description": "Accepted value type in plain words." },
          "description": { "type": "string", "description": "Plain-words meaning of the field." },
          "example": { "description": "Example value accepted at this path." }
        }
      },
      "ImageAdTemplateConstraints": {
        "type": "object",
        "description": "Machine-readable rules keyed by the same copyable JSON paths used in requiredFields.",
        "additionalProperties": {
          "type": "object",
          "additionalProperties": false,
          "required": ["minItems"],
          "properties": {
            "minItems": { "type": "integer", "minimum": 1, "description": "Minimum number of values required at this array path." }
          }
        }
      },
      "ImageAdTemplate": {
        "type": "object",
        "required": ["id", "name", "category", "requiredFields", "constraints", "fields", "examplePictureUrl", "credits"],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "category": { "type": "string" },
          "requiredFields": { "type": "array", "description": "Copyable JSON paths required in the request body. Array-length rules are listed separately in constraints.", "items": { "type": "string", "pattern": "^[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)*$" } },
          "constraints": { "$ref": "#/components/schemas/ImageAdTemplateConstraints" },
          "fields": { "type": "array", "description": "Descriptions and examples for every requiredFields path, derived from the validator rules.", "items": { "$ref": "#/components/schemas/ImageAdTemplateField" } },
          "examplePictureUrl": { "type": "string" },
          "credits": { "type": "integer", "minimum": 0, "description": "Exact current web-app price." }
        }
      },
      "ImageAdTemplatesResponse": {
        "type": "object",
        "required": ["ok", "data"],
        "properties": {
          "ok": { "const": true },
          "data": { "type": "array", "minItems": 40, "maxItems": 40, "items": { "$ref": "#/components/schemas/ImageAdTemplate" } }
        }
      },
      "RenderRequest": {
        "type": "object",
        "additionalProperties": true,
        "required": [
          "workflow"
        ],
        "properties": {
          "workflow": {
            "type": "string",
            "enum": [
              "prompt-to-video",
              "script-to-video",
              "article-to-video",
              "static-bg-video",
              "caption-video",
              "ad-generator",
              "ugc-ad",
              "avatar-to-video",
              "quiz-video"
            ]
          },
          "prompt": {
            "type": "string",
            "maxLength": 100000
          },
          "userScript": {
            "type": "string",
            "maxLength": 4000
          },
          "articleUrl": {
            "type": "string",
            "format": "uri"
          },
          "videoUrl": {
            "type": "string",
            "format": "uri"
          },
          "productUrl": {
            "type": "string",
            "format": "uri"
          },
          "avatarImageUrl": {
            "type": "string",
            "format": "uri"
          },
          "tier": {
            "type": "string",
            "enum": [
              "base",
              "pro",
              "ultra"
            ],
            "default": "pro"
          },
          "durationSec": {
            "type": "integer",
            "minimum": 15,
            "maximum": 300,
            "default": 30
          },
          "aspectRatio": {
            "type": "string",
            "enum": [
              "9:16",
              "16:9",
              "1:1",
              "auto"
            ],
            "default": "9:16"
          },
          "presetId": {
            "type": "string",
            "default": "stock"
          },
          "language": {
            "type": "string",
            "default": "en"
          },
          "captionStyle": {
            "type": "string",
            "default": "highlight"
          },
          "captionPosition": {
            "type": "string",
            "enum": [
              "top",
              "middle",
              "bottom"
            ],
            "default": "bottom"
          },
          "music": {
            "type": "boolean",
            "default": true
          },
          "webhookUrl": {
            "type": "string",
            "format": "uri"
          },
          "referenceImageUrls": {
            "type": "array",
            "items": { "type": "string", "format": "uri" },
            "description": "Ordered owned image references for workflow cinema."
          },
          "referenceVideoUrls": {
            "type": "array",
            "items": { "type": "string", "format": "uri" },
            "description": "Ordered owned video references for workflow cinema."
          },
          "referenceAudioUrls": {
            "type": "array",
            "items": { "type": "string", "format": "uri" },
            "description": "Ordered owned audio references for workflow cinema."
          },
          "nbGenerations": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10
          },
          "musicUrl": {
            "type": "string",
            "format": "uri"
          },
          "voiceId": {
            "type": "string",
            "minLength": 8
          },
          "musicTrackId": {
            "type": "string",
            "maxLength": 40
          },
          "improveConsistency": {
            "type": "boolean",
            "default": true
          },
          "continuousMode": {
            "type": "boolean",
            "default": false
          },
          "premiumVideoModelId": {
            "type": "string",
            "maxLength": 40
          },
          "mediaItems": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/MediaItem"
            }
          }
        }
      },
      "RenderResponse": {
        "type": "object",
        "required": [
          "projectId",
          "renderJobId",
          "debited",
          "balanceBefore"
        ],
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid"
          },
          "renderJobId": {
            "type": "string",
            "format": "uuid"
          },
          "debited": {
            "type": "integer",
            "description": "Credits charged when the render starts."
          },
          "balanceBefore": {
            "type": "integer",
            "description": "Credit balance immediately before this charge."
          }
        }
      },
      "AcceptedJob": {
        "type": "object",
        "required": [
          "jobId",
          "kind",
          "model",
          "creditsCharged",
          "status",
          "statusUrl"
        ],
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "enum": [
              "video",
              "image"
            ]
          },
          "model": {
            "type": "string"
          },
          "creditsCharged": {
            "type": "integer"
          },
          "status": {
            "const": "queued"
          },
          "statusUrl": {
            "type": "string"
          }
        }
      },
      "AcceptedJobResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AcceptedJob"
          }
        }
      },
      "Job": {
        "type": "object",
        "required": [
          "jobId",
          "kind",
          "model",
          "modelUsed",
          "modelsUsed",
          "fallbackFired",
          "status",
          "creditsCharged"
        ],
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "enum": [
              "video",
              "image"
            ]
          },
          "model": {
            "type": "string",
            "description": "Public model requested when the job was submitted."
          },
          "modelUsed": {
            "type": "string",
            "description": "Model used for the last clip. See modelsUsed for index-aligned per-clip truth on mixed outputs."
          },
          "modelsUsed": {
            "type": "array",
            "description": "Index-aligned model identity for each produced clip. Single-output jobs contain one item.",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "fallbackFired": {
            "type": "boolean",
            "description": "True when generation switched from the requested model to a fallback model."
          },
          "status": {
            "enum": [
              "queued",
              "running",
              "ready",
              "failed"
            ]
          },
          "outputUrl": {
            "type": "string",
            "format": "uri"
          },
          "outputUrls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "outputPending": {
            "type": "boolean",
            "description": "True when a video is ready but a signed delivery URL is not yet available."
          },
          "durationSec": {
            "type": "integer"
          },
          "creditsCharged": {
            "type": "integer",
            "description": "Net charge after refunds."
          },
          "error": {
            "type": "string"
          }
        }
      },
      "JobResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Job"
          }
        }
      },
      "WebhookReady": {
        "type": "object",
        "required": [
          "ok",
          "status",
          "jobId",
          "kind",
          "modelUsed",
          "fallbackFired"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "status": {
            "const": "ready"
          },
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "enum": [
              "video",
              "image"
            ]
          },
          "model": {
            "type": "string"
          },
          "modelUsed": {
            "type": "string"
          },
          "fallbackFired": {
            "type": "boolean"
          },
          "outputUrl": {
            "type": "string",
            "format": "uri"
          },
          "outputUrls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "durationSec": {
            "type": "integer"
          },
          "partial": {
            "type": "boolean"
          },
          "deliveredCount": {
            "type": "integer",
            "minimum": 1
          }
        }
      },
      "WebhookFailed": {
        "type": "object",
        "required": [
          "ok",
          "status",
          "jobId",
          "modelUsed",
          "fallbackFired",
          "error"
        ],
        "properties": {
          "ok": {
            "const": false
          },
          "status": {
            "const": "failed"
          },
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "modelUsed": {
            "type": "string"
          },
          "fallbackFired": {
            "type": "boolean"
          },
          "error": {
            "type": "string"
          }
        }
      },
      "WebhookPayload": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/WebhookReady"
          },
          {
            "$ref": "#/components/schemas/WebhookFailed"
          }
        ]
      },
      "FieldError": {
        "type": "object",
        "required": [
          "field",
          "message",
          "code"
        ],
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        }
      },
      "ErrorBody": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldError"
            }
          },
          "required": {
            "type": "integer"
          },
          "balance": {
            "type": "integer"
          },
          "idempotencyKey": {
            "type": "string"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error",
          "docs"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorBody"
          },
          "docs": {
            "const": "/docs/api"
          }
        }
      },
      "DiscoverVideo": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "platform",
          "videoId",
          "thumbnailUrl",
          "videoUrl",
          "viewCount"
        ],
        "properties": {
          "platform": {
            "type": "string",
            "enum": [
              "youtube",
              "tiktok",
              "instagram"
            ]
          },
          "videoId": {
            "type": "string"
          },
          "thumbnailUrl": {
            "type": "string",
            "format": "uri"
          },
          "videoUrl": {
            "type": "string",
            "format": "uri"
          },
          "viewCount": {
            "type": "integer",
            "minimum": 0
          },
          "likeCount": {
            "type": "integer",
            "minimum": 0
          },
          "creator": {
            "type": "string"
          }
        }
      },
      "DiscoverItem": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "title",
          "source",
          "tags"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "youtube",
              "hackernews",
              "wikipedia",
              "google_trends",
              "tiktok"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "score": {
            "type": "number",
            "minimum": 0
          },
          "traffic": {
            "type": "string"
          },
          "imageUrl": {
            "type": "string",
            "format": "uri"
          },
          "region": {
            "type": "string"
          },
          "video": {
            "$ref": "#/components/schemas/DiscoverVideo"
          }
        }
      },
      "DiscoverResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "data",
          "docs"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "items",
              "page",
              "limit",
              "total"
            ],
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DiscoverItem"
                }
              },
              "page": {
                "type": "integer",
                "minimum": 1
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100
              },
              "total": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "docs": {
            "const": "/docs/api/discover"
          }
        }
      },
      "MediaItem": {
        "type": "object",
        "required": [
          "url"
        ],
        "additionalProperties": false,
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2000
          },
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video"
            ]
          },
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "urlLowRes": {
            "type": "string",
            "format": "uri",
            "maxLength": 2000
          },
          "imagePreview": {
            "type": "string",
            "format": "uri",
            "maxLength": 2000
          },
          "noReencode": {
            "type": "boolean"
          }
        }
      },
      "CalculateCreditsRequest": {
        "oneOf": [
          { "$ref": "#/components/schemas/RenderCalculateCreditsRequest" },
          { "$ref": "#/components/schemas/ImageAdCreditsRequest" },
          { "$ref": "#/components/schemas/UgcAdCreditsRequest" }
        ]
      },
      "RenderCalculateCreditsRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "tier": {
            "type": "string",
            "enum": [
              "base",
              "pro",
              "ultra"
            ],
            "default": "pro"
          },
          "mediaType": {
            "type": "string",
            "enum": [
              "ai-video",
              "ai-moving",
              "motion-graphics",
              "stock-videos",
              "user-upload",
              "static-images",
              "ai-action"
            ],
            "default": "ai-video"
          },
          "durationSec": {
            "type": "integer",
            "minimum": 15,
            "maximum": 300,
            "default": 30
          },
          "presetId": {
            "type": "string",
            "default": "stock"
          },
          "nbGenerations": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10
          }
        }
      },
      "ImageAdCreditsRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["kind", "templateId"],
        "properties": {
          "kind": { "const": "image-ad" },
          "templateId": { "type": "string", "minLength": 1, "maxLength": 80 },
          "sizeId": { "type": "string", "minLength": 1, "maxLength": 40 }
        }
      },
      "UgcAdCreditsRequest": {
        "type": "object", "additionalProperties": false, "required": ["kind"],
        "properties": {
          "kind": { "const": "ugc-ad" }, "mode": { "type": "string", "enum": ["i2v", "r2v"], "default": "r2v" },
          "durationSec": { "type": "integer", "enum": [15, 30, 45, 60], "default": 15 },
          "resolution": { "type": "string", "enum": ["480p", "720p", "1080p"], "default": "720p" },
          "singleClip": { "type": "boolean", "default": true }
        }
      },
      "DirectorChatRequest": {
        "oneOf": [
          { "$ref": "#/components/schemas/DirectorSimpleChatRequest" },
          { "$ref": "#/components/schemas/DirectorPublishedChatRequest" }
        ]
      },
      "DirectorSimpleChatRequest": {
        "type": "object", "additionalProperties": false, "required": ["message"],
        "properties": {
          "message": { "type": "string", "minLength": 1, "maxLength": 100000 },
          "chatId": { "type": "string", "format": "uuid" },
          "model": { "type": "string", "minLength": 1, "maxLength": 120, "description": "Video model id from GET /api/v1/models." },
          "durationSec": { "type": "integer", "minimum": 1 },
          "resolution": { "type": "string", "minLength": 1, "maxLength": 40 },
          "aspectRatio": { "type": "string", "minLength": 1, "maxLength": 40 },
          "referenceImageUrls": { "type": "array", "maxItems": 50, "items": { "type": "string", "format": "uri" } },
          "referenceVideoUrls": { "type": "array", "maxItems": 50, "items": { "type": "string", "format": "uri" } },
          "referenceAudioUrls": { "type": "array", "maxItems": 50, "items": { "type": "string", "format": "uri" } }
        }
      },
      "DirectorPublishedChatRequest": {
        "type": "object", "additionalProperties": false, "required": ["messages", "cinemaContext"],
        "properties": {
          "messages": { "type": "array", "minItems": 1, "maxItems": 200, "items": { "type": "object", "additionalProperties": false, "required": ["role", "content"], "properties": { "role": { "type": "string", "enum": ["user", "assistant"] }, "content": { "type": "string", "minLength": 1 } } } },
          "cinemaContext": { "type": "object", "additionalProperties": false, "required": ["modelId", "durationSec"], "properties": {
            "modelId": { "type": "string", "minLength": 1, "maxLength": 120 }, "durationSec": { "type": "integer", "minimum": 1 },
            "resolution": { "type": "string", "minLength": 1, "maxLength": 40 }, "aspect": { "type": "string", "minLength": 1, "maxLength": 40 },
            "references": { "type": "array", "maxItems": 50, "items": { "type": "object", "additionalProperties": false, "required": ["kind", "index", "name", "token"], "properties": { "kind": { "type": "string", "enum": ["image", "video", "audio"] }, "index": { "type": "integer", "minimum": 0 }, "name": { "type": "string", "minLength": 1, "maxLength": 120 }, "token": { "type": "string", "minLength": 1, "maxLength": 32 } } } }
          } }
        }
      },
      "DirectorChatResponse": {
        "type": "object",
        "properties": { "data": { "type": "object", "properties": { "chatId": { "type": "string", "format": "uuid" }, "reply": { "type": "string" }, "status": { "type": "string", "enum": ["talking", "prompt_ready"] }, "prompt": { "type": "string" }, "plan": {} } } },
        "oneOf": [
          { "$ref": "#/components/schemas/DirectorSimpleChatResponse" },
          { "$ref": "#/components/schemas/DirectorPublishedChatResponse" }
        ]
      },
      "DirectorSimpleChatResponse": { "type": "object", "required": ["data"], "properties": { "data": { "type": "object", "required": ["chatId", "reply", "status"], "properties": { "chatId": { "type": "string", "format": "uuid" }, "reply": { "type": "string" }, "status": { "type": "string", "enum": ["talking", "prompt_ready"] }, "prompt": { "type": "string" }, "plan": {} } } } },
      "DirectorPublishedChatResponse": { "type": "object", "required": ["data"], "properties": { "data": { "type": "object", "required": ["replyId", "reply", "chatId", "status"], "properties": { "replyId": { "type": "string", "format": "uuid" }, "reply": { "type": "string" }, "finalPrompt": { "type": "string" }, "chatId": { "type": "string", "format": "uuid" }, "status": { "type": "string", "enum": ["talking", "prompt_ready"] }, "prompt": { "type": "string" }, "plan": {} } } } },
      "UgcAdRequest": {
        "type": "object", "additionalProperties": false, "required": ["uploadId", "prompt", "angle", "creator", "scene"],
        "properties": {
          "uploadId": { "type": "string", "description": "Owned id returned by POST /api/v1/uploads." },
          "prompt": { "type": "string", "minLength": 8, "maxLength": 100000 }, "angle": { "type": "string", "enum": ["testimonial", "unboxing", "before-after", "problem-solution", "founder", "day-in-life"] },
          "creator": { "type": "string", "enum": ["skincare", "lifestyle", "fitness", "tech"] }, "scene": { "type": "string", "enum": ["home", "kitchen", "cafe", "desk"] },
          "singleClip": { "type": "boolean", "default": true }, "mode": { "type": "string", "enum": ["i2v", "r2v"], "default": "r2v" },
          "durationSec": { "type": "integer", "enum": [15, 30, 45, 60], "default": 15 }, "resolution": { "type": "string", "enum": ["480p", "720p", "1080p"], "default": "720p" },
          "aspectRatio": { "type": "string", "enum": ["9:16", "16:9", "1:1"], "default": "9:16" }, "maxCredits": { "type": "integer", "minimum": 0 }, "webhookUrl": { "type": "string", "format": "uri" }
        }
      },
      "UgcAdAcceptedResponse": { "type": "object", "required": ["data"], "properties": { "data": { "type": "object", "required": ["jobId", "kind", "creditsCharged", "status", "statusUrl"], "properties": { "jobId": { "type": "string", "format": "uuid" }, "kind": { "const": "ugc-ad" }, "creditsCharged": { "type": "integer", "minimum": 0 }, "status": { "type": "string", "enum": ["queued", "running", "ready", "failed"] }, "statusUrl": { "type": "string" } } } } },
      "UgcAdOptionsResponse": { "type": "object", "required": ["data"], "properties": { "data": { "type": "object", "required": ["angles", "creators", "scenes", "modes", "durationsSec", "resolutions", "aspectRatios"], "additionalProperties": true } } },
      "StitchRequest": { "type": "object", "additionalProperties": false, "required": ["projectIds"], "properties": { "projectIds": { "type": "array", "minItems": 2, "maxItems": 8, "uniqueItems": true, "items": { "type": "string", "format": "uuid" } } } },
      "StitchResponse": { "type": "object", "required": ["data"], "properties": { "data": { "type": "object", "required": ["jobId", "kind", "creditsCharged", "status", "statusUrl"], "properties": { "jobId": { "type": "string", "format": "uuid" }, "kind": { "const": "stitch" }, "creditsCharged": { "const": 0 }, "status": { "type": "string", "enum": ["queued", "ready"] }, "statusUrl": { "type": "string" } } } } },
      "ScriptWriterRequest": { "type": "object", "additionalProperties": false, "required": ["prompt"], "properties": { "prompt": { "type": "string", "minLength": 8, "maxLength": 100000 }, "durationSec": { "type": "integer", "minimum": 15, "maximum": 120, "default": 30 }, "tone": { "type": "string" }, "scriptFormat": { "type": "string" }, "mediaType": { "type": "string" }, "variants": { "type": "integer", "minimum": 1, "maximum": 3, "default": 1 }, "wordsOnly": { "type": "boolean", "default": false }, "assetBlocks": { "type": "array", "maxItems": 3, "items": { "type": "string", "maxLength": 6000 } } } },
      "HookWriterRequest": { "type": "object", "additionalProperties": false, "required": ["topic"], "properties": { "topic": { "type": "string", "minLength": 8, "maxLength": 500 }, "clickbait": { "type": "integer", "minimum": 1, "maximum": 5, "default": 3 } } },
      "PromptBuilderRequest": { "type": "object", "additionalProperties": false, "required": ["brief", "durationSec", "section1MaxChars", "styleId", "effectEnabled", "effectId", "images"], "properties": { "brief": { "type": "string", "maxLength": 5000 }, "durationSec": { "type": "integer", "minimum": 5, "maximum": 300 }, "section1MaxChars": { "type": ["integer", "null"], "minimum": 500, "maximum": 3500, "multipleOf": 500 }, "styleId": { "type": "string", "minLength": 1, "maxLength": 100 }, "effectEnabled": { "type": "boolean" }, "effectId": { "type": ["string", "null"], "minLength": 1, "maxLength": 100 }, "images": { "type": "array", "maxItems": 4, "items": { "type": "object", "additionalProperties": false, "required": ["name", "mediaType", "base64"], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 160 }, "mediaType": { "type": "string", "enum": ["image/jpeg", "image/png", "image/webp", "image/gif"] }, "base64": { "type": "string", "minLength": 16, "maxLength": 7000000 } } } }, "variationSeed": { "type": "string", "minLength": 1, "maxLength": 100 }, "compact": { "type": "boolean" } } },
      "WriterResponse": { "type": "object", "required": ["data"], "properties": { "data": { "type": "object", "additionalProperties": true } } },
      "CharacterRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60
          },
          "description": {
            "type": "string",
            "minLength": 10,
            "maxLength": 500
          },
          "imageUrl": {
            "type": "string",
            "format": "uri",
            "maxLength": 2000
          },
          "source": {
            "type": "string",
            "enum": [
              "avatar",
              "lora"
            ],
            "default": "avatar"
          },
          "voiceId": {
            "type": "string",
            "maxLength": 60
          }
        }
      },
      "MediaSearchRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "query"
        ],
        "properties": {
          "query": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "any"
            ],
            "default": "any"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 50,
            "default": 20
          }
        }
      },
      "SuccessEnvelope": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "type": "object"
          },
          "docs": {
            "type": "string"
          }
        }
      },
      "AccountResponse": {
        "type": "object",
        "required": [
          "ok",
          "data",
          "docs"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "type": "object",
            "required": [
              "profileId",
              "plan",
              "credits"
            ],
            "properties": {
              "profileId": {
                "type": "string",
                "format": "uuid"
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "displayName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "avatarUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri"
              },
              "about": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "timezone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "topics": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "plan": {
                "type": "string"
              },
              "credits": {
                "type": "number"
              },
              "aiSettings": {
                "type": [
                  "object",
                  "null"
                ]
              }
            }
          },
          "docs": {
            "const": "/docs/api"
          }
        }
      },
      "LegacyErrorEnvelope": {
        "type": "object",
        "description": "Legacy error envelope. POST /api/v1/render's own auth check and every response from /api/v1/characters, /api/v1/characters/{id}, and /api/v1/media-search use this shape instead of ErrorResponse. See /docs/api/errors for which endpoints return which envelope.",
        "required": [
          "ok",
          "error",
          "docs"
        ],
        "properties": {
          "ok": {
            "const": false
          },
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "detail": {
            "description": "A human-readable string, or a zod .flatten() validation object."
          },
          "docs": {
            "type": "string"
          }
        }
      },
      "RenderPipelineError": {
        "type": "object",
        "description": "POST /api/v1/render forwards most non-auth failures (400, 402, 429, and most 500s) verbatim from the internal render pipeline. The body always has a short string 'error' code; other fields vary by code (for example 'required' and 'balance' on insufficient_credits, or 'retryAfterSec' on rate_limited). Unlike ErrorResponse and LegacyErrorEnvelope, it has no 'ok' or 'docs' field.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    },
    "responses": {
      "BadJson": {
        "description": "Body is empty or is not JSON",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Key is missing, revoked, or invalid",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InsufficientCredits": {
        "description": "Account needs more credits",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Model is not available",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "JobNotFound": {
        "description": "Job is not owned or does not exist",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "PriceChanged": {
        "description": "The live charge differs from maxCredits; error.required is current",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Conflict": {
        "description": "Either the live charge changed (price_changed) or the Idempotency-Key was already used with a different request body (idempotency_key_reuse)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ValidationError": {
        "description": "Settings are invalid or a reference field is unsupported",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "GenerationFailed": {
        "description": "Job could not be started",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "StatusFailed": {
        "description": "Job status could not be checked",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Models or rate limiting are temporarily unavailable",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Timeout": {
        "description": "Start timed out. The error echoes idempotencyKey when supplied; retry with the same value.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }
}
