{
  "openapi": "3.0.0",
  "info": {
    "title": "TeamoRouter Videos API",
    "version": "2.0.0",
    "description": "OpenAI-style video job lifecycle with model-specific generation controls."
  },
  "servers": [
    {
      "url": "https://api.teamorouter.com/v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "QueueVideoRequest": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "description": "The model to use for video generation.",
            "example": "seedance-2-0-text-to-video-basic"
          },
          "consents": {
            "type": "object",
            "properties": {
              "seedance": {
                "type": "object",
                "properties": {
                  "confirmed_terms_and_privacy": {
                    "type": "boolean",
                    "enum": [
                      true
                    ],
                    "description": "Confirms acceptance of the current provider policy text returned in the needs_consent response.",
                    "example": true
                  },
                  "confirmed_legal_right": {
                    "type": "boolean",
                    "enum": [
                      true
                    ],
                    "description": "Confirms the API user has the legal right to use the submitted media.",
                    "example": true
                  },
                  "confirmed_screening_acknowledged": {
                    "type": "boolean",
                    "enum": [
                      true
                    ],
                    "description": "Acknowledges that submitted media may be screened before processing.",
                    "example": true
                  }
                },
                "required": [
                  "confirmed_terms_and_privacy",
                  "confirmed_legal_right",
                  "confirmed_screening_acknowledged"
                ]
              }
            },
            "description": "Optional provider-specific consent attestations. Required only for models that return a needs_consent response."
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 20000,
            "description": "The prompt to use for video generation. Required for most models; optional for H3 Max Multi-Angle. The maximum length varies by model (default 2500 characters, up to 20000 for some models).",
            "example": "Commerce being conducted in the city of Venice, Italy."
          },
          "negative_prompt": {
            "type": "string",
            "maxLength": 20000,
            "description": "Optional negative prompt. The maximum length varies by model (default 2500 characters, up to 20000 for some models).",
            "example": "low resolution, error, worst quality, low quality, defects"
          },
          "duration": {
            "type": "string",
            "description": "The duration of the video to generate. Available options vary by model. For Seedance 2.5 reference-to-video edit jobs, `-1` or `auto` matches output length to the source clip (requires reference_video_urls on queue, or reference_video_total_duration on quote; source must be 4–30s).",
            "example": "10s"
          },
          "aspect_ratio": {
            "type": "string",
            "enum": [
              "1:1",
              "2:1",
              "2:3",
              "3:2",
              "3:4",
              "4:3",
              "4:5",
              "5:4",
              "9:16",
              "9:21",
              "16:9",
              "21:9",
              "adaptive",
              "auto"
            ],
            "description": "The aspect ratio of the video. Available options vary by model. Some models do not support aspect_ratio. For Seedance 2.x reference-to-video edit/extend, `adaptive` or `auto` matches output aspect ratio to the source clip (requires reference_video_urls on queue, or reference_video_total_duration on quote).",
            "example": "16:9"
          },
          "omni_reference_task_type": {
            "type": "string",
            "enum": [
              "auto",
              "reference",
              "edit",
              "extend"
            ],
            "description": "Optional Seedance 2.5 reference-to-video task-type hint forwarded to BytePlus (`auto` | `reference` | `edit` | `extend`). Aliases `editing`→`edit` and `extension`→`extend` are accepted on the queue API. Pre-guides classification to reduce async TaskTypeConstraint errors. The prompt must still match the chosen type. When omitted, Venice infers from the prompt if reference_video_urls are present. Not supported on other models.",
            "example": "edit"
          },
          "resolution": {
            "type": "string",
            "enum": [
              "256p",
              "360p",
              "480p",
              "540p",
              "580p",
              "720p",
              "1080p",
              "1440p",
              "2160p",
              "2k",
              "4k",
              "1x",
              "2x",
              "4x",
              "2K",
              "480P",
              "768P",
              "1080P",
              "true_1080p"
            ],
            "description": "The resolution of the video. Available options vary by model. Some models do not support resolution. Use upscale_factor for upscale models.",
            "example": "720p"
          },
          "upscale_factor": {
            "type": "integer",
            "description": "For upscale models only. 1 = quality enhancement, 2 = double resolution (default), 4 = quadruple.",
            "enum": [
              1,
              2,
              4
            ],
            "default": 2,
            "example": 2
          },
          "enhancement_model": {
            "type": "string",
            "description": "For enhancement models only. The provider-side enhancement model. Available values are listed per model in GET /models constraints.topaz.models.",
            "example": "Proteus"
          },
          "target_fps": {
            "type": "integer",
            "description": "For enhancement models only. Target FPS for frame interpolation (16-120). Omit to keep the source frame rate.",
            "example": 60
          },
          "softness": {
            "type": "number",
            "minimum": 1,
            "maximum": 5,
            "description": "For enhancement models only. Softness level (1-5, sharpest to softest).",
            "example": 3
          },
          "creativity": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "For enhancement models only. How much new detail the model invents (0.0-1.0).",
            "example": 0.5
          },
          "realism": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "For enhancement models only. Bias generated detail toward photorealism (0.0-1.0).",
            "example": 0.5
          },
          "sharp": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "For enhancement models only. Output sharpness (0.0 softens, 0.5 neutral, 1.0 strong).",
            "example": 0.5
          },
          "compression": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "For enhancement models only. Compression artifact removal level (0.0-1.0).",
            "example": 0.5
          },
          "noise": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "For enhancement models only. Noise reduction level (0.0-1.0).",
            "example": 0.5
          },
          "halo": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "For enhancement models only. Halo reduction level (0.0-1.0).",
            "example": 0.5
          },
          "grain": {
            "type": "number",
            "minimum": 0,
            "maximum": 0.1,
            "description": "For enhancement models only. Film grain amount (0.0-0.1).",
            "example": 0
          },
          "recover_detail": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "For enhancement models only. Recover original detail level (0.0-1.0).",
            "example": 0.5
          },
          "h264_output": {
            "type": "boolean",
            "description": "For enhancement models only. Output H.264 instead of the default H.265.",
            "example": false
          },
          "output_format": {
            "type": "string",
            "enum": [
              "mp4",
              "prores"
            ],
            "description": "For enhancement models only (SDR-to-HDR). Output container: mp4 (10-bit H265 HDR10) or prores (10-bit ProRes).",
            "example": "mp4"
          },
          "slowdown_factor": {
            "type": "integer",
            "description": "For enhancement models only (frame interpolation). Slow-motion factor: 2 makes the output twice as long at the target FPS, up to 8x.",
            "enum": [
              1,
              2,
              4,
              8
            ],
            "example": 1
          },
          "audio": {
            "type": "boolean",
            "default": true,
            "description": "For models which support audio generation and configuration. Defaults to true.",
            "example": true
          },
          "camera_trajectory": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "time": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                },
                "azimuth": {
                  "type": "number"
                },
                "elevation": {
                  "type": "number",
                  "minimum": -90,
                  "maximum": 90
                },
                "distance": {
                  "type": "number",
                  "minimum": 0,
                  "exclusiveMinimum": true
                }
              },
              "required": [
                "time",
                "azimuth",
                "elevation",
                "distance"
              ],
              "additionalProperties": false
            },
            "minItems": 2,
            "maxItems": 12,
            "description": "For H3 Max Multi-Angle only. 2–12 camera keyframes with strictly increasing normalized time (0–1), azimuth in degrees (signed; total absolute travel at most 32 turns), elevation in degrees (−90 to 90), and positive distance relative to the initial camera (1 = unchanged). Omit to leave the camera path to the model. Requires image_url; aspect ratio follows that image.",
            "example": [
              {
                "time": 0,
                "azimuth": 0,
                "elevation": 0,
                "distance": 1
              },
              {
                "time": 1,
                "azimuth": 45,
                "elevation": 10,
                "distance": 1
              }
            ]
          },
          "image_url": {
            "type": "string",
            "description": "For image-to-video models, the reference image. Must be a URL (http/https) or a data URL (data:image/...).",
            "example": "data:image/png;base64,iVBORw0K..."
          },
          "end_image_url": {
            "type": "string",
            "description": "For models that support end images or transitions, the end frame image. Must be a URL or data URL.",
            "example": "data:image/png;base64,iVBORw0K..."
          },
          "image_strength": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "How strongly the input image guides an image-to-video generation, from 0 to 1. Supported on models that declare image strength. Omitted values use the provider default (1).",
            "example": 1
          },
          "audio_url": {
            "type": "string",
            "description": "For models that support audio input, background music. Must be a URL or data URL. Supported: WAV, MP3. Max: 30s, 15MB.",
            "example": "data:audio/mpeg;base64,SUQzBAA..."
          },
          "video_url": {
            "type": "string",
            "description": "For models that support video input (video-to-video, upscale). Must be a URL or data URL. Supported: MP4, MOV, WebM.",
            "example": "data:video/mp4;base64,AAAAFGZ0eXA..."
          },
          "reference_image_urls": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 30,
            "description": "For models with reference image support, up to 30 images for character/style consistency. Each must be a URL or data URL.",
            "example": [
              "data:image/png;base64,iVBORw0K..."
            ]
          },
          "reference_video_urls": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 10,
            "description": "For models with reference video support (e.g. Seedance 2.0 R2V), up to 10 reference video URLs (`role: \"reference_video\"`) used to inherit subject motion, camera movement, and overall style. Per-clip 2–15 s, .mp4 or .mov, ≤50 MB; aggregate duration ≤15 s. Each must be a URL or data URL.",
            "example": [
              "https://example.com/reference-clip.mp4"
            ]
          },
          "reference_audio_urls": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 10,
            "description": "For models with reference audio support (e.g. Seedance 2.0 R2V), up to 10 reference audio URLs (`role: \"reference_audio\"`) used as donors for vocal timbre, narration, or sound effects. Per-clip 2–15 s, .wav or .mp3; aggregate duration ≤15 s. Must be paired with at least one reference image or reference video — audio-only Reference workflows are rejected at validation. Each must be a URL or data URL.",
            "example": [
              "data:audio/mpeg;base64,SUQzBAAAAAA..."
            ]
          },
          "reference_document_urls": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 1,
            "description": "For models with document / webpage Omni-Reference (Wan 3.0), up to 1 URL. Document files and public webpage URLs are fetched by Venice and forwarded as `type: \"file\"` (≤100 MB). Each must be a URL or data URL.",
            "example": [
              "https://example.com/brief.pdf"
            ]
          },
          "elements": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "frontal_image_url": {
                  "type": "string"
                },
                "reference_image_urls": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 3
                },
                "video_url": {
                  "type": "string"
                }
              }
            },
            "maxItems": 4,
            "description": "For models with advanced element support (e.g., Kling O3 R2V). Up to 4 elements defining characters/objects. Reference in prompt as @Element1, @Element2, etc.",
            "example": [
              {
                "frontal_image_url": "data:image/png;base64,iVBORw0K...",
                "reference_image_urls": [
                  "data:image/png;base64,iVBORw0K..."
                ]
              }
            ]
          },
          "scene_image_urls": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 4,
            "description": "For models with advanced element support. Up to 4 scene reference images. Reference in prompt as @Image1, @Image2, etc.",
            "example": [
              "data:image/png;base64,iVBORw0K..."
            ]
          },
          "keyframes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "image_url": {
                  "type": "string"
                },
                "frame_index": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "required": [
                "image_url",
                "frame_index"
              ]
            },
            "maxItems": 10,
            "description": "For keyframe-driven models. Up to 10 keyframe images pinned to frame positions in the generated 24 fps video. Each frame_index must be unique and no greater than duration × 24.",
            "example": [
              {
                "image_url": "data:image/png;base64,iVBORw0K...",
                "frame_index": 0
              },
              {
                "image_url": "data:image/png;base64,iVBORw0K...",
                "frame_index": 120
              }
            ]
          },
          "conversation_id": {
            "type": "string",
            "description": "Optional TeamoRouter conversation ID, created with POST /video/conversations. Never forwarded upstream."
          },
          "parent_queue_id": {
            "type": "string",
            "description": "Optional previous task ID in this conversation; records a new version. Never forwarded upstream."
          },
          "quote_id": {
            "type": "string",
            "description": "Quote ID from POST /videos/quote, valid for 10 minutes; bound to account, generation settings and channel. Reuse it for an idempotent retry."
          },
          "seconds": {
            "type": "string",
            "description": "Duration in seconds; model-dependent.",
            "example": "4"
          },
          "size": {
            "type": "string",
            "description": "Supported WIDTHxHEIGHT.",
            "example": "1280x720"
          },
          "input_reference": {
            "type": "object",
            "required": [
              "image_url"
            ],
            "additionalProperties": false,
            "properties": {
              "image_url": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "model",
          "prompt"
        ],
        "description": "Video creation parameters. Native generation controls are optional extensions."
      },
      "Video": {
        "type": "object",
        "required": [
          "id",
          "object",
          "model",
          "status",
          "progress",
          "created_at",
          "seconds",
          "size"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "enum": [
              "video"
            ]
          },
          "model": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "in_progress",
              "completed",
              "failed"
            ]
          },
          "progress": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "created_at": {
            "type": "integer",
            "description": "Unix seconds"
          },
          "completed_at": {
            "type": "integer",
            "nullable": true
          },
          "expires_at": {
            "type": "integer",
            "nullable": true
          },
          "prompt": {
            "type": "string",
            "nullable": true
          },
          "seconds": {
            "type": "string"
          },
          "size": {
            "type": "string"
          },
          "error": {
            "type": "object",
            "nullable": true,
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          },
          "remixed_from_video_id": {
            "type": "string",
            "nullable": true
          }
        }
      }
    }
  },
  "paths": {
    "/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "summary": "List Models",
        "description": "Returns the video models you can call, with the parameter values each one accepts.",
        "operationId": "modelsList",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "video",
                "all"
              ],
              "default": "video",
              "description": "Model family to list. `video` and `all` both return video models."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "description": "Always `list`."
                    },
                    "type": {
                      "type": "string",
                      "description": "The family that was listed."
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "503": {
            "description": "The model catalogue could not be loaded. Retry shortly.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/videos": {
      "post": {
        "operationId": "createVideo",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Video"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueueVideoRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "model",
                  "prompt"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "The model to use for video generation.",
                    "example": "seedance-2-0-text-to-video-basic"
                  },
                  "consents": {
                    "type": "object",
                    "properties": {
                      "seedance": {
                        "type": "object",
                        "properties": {
                          "confirmed_terms_and_privacy": {
                            "type": "boolean",
                            "enum": [
                              true
                            ],
                            "description": "Confirms acceptance of the current provider policy text returned in the needs_consent response.",
                            "example": true
                          },
                          "confirmed_legal_right": {
                            "type": "boolean",
                            "enum": [
                              true
                            ],
                            "description": "Confirms the API user has the legal right to use the submitted media.",
                            "example": true
                          },
                          "confirmed_screening_acknowledged": {
                            "type": "boolean",
                            "enum": [
                              true
                            ],
                            "description": "Acknowledges that submitted media may be screened before processing.",
                            "example": true
                          }
                        },
                        "required": [
                          "confirmed_terms_and_privacy",
                          "confirmed_legal_right",
                          "confirmed_screening_acknowledged"
                        ]
                      }
                    },
                    "description": "Optional provider-specific consent attestations. Required only for models that return a needs_consent response."
                  },
                  "prompt": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20000,
                    "description": "The prompt to use for video generation. Required for most models; optional for H3 Max Multi-Angle. The maximum length varies by model (default 2500 characters, up to 20000 for some models).",
                    "example": "Commerce being conducted in the city of Venice, Italy."
                  },
                  "negative_prompt": {
                    "type": "string",
                    "maxLength": 20000,
                    "description": "Optional negative prompt. The maximum length varies by model (default 2500 characters, up to 20000 for some models).",
                    "example": "low resolution, error, worst quality, low quality, defects"
                  },
                  "duration": {
                    "type": "string",
                    "description": "The duration of the video to generate. Available options vary by model. For Seedance 2.5 reference-to-video edit jobs, `-1` or `auto` matches output length to the source clip (requires reference_video_urls on queue, or reference_video_total_duration on quote; source must be 4–30s).",
                    "example": "10s"
                  },
                  "aspect_ratio": {
                    "type": "string",
                    "enum": [
                      "1:1",
                      "2:1",
                      "2:3",
                      "3:2",
                      "3:4",
                      "4:3",
                      "4:5",
                      "5:4",
                      "9:16",
                      "9:21",
                      "16:9",
                      "21:9",
                      "adaptive",
                      "auto"
                    ],
                    "description": "The aspect ratio of the video. Available options vary by model. Some models do not support aspect_ratio. For Seedance 2.x reference-to-video edit/extend, `adaptive` or `auto` matches output aspect ratio to the source clip (requires reference_video_urls on queue, or reference_video_total_duration on quote).",
                    "example": "16:9"
                  },
                  "omni_reference_task_type": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "reference",
                      "edit",
                      "extend"
                    ],
                    "description": "Optional Seedance 2.5 reference-to-video task-type hint forwarded to BytePlus (`auto` | `reference` | `edit` | `extend`). Aliases `editing`→`edit` and `extension`→`extend` are accepted on the queue API. Pre-guides classification to reduce async TaskTypeConstraint errors. The prompt must still match the chosen type. When omitted, Venice infers from the prompt if reference_video_urls are present. Not supported on other models.",
                    "example": "edit"
                  },
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "256p",
                      "360p",
                      "480p",
                      "540p",
                      "580p",
                      "720p",
                      "1080p",
                      "1440p",
                      "2160p",
                      "2k",
                      "4k",
                      "1x",
                      "2x",
                      "4x",
                      "2K",
                      "480P",
                      "768P",
                      "1080P",
                      "true_1080p"
                    ],
                    "description": "The resolution of the video. Available options vary by model. Some models do not support resolution. Use upscale_factor for upscale models.",
                    "example": "720p"
                  },
                  "upscale_factor": {
                    "type": "integer",
                    "description": "For upscale models only. 1 = quality enhancement, 2 = double resolution (default), 4 = quadruple.",
                    "enum": [
                      1,
                      2,
                      4
                    ],
                    "default": 2,
                    "example": 2
                  },
                  "enhancement_model": {
                    "type": "string",
                    "description": "For enhancement models only. The provider-side enhancement model. Available values are listed per model in GET /models constraints.topaz.models.",
                    "example": "Proteus"
                  },
                  "target_fps": {
                    "type": "integer",
                    "description": "For enhancement models only. Target FPS for frame interpolation (16-120). Omit to keep the source frame rate.",
                    "example": 60
                  },
                  "softness": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 5,
                    "description": "For enhancement models only. Softness level (1-5, sharpest to softest).",
                    "example": 3
                  },
                  "creativity": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "For enhancement models only. How much new detail the model invents (0.0-1.0).",
                    "example": 0.5
                  },
                  "realism": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "For enhancement models only. Bias generated detail toward photorealism (0.0-1.0).",
                    "example": 0.5
                  },
                  "sharp": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "For enhancement models only. Output sharpness (0.0 softens, 0.5 neutral, 1.0 strong).",
                    "example": 0.5
                  },
                  "compression": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "For enhancement models only. Compression artifact removal level (0.0-1.0).",
                    "example": 0.5
                  },
                  "noise": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "For enhancement models only. Noise reduction level (0.0-1.0).",
                    "example": 0.5
                  },
                  "halo": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "For enhancement models only. Halo reduction level (0.0-1.0).",
                    "example": 0.5
                  },
                  "grain": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 0.1,
                    "description": "For enhancement models only. Film grain amount (0.0-0.1).",
                    "example": 0
                  },
                  "recover_detail": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "For enhancement models only. Recover original detail level (0.0-1.0).",
                    "example": 0.5
                  },
                  "h264_output": {
                    "type": "boolean",
                    "description": "For enhancement models only. Output H.264 instead of the default H.265.",
                    "example": false
                  },
                  "output_format": {
                    "type": "string",
                    "enum": [
                      "mp4",
                      "prores"
                    ],
                    "description": "For enhancement models only (SDR-to-HDR). Output container: mp4 (10-bit H265 HDR10) or prores (10-bit ProRes).",
                    "example": "mp4"
                  },
                  "slowdown_factor": {
                    "type": "integer",
                    "description": "For enhancement models only (frame interpolation). Slow-motion factor: 2 makes the output twice as long at the target FPS, up to 8x.",
                    "enum": [
                      1,
                      2,
                      4,
                      8
                    ],
                    "example": 1
                  },
                  "audio": {
                    "type": "boolean",
                    "default": true,
                    "description": "For models which support audio generation and configuration. Defaults to true.",
                    "example": true
                  },
                  "camera_trajectory": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "time": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1
                        },
                        "azimuth": {
                          "type": "number"
                        },
                        "elevation": {
                          "type": "number",
                          "minimum": -90,
                          "maximum": 90
                        },
                        "distance": {
                          "type": "number",
                          "minimum": 0,
                          "exclusiveMinimum": true
                        }
                      },
                      "required": [
                        "time",
                        "azimuth",
                        "elevation",
                        "distance"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 2,
                    "maxItems": 12,
                    "description": "For H3 Max Multi-Angle only. 2–12 camera keyframes with strictly increasing normalized time (0–1), azimuth in degrees (signed; total absolute travel at most 32 turns), elevation in degrees (−90 to 90), and positive distance relative to the initial camera (1 = unchanged). Omit to leave the camera path to the model. Requires image_url; aspect ratio follows that image.",
                    "example": [
                      {
                        "time": 0,
                        "azimuth": 0,
                        "elevation": 0,
                        "distance": 1
                      },
                      {
                        "time": 1,
                        "azimuth": 45,
                        "elevation": 10,
                        "distance": 1
                      }
                    ]
                  },
                  "image_url": {
                    "type": "string",
                    "description": "For image-to-video models, the reference image. Must be a URL (http/https) or a data URL (data:image/...).",
                    "example": "data:image/png;base64,iVBORw0K..."
                  },
                  "end_image_url": {
                    "type": "string",
                    "description": "For models that support end images or transitions, the end frame image. Must be a URL or data URL.",
                    "example": "data:image/png;base64,iVBORw0K..."
                  },
                  "image_strength": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "How strongly the input image guides an image-to-video generation, from 0 to 1. Supported on models that declare image strength. Omitted values use the provider default (1).",
                    "example": 1
                  },
                  "audio_url": {
                    "type": "string",
                    "description": "For models that support audio input, background music. Must be a URL or data URL. Supported: WAV, MP3. Max: 30s, 15MB.",
                    "example": "data:audio/mpeg;base64,SUQzBAA..."
                  },
                  "video_url": {
                    "type": "string",
                    "description": "For models that support video input (video-to-video, upscale). Must be a URL or data URL. Supported: MP4, MOV, WebM.",
                    "example": "data:video/mp4;base64,AAAAFGZ0eXA..."
                  },
                  "reference_image_urls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 30,
                    "description": "For models with reference image support, up to 30 images for character/style consistency. Each must be a URL or data URL.",
                    "example": [
                      "data:image/png;base64,iVBORw0K..."
                    ]
                  },
                  "reference_video_urls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 10,
                    "description": "For models with reference video support (e.g. Seedance 2.0 R2V), up to 10 reference video URLs (`role: \"reference_video\"`) used to inherit subject motion, camera movement, and overall style. Per-clip 2–15 s, .mp4 or .mov, ≤50 MB; aggregate duration ≤15 s. Each must be a URL or data URL.",
                    "example": [
                      "https://example.com/reference-clip.mp4"
                    ]
                  },
                  "reference_audio_urls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 10,
                    "description": "For models with reference audio support (e.g. Seedance 2.0 R2V), up to 10 reference audio URLs (`role: \"reference_audio\"`) used as donors for vocal timbre, narration, or sound effects. Per-clip 2–15 s, .wav or .mp3; aggregate duration ≤15 s. Must be paired with at least one reference image or reference video — audio-only Reference workflows are rejected at validation. Each must be a URL or data URL.",
                    "example": [
                      "data:audio/mpeg;base64,SUQzBAAAAAA..."
                    ]
                  },
                  "reference_document_urls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 1,
                    "description": "For models with document / webpage Omni-Reference (Wan 3.0), up to 1 URL. Document files and public webpage URLs are fetched by Venice and forwarded as `type: \"file\"` (≤100 MB). Each must be a URL or data URL.",
                    "example": [
                      "https://example.com/brief.pdf"
                    ]
                  },
                  "elements": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "frontal_image_url": {
                          "type": "string"
                        },
                        "reference_image_urls": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "maxItems": 3
                        },
                        "video_url": {
                          "type": "string"
                        }
                      }
                    },
                    "maxItems": 4,
                    "description": "For models with advanced element support (e.g., Kling O3 R2V). Up to 4 elements defining characters/objects. Reference in prompt as @Element1, @Element2, etc.",
                    "example": [
                      {
                        "frontal_image_url": "data:image/png;base64,iVBORw0K...",
                        "reference_image_urls": [
                          "data:image/png;base64,iVBORw0K..."
                        ]
                      }
                    ]
                  },
                  "scene_image_urls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 4,
                    "description": "For models with advanced element support. Up to 4 scene reference images. Reference in prompt as @Image1, @Image2, etc.",
                    "example": [
                      "data:image/png;base64,iVBORw0K..."
                    ]
                  },
                  "keyframes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "image_url": {
                          "type": "string"
                        },
                        "frame_index": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "image_url",
                        "frame_index"
                      ]
                    },
                    "maxItems": 10,
                    "description": "For keyframe-driven models. Up to 10 keyframe images pinned to frame positions in the generated 24 fps video. Each frame_index must be unique and no greater than duration × 24.",
                    "example": [
                      {
                        "image_url": "data:image/png;base64,iVBORw0K...",
                        "frame_index": 0
                      },
                      {
                        "image_url": "data:image/png;base64,iVBORw0K...",
                        "frame_index": 120
                      }
                    ]
                  },
                  "conversation_id": {
                    "type": "string",
                    "description": "Optional TeamoRouter conversation ID, created with POST /video/conversations. Never forwarded upstream."
                  },
                  "parent_queue_id": {
                    "type": "string",
                    "description": "Optional previous task ID in this conversation; records a new version. Never forwarded upstream."
                  },
                  "quote_id": {
                    "type": "string",
                    "description": "Quote ID from POST /videos/quote, valid for 10 minutes; bound to account, generation settings and channel. Reuse it for an idempotent retry."
                  },
                  "seconds": {
                    "type": "string",
                    "description": "Duration in seconds; model-dependent.",
                    "example": "4"
                  },
                  "size": {
                    "type": "string",
                    "description": "Supported WIDTHxHEIGHT.",
                    "example": "1280x720"
                  },
                  "input_reference": {
                    "type": "string",
                    "format": "binary",
                    "description": "PNG, JPEG or WebP image"
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listVideos",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "enum": [
                        "list"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Video"
                      }
                    },
                    "first_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "last_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "has_more": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ]
      }
    },
    "/videos/{video_id}": {
      "parameters": [
        {
          "name": "video_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "retrieveVideo",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Video"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteVideo",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "object": {
                      "type": "string",
                      "enum": [
                        "video.deleted"
                      ]
                    },
                    "deleted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/videos/{video_id}/content": {
      "parameters": [
        {
          "name": "video_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "downloadVideo",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Video bytes",
            "content": {
              "video/mp4": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "409": {
            "description": "Video not ready"
          },
          "404": {
            "description": "Video or media not found"
          }
        },
        "parameters": [
          {
            "name": "variant",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "video"
              ]
            }
          }
        ]
      }
    },
    "/videos/quote": {
      "post": {
        "tags": [
          "Video"
        ],
        "summary": "Quote Video Generation",
        "description": "Returns a quote and quote_id for the supplied generation settings. The quote_id is valid for 10 minutes. Use the same settings and media when submitting to /videos.",
        "operationId": "videoQuote",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "Model ID."
                  },
                  "duration": {
                    "type": "string",
                    "enum": [
                      "1s",
                      "2s",
                      "3s",
                      "4s",
                      "5s",
                      "6s",
                      "7s",
                      "8s",
                      "9s",
                      "10s",
                      "11s",
                      "12s",
                      "13s",
                      "14s",
                      "15s",
                      "16s",
                      "17s",
                      "18s",
                      "19s",
                      "20s",
                      "21s",
                      "22s",
                      "23s",
                      "24s",
                      "25s",
                      "26s",
                      "27s",
                      "28s",
                      "29s",
                      "30s",
                      "-1",
                      "1 gen",
                      "auto",
                      "Auto"
                    ],
                    "description": "Clip length, as for `/videos`."
                  },
                  "aspect_ratio": {
                    "type": "string",
                    "enum": [
                      "1:1",
                      "2:1",
                      "2:3",
                      "3:2",
                      "3:4",
                      "4:3",
                      "4:5",
                      "5:4",
                      "9:16",
                      "9:21",
                      "16:9",
                      "21:9",
                      "adaptive",
                      "auto"
                    ],
                    "description": "Frame shape, if the model supports it."
                  },
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "256p",
                      "360p",
                      "480p",
                      "540p",
                      "580p",
                      "720p",
                      "1080p",
                      "1440p",
                      "2160p",
                      "2k",
                      "4k",
                      "1x",
                      "2x",
                      "4x",
                      "2K",
                      "480P",
                      "768P",
                      "1080P",
                      "true_1080p"
                    ],
                    "description": "Output resolution, if the model supports it."
                  },
                  "audio": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether audio will be generated."
                  },
                  "upscale_factor": {
                    "type": "integer",
                    "enum": [
                      1,
                      2,
                      4
                    ],
                    "description": "Upscale models only."
                  },
                  "enhancement_model": {
                    "type": "string",
                    "description": "Enhancement models only."
                  },
                  "target_fps": {
                    "type": "integer",
                    "description": "Enhancement models only."
                  },
                  "slowdown_factor": {
                    "type": "integer",
                    "enum": [
                      1,
                      2,
                      4,
                      8
                    ],
                    "description": "Frame-interpolation models only."
                  },
                  "video_url": {
                    "type": "string",
                    "description": "Source video URL."
                  },
                  "reference_video_total_duration": {
                    "type": "number",
                    "description": "Total reference video duration in seconds for edit / extend requests."
                  },
                  "image_url": {
                    "type": "string",
                    "description": "For image-to-video models, the reference image. Must be a URL (http/https) or a data URL (data:image/...).",
                    "example": "data:image/png;base64,iVBORw0K..."
                  },
                  "end_image_url": {
                    "type": "string",
                    "description": "For models that support end images or transitions, the end frame image. Must be a URL or data URL.",
                    "example": "data:image/png;base64,iVBORw0K..."
                  },
                  "reference_image_urls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 30,
                    "description": "For models with reference image support, up to 30 images for character/style consistency. Each must be a URL or data URL.",
                    "example": [
                      "data:image/png;base64,iVBORw0K..."
                    ]
                  },
                  "reference_video_urls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 10,
                    "description": "For models with reference video support (e.g. Seedance 2.0 R2V), up to 10 reference video URLs (`role: \"reference_video\"`) used to inherit subject motion, camera movement, and overall style. Per-clip 2–15 s, .mp4 or .mov, ≤50 MB; aggregate duration ≤15 s. Each must be a URL or data URL.",
                    "example": [
                      "https://example.com/reference-clip.mp4"
                    ]
                  }
                },
                "required": [
                  "model",
                  "duration"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quote response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "quote": {
                      "type": "number",
                      "description": "Quote value in USD."
                    },
                    "quote_id": {
                      "type": "string",
                      "description": "Quote ID from POST /videos/quote, valid for 10 minutes; bound to account, generation settings and channel. Reuse it for an idempotent retry."
                    },
                    "estimated": {
                      "type": "boolean",
                      "description": "Whether the returned value is an estimate."
                    },
                    "currency": {
                      "type": "string",
                      "enum": [
                        "USD"
                      ]
                    }
                  },
                  "required": [
                    "quote"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid model or settings for this model.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/videos/{id}/request": {
      "get": {
        "summary": "Restore generation parameters and retained inputs",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Scoped to the authenticated user and organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found in this account."
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/videos/conversations": {
      "get": {
        "summary": "List saved conversations, counts and pagination",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Scoped to the authenticated user and organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found in this account."
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "summary": "Create or import a conversation idempotently",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Scoped to the authenticated user and organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found in this account."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 40
                  },
                  "queue_ids": {
                    "type": "array",
                    "maxItems": 200,
                    "items": {
                      "type": "string"
                    }
                  },
                  "parents": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "id",
                  "title"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/videos/conversations/{id}": {
      "patch": {
        "summary": "Rename a saved conversation",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Scoped to the authenticated user and organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found in this account."
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 40
                  }
                },
                "required": [
                  "title"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete conversation archive while keeping videos",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Scoped to the authenticated user and organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found in this account."
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/videos/catalog": {
      "get": {
        "tags": [
          "Models"
        ],
        "operationId": "publicVideoCatalogue",
        "summary": "Public video catalogue",
        "security": [],
        "responses": {
          "200": {
            "description": "Public model metadata."
          }
        }
      }
    }
  }
}
