{"openapi":"3.1.0","info":{"title":"API Reference","version":"1.0.0"},"paths":{"/v2/text-to-video":{"post":{"operationId":"asyncVideoGeneration_submitTextToVideo","summary":"Generate video from text","description":"Generate a video from a text prompt. Describe the scene, camera motion, and mood — the model returns a video with matching audio.\n\nResponds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/text-to-video/{id}` until the status is `completed`, then download from `result.video_url`.\n\nBilled per second of generated video. See [Pricing](/pricing).\n","tags":["asyncVideoGeneration"],"responses":{"202":{"description":"Job submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobCreatedResponse"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextToVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v2/image-to-video":{"post":{"operationId":"asyncVideoGeneration_submitImageToVideo","summary":"Generate video from image","description":"Animate a still image with realistic motion, depth, and audio. Provide a reference image plus a prompt describing the desired motion. The output preserves the visual identity of the source image.\n\nResponds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/image-to-video/{id}` until the status is `completed`, then download from `result.video_url`.\n\nBilled per second of generated video. See [Pricing](/pricing).\n","tags":["asyncVideoGeneration"],"responses":{"202":{"description":"Job submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobCreatedResponse"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageToVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v2/audio-to-video":{"post":{"operationId":"asyncVideoGeneration_submitAudioToVideo","summary":"Generate video from audio","description":"Generate a video driven by an audio track. Supply dialogue, music, or ambient sound and the model produces visuals synchronized to the audio. Optionally condition on a reference image for visual direction, a last frame for interpolation, and camera motion. Output frame rate defaults to 24 fps; its length is set by the audio.\n\nResponds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/audio-to-video/{id}` until the status is `completed`, then download from `result.video_url`.\n\nBilled per second of input audio. See [Pricing](/pricing).\n","tags":["asyncVideoGeneration"],"responses":{"202":{"description":"Job submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobCreatedResponse"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioToVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v2/retake":{"post":{"operationId":"asyncVideoGeneration_submitRetake","summary":"Retake video section","description":"Re-generate a section of an existing video by replacing either its audio, its video, or both. Select a time range and mode to iterate on part of a generation without starting over — the rest of the video is preserved.\n\nResponds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/retake/{id}` until the status is `completed`, then download from `result.video_url`.\n\nBilled per second of the input video. See [Pricing](/pricing).\n","tags":["asyncVideoGeneration"],"responses":{"202":{"description":"Job submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobCreatedResponse"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v2/extend":{"post":{"operationId":"asyncVideoGeneration_submitExtend","summary":"Extend video duration","description":"Extend a video by generating additional frames at the beginning or end. The model uses context frames from the input to produce a seamless continuation with consistent motion and audio.\n\nResponds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/extend/{id}` until the status is `completed`, then download from `result.video_url`.\n\nBilled per second, based on the extended portion plus the context frames used from the input video. See [Pricing](/pricing).\n","tags":["asyncVideoGeneration"],"responses":{"202":{"description":"Job submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobCreatedResponse"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v2/video-to-video-hdr":{"post":{"operationId":"asyncVideoGeneration_submitVideoToVideoHdr","summary":"Upscale video to HDR","description":"Convert an SDR video into HDR. On completion, the result contains `exr_frames_url` — a ZIP of per-frame EXR images suitable for color grading or HDR rendering pipelines.\n\nResponds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/video-to-video-hdr/{id}` until the status is `completed`.\n\nBilled per second of input video, by input resolution tier. See [Pricing](/pricing).\n","tags":["asyncVideoGeneration"],"responses":{"202":{"description":"Job submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobCreatedResponse"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoToVideoHdrRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v2/video-to-video-reframe":{"post":{"operationId":"asyncVideoGeneration_submitVideoToVideoReframe","summary":"Reframe a video to a new resolution","description":"Reframe a video to a new resolution. The model fills in the missing areas with generated content that matches the original. On completion, the result contains `video_url`, the source video reframed to the requested resolution.\n\nResponds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/video-to-video-reframe/{id}` until the status is `completed`.\n\nBilled per second of input video, by output resolution. See [Pricing](/pricing).\n","tags":["asyncVideoGeneration"],"responses":{"202":{"description":"Job submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobCreatedResponse"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoToVideoReframeRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v2/{endpoint}/{id}":{"get":{"operationId":"asyncVideoGeneration_getJobStatus","summary":"Get job status","description":"Poll the status of an async generation job. Status transitions through `pending` → `processing` → `completed` or `failed`. When completed, the `result` object contains output URLs (see each endpoint's documentation for the available keys).\n\nWe recommend waiting at least 5 seconds between polls. Choose a slightly different delay each time, for example between 5 and 6 seconds, to spread out requests when polling multiple jobs. Stop when the status reaches `completed` or `failed`.\n\nJob status is available for up to 24 hours after the job reaches a terminal state, and can be removed sooner. Once a job is removed, this endpoint returns `404`. Output URLs expire independently of job status; download or re-host outputs as soon as the job completes. See [retention](/async-jobs#retention).\n","tags":["asyncVideoGeneration"],"parameters":[{"name":"id","in":"path","description":"Job ID returned from the submit endpoint.","required":true,"schema":{"type":"string"}},{"name":"endpoint","in":"path","description":"The endpoint type used when submitting the job (e.g., `text-to-video`, `image-to-video`, `audio-to-video`, `retake`, `extend`, `video-to-video-hdr`, `video-to-video-reframe`).","required":true,"schema":{"$ref":"#/components/schemas/V2EndpointIdGetParametersEndpoint"}}],"responses":{"200":{"description":"Current job status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2JobStatusResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/text-to-video":{"post":{"operationId":"videoGeneration_textToVideo","summary":"Generate video from text","description":"> **Deprecated:** After October 26, 2026 at 11:59 PM UTC, requests to this endpoint will no longer work. See [Migrate from V1 to V2](/migrate-v1-to-v2).\n\nGenerate a video from a text prompt. Describe the scene, camera motion, and mood — the model returns a video with matching audio.\n\nReturns the generated video directly in the response. For an asynchronous version that returns a job to poll, see [v2/text-to-video](/api-documentation/api-reference/async-video-generation/submit-text-to-video).\n\nBilled per second of generated video. See [Pricing](/pricing).\n","tags":["videoGeneration"],"responses":{"200":{"description":"Video generated successfully","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Request timeout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"deprecated":true,"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextToVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v1/image-to-video":{"post":{"operationId":"videoGeneration_imageToVideo","summary":"Generate video from image","description":"> **Deprecated:** After October 26, 2026 at 11:59 PM UTC, requests to this endpoint will no longer work. See [Migrate from V1 to V2](/migrate-v1-to-v2).\n\nAnimate a still image with realistic motion, depth, and audio. Provide a reference image plus a prompt describing the desired motion. The output preserves the visual identity of the source image.\n\nReturns the generated video directly in the response. For an asynchronous version that returns a job to poll, see [v2/image-to-video](/api-documentation/api-reference/async-video-generation/submit-image-to-video).\n\nBilled per second of generated video. See [Pricing](/pricing).\n","tags":["videoGeneration"],"responses":{"200":{"description":"Video generated successfully","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Request timeout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"deprecated":true,"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageToVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v1/audio-to-video":{"post":{"operationId":"videoGeneration_audioToVideo","summary":"Generate video from audio","description":"> **Deprecated:** After October 26, 2026 at 11:59 PM UTC, requests to this endpoint will no longer work. See [Migrate from V1 to V2](/migrate-v1-to-v2).\n\nGenerate a video driven by an audio track. Supply dialogue, music, or ambient sound and the model produces visuals synchronized to the audio. Optionally condition on a reference image for visual direction, a last frame for interpolation, and camera motion. Output frame rate defaults to 24 fps; its length is set by the audio.\n\nReturns the generated video directly in the response. For an asynchronous version that returns a job to poll, see [v2/audio-to-video](/api-documentation/api-reference/async-video-generation/submit-audio-to-video).\n\nBilled per second of input audio. See [Pricing](/pricing).\n","tags":["videoGeneration"],"responses":{"200":{"description":"Video generated successfully","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Request timeout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"deprecated":true,"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioToVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v1/retake":{"post":{"operationId":"videoGeneration_retake","summary":"Retake video section","description":"> **Deprecated:** After October 26, 2026 at 11:59 PM UTC, requests to this endpoint will no longer work. See [Migrate from V1 to V2](/migrate-v1-to-v2).\n\nRe-generate a section of an existing video by replacing either its audio, its video, or both. Iterate on part of a generation without starting over — the rest of the video is preserved. The edited section is defined by the `start_time` and `duration` parameters.\n\nReturns the generated video directly in the response. For an asynchronous version that returns a job to poll, see [v2/retake](/api-documentation/api-reference/async-video-generation/submit-retake).\n\nBilled per second of the input video. See [Pricing](/pricing).\n","tags":["videoGeneration"],"responses":{"200":{"description":"Video edited successfully","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Request timeout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"deprecated":true,"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v1/extend":{"post":{"operationId":"videoGeneration_extend","summary":"Extend video duration","description":"> **Deprecated:** After October 26, 2026 at 11:59 PM UTC, requests to this endpoint will no longer work. See [Migrate from V1 to V2](/migrate-v1-to-v2).\n\nExtend a video by generating additional frames at the beginning or end. The model uses context frames from the input to produce a seamless continuation with consistent motion and audio.\n> Audio is generated for the extended portion if the input video has audio.\n\nReturns the generated video directly in the response. For an asynchronous version that returns a job to poll, see [v2/extend](/api-documentation/api-reference/async-video-generation/submit-extend).\n\nBilled per second, based on the extended portion plus the context frames used from the input video. See [Pricing](/pricing).\n","tags":["videoGeneration"],"responses":{"200":{"description":"Video extended successfully","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request is invalid or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Content rejected by safety filters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Concurrency or queue limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Request timeout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"deprecated":true,"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendVideoRequest"}}}},"security":[{"bearerAuth":[]}]}},"/v1/upload":{"post":{"operationId":"upload_createUpload","summary":"Upload file","description":"Generate a signed URL for uploading media files to use as input for video generation.\n\nReturns a pre-signed URL that can be used to upload files directly to cloud storage.\nThe URL creates a new object and cannot overwrite an existing object. Include every header returned in `required_headers` in the upload request.\nUse the returned `storage_uri` in subsequent video generation requests (e.g., `image_uri` or `video_uri` parameters).\nThe URL expires after 1 hour.\n","tags":["upload"],"responses":{"200":{"description":"Upload URL generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResponse"}}}},"401":{"description":"Authentication failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"An unexpected error occurred","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]}]}}},"tags":[{"name":"asyncVideoGeneration"},{"name":"videoGeneration"},{"name":"upload"}],"servers":[{"url":"https://api.ltx.io","description":"Production server"}],"components":{"schemas":{"TextToVideoRequestModel":{"type":"string","enum":["ltx-2-3-fast","ltx-2-3-pro","ltx-2-5-fast","ltx-2-5-pro"],"description":"Model to use for generation. See [Supported Models](/models) for details.","title":"TextToVideoRequestModel"},"TextToVideoRequestCameraMotion":{"type":"string","enum":["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"],"description":"Apply camera motion effects to the generated video.","title":"TextToVideoRequestCameraMotion"},"TextToVideoRequest":{"type":"object","properties":{"prompt":{"type":"string","maxLength":5000,"description":"Text prompt describing the desired video content"},"model":{"$ref":"#/components/schemas/TextToVideoRequestModel","description":"Model to use for generation. See [Supported Models](/models) for details."},"duration":{"type":["integer","null"],"description":"Video duration in seconds. See [Supported Models](/models) for available durations per model. Pass `null` to let `ltx-2-5-fast` or `ltx-2-5-pro` choose the length from your prompt — see [Automatic duration](/models/ltx-2-5#automatic-duration)."},"fps":{"type":"integer","default":24,"description":"Frame rate in frames per second. See [Supported Models](/models) for available FPS per model and resolution."},"resolution":{"type":"string","description":"Output video resolution. See [Supported Models](/models) for available resolutions per model."},"generate_audio":{"type":"boolean","default":true,"description":"Generate audio for the video. When true, the generated video will include AI-generated audio matching the scene. When false, only silent video is generated."},"camera_motion":{"$ref":"#/components/schemas/TextToVideoRequestCameraMotion","description":"Apply camera motion effects to the generated video."}},"required":["prompt","model","duration","resolution"],"title":"TextToVideoRequest"},"V2JobCreatedResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique job identifier. Use this to poll for status."},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of when the job was created."}},"required":["id","created_at"],"description":"Response returned when a V2 async job is successfully submitted.","title":"V2JobCreatedResponse"},"ErrorType":{"type":"string","enum":["error"],"description":"Response type indicator","title":"ErrorType"},"ErrorError":{"type":"object","properties":{"type":{"type":"string","description":"Error type for programmatic handling"},"message":{"type":"string","description":"Human-readable error description"}},"required":["type","message"],"title":"ErrorError"},"Error":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ErrorType","description":"Response type indicator"},"error":{"$ref":"#/components/schemas/ErrorError"}},"required":["type","error"],"title":"Error"},"ImageToVideoRequestModel":{"type":"string","enum":["ltx-2-3-fast","ltx-2-3-pro","ltx-2-5-fast","ltx-2-5-pro"],"description":"Model to use for generation. See [Supported Models](/models) for details.","title":"ImageToVideoRequestModel"},"ImageToVideoRequestCameraMotion":{"type":"string","enum":["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"],"description":"Apply camera motion effects to the generated video.","title":"ImageToVideoRequestCameraMotion"},"ImageToVideoRequest":{"type":"object","properties":{"image_uri":{"type":"string","description":"Image to be used as the first frame of the video. See [Input Formats](/input-formats#image-input) for supported formats and size limits."},"prompt":{"type":"string","maxLength":5000,"description":"Text description of how the image should be animated, can relate to the details in the image"},"model":{"$ref":"#/components/schemas/ImageToVideoRequestModel","description":"Model to use for generation. See [Supported Models](/models) for details."},"duration":{"type":["integer","null"],"description":"Video duration in seconds. See [Supported Models](/models) for available durations per model. Pass `null` to let `ltx-2-5-fast` or `ltx-2-5-pro` choose the length from your prompt — see [Automatic duration](/models/ltx-2-5#automatic-duration). Cannot be combined with `last_frame_uri`."},"fps":{"type":"integer","default":24,"description":"Frame rate in frames per second. See [Supported Models](/models) for available FPS per model and resolution."},"resolution":{"type":"string","description":"Output video resolution. See [Supported Models](/models) for available resolutions per model."},"generate_audio":{"type":"boolean","default":true,"description":"Generate audio for the video. When true, the generated video will include AI-generated audio matching the scene. When false, only silent video is generated."},"last_frame_uri":{"type":"string","description":"Image to be used as the last frame of the video. When provided, the video will interpolate between the first frame (image_uri) and this last frame. See [Input Formats](/input-formats#image-input) for supported formats and size limits."},"camera_motion":{"$ref":"#/components/schemas/ImageToVideoRequestCameraMotion","description":"Apply camera motion effects to the generated video."}},"required":["image_uri","prompt","model","duration","resolution"],"title":"ImageToVideoRequest"},"AudioToVideoRequestModel":{"type":"string","enum":["ltx-2-3-pro","ltx-2-5-fast","ltx-2-5-pro"],"default":"ltx-2-3-pro","description":"Model to use for video generation.","title":"AudioToVideoRequestModel"},"AudioToVideoRequestCameraMotion":{"type":"string","enum":["dolly_in","dolly_out","dolly_left","dolly_right","jib_up","jib_down","static","focus_shift"],"description":"Apply camera motion effects to the generated video.","title":"AudioToVideoRequestCameraMotion"},"AudioToVideoRequest":{"type":"object","properties":{"audio_uri":{"type":"string","description":"Audio file to be used as the soundtrack for the video. The audio sets the length of the\ngenerated video, so its duration must not exceed the maximum the selected model supports\nat the chosen resolution.\n\n| Model | Resolution | Maximum audio duration |\n| --- | --- | --- |\n| `ltx-2-5-fast` | 720p, 1080p | 20 seconds |\n| `ltx-2-5-fast` | 1440p, 4K | 10 seconds |\n| `ltx-2-5-pro` | 720p, 1080p | 10 seconds |\n| `ltx-2-5-pro` | 1440p, 4K | 10 seconds |\n| `ltx-2-3-pro` | 720p, 1080p | 20 seconds |\n| `ltx-2-3-pro` | 1440p, 4K | 10 seconds |\n\nSee [Input Formats](/input-formats#audio-input) for supported formats and size limits.\n"},"image_uri":{"type":"string","description":"Input image to be used as the first frame of the video. Required if prompt is not provided. See [Input Formats](/input-formats#image-input) for supported formats and size limits."},"prompt":{"type":"string","maxLength":5000,"description":"Text description of how the video should be generated. Required if image_uri is not provided. Can be empty string when image_uri is provided. If image_uri is provided, this describes how the image should be animated. If no image_uri is provided, this describes the video content."},"resolution":{"type":"string","description":"The resolution of the generated video in WIDTHxHEIGHT format. When omitted, the resolution is automatically determined based on the input image orientation — portrait images produce 1080x1920 video, landscape images produce 1920x1080 video. If no image is provided, defaults to 1920x1080.\n\nSupported resolutions depend on the model — see [Supported Models](/models) for the full matrix. `ltx-2-5-fast`, `ltx-2-5-pro`, and `ltx-2-3-pro` support 720p through 4K.\n"},"model":{"$ref":"#/components/schemas/AudioToVideoRequestModel","description":"Model to use for video generation."},"fps":{"type":"integer","default":24,"description":"Frame rate in frames per second. See [Supported Models](/models) for available FPS per model and resolution."},"last_frame_uri":{"type":"string","description":"Image to be used as the last frame of the video. Requires `image_uri`. When provided, the video interpolates between the first and last frame. See [Input Formats](/input-formats#image-input) for supported formats and size limits."},"camera_motion":{"$ref":"#/components/schemas/AudioToVideoRequestCameraMotion","description":"Apply camera motion effects to the generated video."}},"required":["audio_uri"],"title":"AudioToVideoRequest"},"EditVideoRequestMode":{"type":"string","enum":["replace_audio","replace_video","replace_audio_and_video"],"default":"replace_audio_and_video","description":"Can be any of the following:\n- `replace_audio` - Replace only the audio track\n- `replace_video` - Replace only the video track\n- `replace_audio_and_video` - Replace both audio and video tracks\n\nThe default value is `replace_audio_and_video` if not specified.\n","title":"EditVideoRequestMode"},"EditVideoRequestResolution":{"type":"string","enum":["1920x1080","1080x1920"],"description":"The resolution of the generated video in WIDTHxHEIGHT format. When omitted, the resolution is automatically determined based on the input video orientation — portrait videos produce 1080x1920 output, landscape videos produce 1920x1080 output.\n","title":"EditVideoRequestResolution"},"EditVideoRequestModel":{"type":"string","enum":["ltx-2-3-pro"],"default":"ltx-2-3-pro","description":"Model to use for video generation.","title":"EditVideoRequestModel"},"EditVideoRequest":{"type":"object","properties":{"video_uri":{"type":"string","description":"Input video for editing. See [Input Formats](/input-formats#video-input) for supported formats and codecs.\n\n- Maximum resolution: 3840x2160 (4K)\n- Minimum frame count: 73 (around 3 seconds at 24fps)\n"},"prompt":{"type":"string","maxLength":5000,"description":"Describing what needs to happen in the generated video in a section\ndefined by `start_time` and `duration`.\n"},"start_time":{"type":"number","format":"double","minimum":0,"description":"Start time in seconds, defines the section to be edited in the input video.\n\nThe section defined by `start_time` and `duration` should be within the duration of the input video.\nIf the section extends beyond the duration of the video, it will be clamped to the video duration.\n"},"duration":{"type":"number","format":"double","minimum":2,"description":"Duration in seconds, defines the duration of the section to be edited\nin the input video. Must be at least 2 seconds.\n\nThe section defined by `start_time` and `duration` should be within the duration of the input video.\nIf the section extends beyond the duration of the video, it will be clamped to the video duration.\n"},"mode":{"$ref":"#/components/schemas/EditVideoRequestMode","description":"Can be any of the following:\n- `replace_audio` - Replace only the audio track\n- `replace_video` - Replace only the video track\n- `replace_audio_and_video` - Replace both audio and video tracks\n\nThe default value is `replace_audio_and_video` if not specified.\n"},"resolution":{"$ref":"#/components/schemas/EditVideoRequestResolution","description":"The resolution of the generated video in WIDTHxHEIGHT format. When omitted, the resolution is automatically determined based on the input video orientation — portrait videos produce 1080x1920 output, landscape videos produce 1920x1080 output.\n"},"model":{"$ref":"#/components/schemas/EditVideoRequestModel","description":"Model to use for video generation."}},"required":["video_uri","start_time","duration"],"title":"EditVideoRequest"},"ExtendVideoRequestMode":{"type":"string","enum":["start","end"],"default":"end","description":"Where to extend the video:\n- `end` (default): Extends the video at the end.\n- `start`: Extends the video at the beginning.\n","title":"ExtendVideoRequestMode"},"ExtendVideoRequestModel":{"type":"string","enum":["ltx-2-3-pro"],"default":"ltx-2-3-pro","description":"Model to use for video generation.","title":"ExtendVideoRequestModel"},"ExtendVideoRequest":{"type":"object","properties":{"video_uri":{"type":"string","description":"Input video for extending. See [Input Formats](/input-formats#video-input) for supported formats and codecs.\n\n- Supported aspect ratios: 16:9 and 9:16\n- Maximum resolution: 3840x2160 (4K)\n- Minimum frame count: 73 (around 3 seconds at 24fps)\n\nThe output video preserves the input video's resolution.\n"},"prompt":{"type":"string","maxLength":5000,"description":"Description of what should happen in the extended portion of the video.\n"},"duration":{"type":"number","format":"double","minimum":2,"maximum":20,"description":"Duration in seconds to extend the video. Minimum 2 seconds, maximum 20 seconds (480 frames at 24fps).\n"},"mode":{"$ref":"#/components/schemas/ExtendVideoRequestMode","description":"Where to extend the video:\n- `end` (default): Extends the video at the end.\n- `start`: Extends the video at the beginning.\n"},"model":{"$ref":"#/components/schemas/ExtendVideoRequestModel","description":"Model to use for video generation."},"context":{"type":"number","format":"double","minimum":1,"maximum":20,"description":"**Advanced parameter:** Number of seconds from the input video to use as context for the extension (maximum 20 seconds).\n\nThe model uses context frames from the input video to generate a more coherent extension.\nThe sum of `context` + `duration` (converted to frames using the input video's FPS) cannot exceed 505 frames (~21 seconds at 24fps). For higher-FPS inputs, the maximum total duration in seconds will be proportionally lower; for lower-FPS inputs, it will be proportionally higher.\n\nIf not provided, defaults to maximize available context within the 505 frame limit while respecting the 20-second cap.\n"}},"required":["video_uri","duration"],"title":"ExtendVideoRequest"},"VideoToVideoHdrRequest":{"type":"object","properties":{"video_uri":{"type":"string","description":"SDR source video in HTTPS URL or base64 data URI format. See [Input Formats](/input-formats#video-input) for supported formats and codecs.\n\nMax frames (and max duration at 24 fps) depend on the input resolution tier — inputs are snapped to the smallest tier that fits by pixel count:\n\n| Input resolution tier | Max frames | Max duration (at 24 fps) |\n| --- | --- | --- |\n| Up to 1080p (≤ 1920×1080) | 181 | ~7 seconds |\n| Up to 1440p (≤ 2560×1440) | 101 | ~4 seconds |\n| Up to 4K (≤ 3840×2160) | 41 | ~2 seconds |\n\nThe output video preserves the input video's resolution.\n"}},"required":["video_uri"],"title":"VideoToVideoHdrRequest"},"VideoToVideoReframeRequestResolution":{"type":"string","enum":["720x720","1080x1080","720x900","1080x1350","900x720","1350x1080","720x1280","1080x1920","1280x720","1920x1080"],"description":"Target output resolution. The source video is extended to fill this frame. Pass one of the values below; each maps to an aspect ratio:\n\n| Aspect ratio | Resolutions |\n| --- | --- |\n| 1:1 (square) | `720x720`, `1080x1080` |\n| 4:5 (portrait) | `720x900`, `1080x1350` |\n| 5:4 (landscape) | `900x720`, `1350x1080` |\n| 9:16 (portrait) | `720x1280`, `1080x1920` |\n| 16:9 (landscape) | `1280x720`, `1920x1080` |\n","title":"VideoToVideoReframeRequestResolution"},"VideoToVideoReframeRequestPlacementOneOf0Anchor":{"type":"string","enum":["center","top","bottom","left","right","top_left","top_right","bottom_left","bottom_right"],"title":"VideoToVideoReframeRequestPlacementOneOf0Anchor"},"VideoToVideoReframeRequestPlacement0":{"type":"object","properties":{"anchor":{"$ref":"#/components/schemas/VideoToVideoReframeRequestPlacementOneOf0Anchor"}},"required":["anchor"],"description":"Fits the video inside the frame and aligns it, e.g. `{ \"anchor\": \"top\" }`:\n\n| `anchor` | Where the video lands |\n| --- | --- |\n| `center` | Middle (same as omitting `placement`) |\n| `top` | Top edge |\n| `bottom` | Bottom edge |\n| `left` | Left edge |\n| `right` | Right edge |\n| `top_left` | Top-left corner |\n| `top_right` | Top-right corner |\n| `bottom_left` | Bottom-left corner |\n| `bottom_right` | Bottom-right corner |\n\nThe fitted video always fills the frame along one axis, so an anchor only moves it along the other:\n\n<pre>\nlandscape source → portrait frame\nfills the width, so it moves up or down\n\n top       center     bottom\n┌────┐     ┌────┐     ┌────┐\n│████│     │    │     │    │\n│    │     │████│     │    │\n│    │     │    │     │████│\n└────┘     └────┘     └────┘\n\nportrait source → landscape frame\nfills the height, so it moves left or right\n\n   left        center       right\n┌──┬──────┐   ┌───┬──┬───┐   ┌──────┬──┐\n│██│      │   │   │██│   │   │      │██│\n│██│      │   │   │██│   │   │      │██│\n└──┴──────┘   └───┴──┴───┘   └──────┴──┘\n\n████ = your video, the rest is generated\n</pre>\n\nA corner anchor such as `bottom_left` works whatever the video's orientation, and a video with the frame's aspect ratio fills it, so every anchor gives the same result.\n\nAnchors other than `center` can't enlarge the video more than 2× its original pixel size, so they may be rejected for a small video; use `center` (or omit `placement`) to fit it at any size, or use a rectangle.\n","title":"VideoToVideoReframeRequestPlacement0"},"VideoToVideoReframeRequestPlacement1":{"type":"object","properties":{"x":{"type":"number","format":"double","minimum":0,"exclusiveMaximum":1,"description":"Left edge of the placed video, as a fraction of the output width."},"y":{"type":"number","format":"double","minimum":0,"exclusiveMaximum":1,"description":"Top edge of the placed video, as a fraction of the output height."},"width":{"type":"number","format":"double","maximum":1,"exclusiveMinimum":0,"description":"Width of the placed video, as a fraction of the output width."},"height":{"type":"number","format":"double","maximum":1,"exclusiveMinimum":0,"description":"Height of the placed video, as a fraction of the output height."}},"required":["x","y"],"description":"- `x`, `y`: the video's top-left corner, as fractions of the output frame (`0, 0` is its top-left).\n- Send `width`, `height`, or both, as fractions of the frame. With one, the other follows the video's aspect ratio; with both, they must match it to within a pixel.\n- The video must stay inside the frame, be at least one pixel on each side, and can't be enlarged more than 2×.\n\nFor a 1920x1080 video in a `1080x1920` frame:\n\n| `placement` | Result |\n| --- | --- |\n| `{ \"x\": 0, \"y\": 0.35, \"width\": 1 }` | Full width, top edge 35% down; height follows the video |\n| `{ \"x\": 0.1, \"y\": 0.1, \"height\": 0.25 }` | A quarter of the frame tall; width follows the video |\n","title":"VideoToVideoReframeRequestPlacement1"},"VideoToVideoReframeRequestPlacement":{"oneOf":[{"$ref":"#/components/schemas/VideoToVideoReframeRequestPlacement0"},{"$ref":"#/components/schemas/VideoToVideoReframeRequestPlacement1"}],"description":"Where the source video lands on the output frame: an **Anchor** such as `{ \"anchor\": \"top\" }` to fit and align it, or a **Rectangle** such as `{ \"x\": 0, \"y\": 0.35, \"width\": 1 }` to set its position and size exactly (see both below). The whole source is always kept and never stretched; the model generates the rest of the frame. Omit to center it at the largest size that fits.\n","title":"VideoToVideoReframeRequestPlacement"},"VideoToVideoReframeRequest":{"type":"object","properties":{"video_uri":{"type":"string","description":"Input video in HTTPS URL or base64 data URI format. See [Input Formats](/input-formats#video-input) for supported formats and codecs.\n\nMax 60 seconds and 1800 frames (e.g. 60s at 30fps, or 30s at 60fps).\n"},"resolution":{"$ref":"#/components/schemas/VideoToVideoReframeRequestResolution","description":"Target output resolution. The source video is extended to fill this frame. Pass one of the values below; each maps to an aspect ratio:\n\n| Aspect ratio | Resolutions |\n| --- | --- |\n| 1:1 (square) | `720x720`, `1080x1080` |\n| 4:5 (portrait) | `720x900`, `1080x1350` |\n| 5:4 (landscape) | `900x720`, `1350x1080` |\n| 9:16 (portrait) | `720x1280`, `1080x1920` |\n| 16:9 (landscape) | `1280x720`, `1920x1080` |\n"},"placement":{"$ref":"#/components/schemas/VideoToVideoReframeRequestPlacement","description":"Where the source video lands on the output frame: an **Anchor** such as `{ \"anchor\": \"top\" }` to fit and align it, or a **Rectangle** such as `{ \"x\": 0, \"y\": 0.35, \"width\": 1 }` to set its position and size exactly (see both below). The whole source is always kept and never stretched; the model generates the rest of the frame. Omit to center it at the largest size that fits.\n"}},"required":["video_uri","resolution"],"title":"VideoToVideoReframeRequest"},"V2EndpointIdGetParametersEndpoint":{"type":"string","enum":["text-to-video","image-to-video","audio-to-video","retake","extend","video-to-video-hdr","video-to-video-reframe"],"title":"V2EndpointIdGetParametersEndpoint"},"V2JobPendingStatus":{"type":"string","enum":["pending"],"title":"V2JobPendingStatus"},"V2JobProcessingStatus":{"type":"string","enum":["processing"],"title":"V2JobProcessingStatus"},"V2JobCompletedStatus":{"type":"string","enum":["completed"],"title":"V2JobCompletedStatus"},"V2JobResult":{"type":"object","additionalProperties":{"type":"string","format":"uri"},"description":"Result object for a completed job. Contains output URLs — the available keys depend on the endpoint. Output URLs expire independently of job-status retention. Download or re-host outputs as soon as the job completes. See [retention](/async-jobs#retention).\n","title":"V2JobResult"},"V2JobFailedStatus":{"type":"string","enum":["failed"],"title":"V2JobFailedStatus"},"V2JobError":{"type":"object","properties":{"type":{"type":"string","description":"Error type for programmatic handling. Same values as HTTP error types."},"message":{"type":"string","description":"Human-readable error description."}},"required":["type","message"],"description":"Error details for a failed job. Uses the same error types as HTTP error responses\n(`api_error`, `content_filtered_error`, `insufficient_funds_error`, etc.).\n","title":"V2JobError"},"V2JobStatusResponse":{"oneOf":[{"type":"object","properties":{"status":{"$ref":"#/components/schemas/V2JobPendingStatus"},"id":{"type":"string"},"created_at":{"type":"string","format":"date-time"}},"required":["status","id","created_at"],"description":"pending variant"},{"type":"object","properties":{"status":{"$ref":"#/components/schemas/V2JobProcessingStatus"},"id":{"type":"string"},"created_at":{"type":"string","format":"date-time"}},"required":["status","id","created_at"],"description":"processing variant"},{"type":"object","properties":{"status":{"$ref":"#/components/schemas/V2JobCompletedStatus"},"id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of when the job completed."},"result":{"$ref":"#/components/schemas/V2JobResult"}},"required":["status","id","created_at","completed_at","result"],"description":"completed variant"},{"type":"object","properties":{"status":{"$ref":"#/components/schemas/V2JobFailedStatus"},"id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of when the job failed."},"error":{"$ref":"#/components/schemas/V2JobError"}},"required":["status","id","created_at","completed_at","error"],"description":"failed variant"}],"discriminator":{"propertyName":"status"},"description":"Job status response. The shape depends on the current status:\n- `pending` — job is queued\n- `processing` — generation in progress\n- `completed` — done, `result` contains output URLs (keys depend on the endpoint)\n- `failed` — error occurred, `error` contains details\n","title":"V2JobStatusResponse"},"UploadResponse":{"type":"object","properties":{"upload_url":{"type":"string","description":"Pre-signed URL for uploading the file. Use PUT request to upload your file to this URL.\nThe URL includes all necessary authentication and expires after 1 hour.\n"},"storage_uri":{"type":"string","description":"Storage URI that can be used to reference the uploaded file in subsequent API requests.\nUse this value in image_uri or video_uri parameters.\nThe uploaded file will be available for 24 hours.\n"},"expires_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp indicating when the signed URL expires (1 hour from creation).\n"},"required_headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Headers that must be included unchanged in the upload request to cloud storage.\nThese headers enforce the file size limit and prevent overwriting an existing object.\n"}},"required":["upload_url","storage_uri","expires_at","required_headers"],"title":"UploadResponse"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key authentication"}}}}