Videos
Video generation is always asynchronous: submission returns 202 immediately, the job runs in the background (up to 30 minutes), and you collect the result by polling, webhook, or console.
Two submission routes — same engine, different shapes:
| Route | Shape | Use it when |
|---|---|---|
POST /v1/videos | OpenAI Video API (multipart, seconds+size) | You use the OpenAI SDK (client.videos.create) or need image-to-video |
POST /v1/videos/generations | Meshive JSON (resolution+duration+fps) | Plain JSON integrations, text-to-video |
POST /v1/videos
Section titled “POST /v1/videos”Multipart form, OpenAI Video (Sora) style. Text-to-video or — by attaching input_reference — image-to-video, automatically matched against the model’s input modalities.
| Field | Type | Default | Notes |
|---|---|---|---|
prompt | string | required | |
model | string | required | |
seconds | float | required | Clip duration |
size | string | required | WIDTHxHEIGHT, validated against the model’s supported resolutions |
input_reference | file | — | Reference image → image-to-video |
fps | int | 24 | |
seed / negative_prompt / steps | — | — | Meshive extensions |
webhook_url | string | — | Meshive extension |
storage_credential_id | int | — | Meshive extension |
Header: Idempotency-Key (semantics).
Response 202 — an OpenAI Video object:
{ "id": "req_4d5e6f7a8b9c0d1e", "object": "video", "status": "queued", "model": "<model-id>", "progress": 0, "created_at": 1780000000, "size": "720x1280", "seconds": "5"}video = client.videos.create( model="<model-id>", prompt="A red fox running through fresh snow, cinematic", seconds=5, size="720x1280", # input_reference=open("ref.png", "rb"), # ← image-to-video)print(video.id, video.status)curl https://<your-deployment>.inference.meshive.ai/v1/videos \ -H "Authorization: Bearer $MESHIVE_API_KEY" \ -F prompt="A red fox running through fresh snow, cinematic" \ -F model="<model-id>" \ -F seconds=5 \ -F size="720x1280"POST /v1/videos/generations
Section titled “POST /v1/videos/generations”JSON body, text-to-video. (Image-to-video models must use POST /v1/videos.)
| Field | Type | Default |
|---|---|---|
model | string | required |
prompt | string | required |
resolution | string | "720x1280" |
duration | float (seconds) | 5.0 |
fps | int | 24 |
seed / negative_prompt / steps | — | — |
webhook_url / storage_credential_id | — | — |
Response 202 — Meshive request shape (track via /v1/requests):
{ "id": "req_...", "object": "inference.request", "status": "queued", "modality": "video", "estimated_seconds": 30 }Validation — duration, fps, resolution
Section titled “Validation — duration, fps, resolution”- Resolution/size must be in the model’s supported list — otherwise
422 resolution_not_supportedwith the valid options sorted in the message. - Models with a pinned native spec (most official video models are trained at one fixed frames/fps pair):
duration/secondsmust land within 0.5s of the native duration andfpsmust match exactly — otherwise422 duration_mismatch/422 fps_mismatch, with the supported values in the message. - Models without a pinned spec (typical for custom registrations): your
duration × fpsis honored, with the frame count snapped to the nearest value the architecture supports (4n+1, minimum 5). On the JSON route, resolutions are also snapped down to multiples of 32 —718x1278becomes704x1248. Quality at off-native settings is the model’s behavior, not the platform’s.
GET /v1/videos/{id}
Section titled “GET /v1/videos/{id}”Returns the Video object with current status:
status | Meaning |
|---|---|
queued | Waiting for a worker |
in_progress | Running — progress is a 0–99 estimate |
completed | Done — fetch /content |
failed | Inspect the attached error: {code, message} — also covers requests that timed out (30 min) or expired |
canceled | Canceled while queued |
GET /v1/videos/{id}/content
Section titled “GET /v1/videos/{id}/content”302 redirect to a presigned download URL (valid ~1 hour; results in your own bucket are signed against it). Follow redirects in your HTTP client:
curl -L -o out.mp4 \ -H "Authorization: Bearer $MESHIVE_API_KEY" \ https://<your-deployment>.inference.meshive.ai/v1/videos/req_.../contentNot finished yet → 409 video_not_ready with the current status.
DELETE /v1/videos/{id}
Section titled “DELETE /v1/videos/{id}”Cancels a queued video — 204. Consistent with the cancellation policy:
running→409 video_not_cancellable(the GPU is already committed).- Already terminal (
completed/failed/canceled) →204no-op (idempotent).