Create an asynchronous video job from text or reference media. Poll the stable OTRouter video ID until it reaches a terminal state, then read the generated bytes from the content endpoint.
GEThttps://router.omnitools.ai/catalog/modelsList logical models, capabilities and public tariffs · public
POSThttps://router.omnitools.ai/v1/videosCreate a video job
GEThttps://router.omnitools.ai/v1/videos/{video_id}Read status and progress
GEThttps://router.omnitools.ai/v1/videos/{video_id}/contentRead completed video content
Choose a model
GET /catalog/models without a Bearer key, then select an entry whose modality is video and whose protocols include videos. Create requests with its logical model ID and advertised capabilities.
Select publicPricing.rates by the required resolution. Charge = max(minimumAmount, duration × secondRate); a zero secondRate means minimumAmount is the fixed per-request charge. This public tariff is determined before internal routing.
Authentication
Authenticate every /v1/videos request with the same Team API key. Keep the key in a trusted server environment, including status and content requests.
Authorization: Bearer $OTRouter_API_KEY
POST requests require Content-Type: application/json. GET requests do not have a request body.
Create a video
Submit one model-specific generation request. The response is a queued video object; creation does not wait for rendering to finish.
Always send resolution and duration so OTRouter can select capabilities and determine the public charge before routing. Their supported values, aspect ratios and media capabilities come from the selected video model.
Parameter
Requirement
Description
model
Required
Stable logical video model ID from GET /catalog/models.
prompt
Required
Text description of the requested video. Length limits are model-specific.
mode
Required
Use references for text or reference-media generation.
aspect_ratio
Optional
Requested frame ratio. Allowed values depend on the model.
resolution
Required
Requested output resolution. Must match a value in capabilities.resolutions and publicPricing.rates.
duration
Required
Requested video length in seconds. Must satisfy the selected model's capabilities.durations.
references
Model-specific
Reference-media object accepted only with mode: references.
client_task_id
Required
Client idempotency key: 1–128 letters, numbers, underscores, hyphens or periods.
Reference media
Use mode: references for text-only generation or attach publicly reachable media URLs allowed by the selected model. Direct file uploads, base64 values and data URLs are not accepted.
Each singular/plural pair is mutually exclusive. Plural fields require at least two entries. capabilities.references limits each media type, audioVideos limits audio and video combined, and total limits all assets combined.
Asynchronous lifecycle
Creation returns immediately. Poll the returned video ID at a reasonable interval until status becomes completed or failed.
Status
Phase
Description
queued
Active
Accepted and waiting to begin generation.
in_progress
Active
Generation is running; progress may increase from 0 through 100.
completed
Terminal
Generation succeeded. Read the bytes from the content endpoint.
failed
Terminal
Generation failed. metadata.fail_reason contains the public failure reason.
unknown
Active
Submission was attempted but OTRouter cannot confirm its upstream task identity. The same request returns the same OTRouter video ID without another submission; an operator reconciles the upstream task ID before settlement.
Retrieve a video
GET the video resource to read its status, progress and terminal metadata. The video belongs to the Team identified by the API key.
The same public ID and model are preserved throughout the job. completed_at and metadata appear when the job reaches a terminal state.
Parameter
Present
Description
id
Always
OTRouter video ID used by the status and content endpoints.
object
Always
The constant value video.
model
Always
Stable public model ID submitted at creation.
status
Always
Current asynchronous lifecycle state.
progress
Always
Best-known completion percentage from 0 through 100.
created_at
Always
Creation time as Unix seconds.
completed_at
Terminal
Completion or failure time as Unix seconds.
metadata.url
completed
Relative OTRouter content path for the generated video.
metadata.fail_reason
failed
Public reason the generation did not complete.
Read video content
After status is completed, GET the content endpoint with the same Bearer credential. The response streams binary video data and supports Range requests; do not parse it as JSON.
Omit Range to stream the complete file, or send Range: bytes={start}-{end} for a partial or resumed read. Before completion, the endpoint returns 404 video_not_ready. A well-formed but unsatisfiable range returns an empty 416 with only safe Content-Range and Accept-Ranges headers.
Idempotency
client_task_id identifies one logical generation request inside the authenticated Team. Choose it before the first attempt and keep it stable across uncertain transport retries.
First attempt
Create a new client_task_id from your own order or job identity.
Safe replay
The same key and normalized request reuse the original OTRouter video ID and Request without starting or charging a second logical job.
Conflicting replay
The same key with different parameters returns 409 idempotency_conflict.
Submission unknown
A 503 submission_unknown includes the stable OTRouter video ID in x-video-id. Replaying the same request returns that ID and never submits upstream again; an operator reconciles the upstream task ID before settlement.
Accepted job
Keep the returned video ID and use GET for all status and content reads.
New generation
Use a new client_task_id whenever you intend to create a distinct video.
Errors
Errors use the standard OTRouter JSON envelope, except the media content endpoint's empty RFC 416 response. Invalid modes, conflicting media fields and model-specific constraint failures are rejected before generation begins.
The JSON shape, mode, media combination or model-specific value is invalid.
401
invalid_api_key
The Bearer API key is missing, invalid, expired or deleted.
402
insufficient_credits
The Team cannot fund a new generation.
404
model_not_found
The requested public video model is unavailable.
404
task_not_found
The video ID is invalid, unavailable to this Team or does not exist.
404
video_not_ready
Content was requested before the video completed.
409
idempotency_conflict
client_task_id was already used with a different normalized request.
413
payload_too_large
The create request body exceeds 256 KiB.
416
invalid_range
Range is invalid or contains more than one byte range.
429
api_key_spend_limit_exceeded
The API key reached a rolling spend limit.
503
submission_unknown
The generation may have been accepted but OTRouter cannot identify its upstream task. x-video-id remains stable, the request is not submitted again, and settlement waits for operator reconciliation.
For submission_unknown, keep x-video-id for status checks and operator reconciliation. Keep x-request-id and error.requestId when contacting support.