Videos API

Create, poll, and download asynchronous video tasks

Video generation uses an async task model: create → poll status → download result. The gateway provides two create paths; query and download endpoints are shared.

1. Overview

Async flow

Create task → Poll GET /v1/videos/{task_id} → Download GET /v1/videos/{task_id}/content
  1. Call POST /v1/videos or POST /v1/guidai/videos to submit a task and receive a task_id
  2. Poll GET /v1/videos/{task_id} until status is completed or failed
  3. After completion, download via GET /v1/videos/{task_id}/content; optionally use ?variant=thumbnail for the cover image

Comparing the two create paths

ItemPOST /v1/videosPOST /v1/guidai/videos
Use caseGeneral video create; fields follow upstream video model conventionsMultimodal video generation via mode + assets[]
Content-Typeapplication/json or multipart/form-dataapplication/json
Core paramsmodel, prompt, size, seconds, input_referencemodel, mode, prompt, assets[], resolution, duration_sec, etc.
Reference imageJSON URL / Base64 data URI / multipart file uploadPass URLs in assets[] by role
Generation modeNo mode field; determined by model and request fieldsExplicit mode: t2v, i2v, first_frame, first_last_frame, ref_image, video_extend, video_edit
Query & downloadGET /v1/videos/{task_id}, GET /v1/videos/{task_id}/contentSame (shared)

Prerequisite: model must be a model from the Models API whose supported_endpoint_types includes openai-video.


2. Endpoints

MethodPathDescription
POST/v1/videosCreate video task (general)
GET/v1/videos/{task_id}Query task status
GET/v1/videos/{task_id}/contentDownload video or thumbnail
POST/v1/guidai/videosCreate video task (multimodal / Guid AI)

3. Task status

ItemDescription
Task ID formatPublic ID shaped like task_xxxxxxxx
Status flowqueuedin_progresscompleted / failed
statusDescription
queuedQueued
in_progressGenerating
completedCompleted; ready to download
failedFailed; see the error field

4. POST /v1/videos

Create a video task.

Auth: Bearer Token

Content-Type: application/json or multipart/form-data

Request body (JSON)

{
  "model": "sora-2",
  "prompt": "A cinematic shot of a cat walking on the beach at sunset, soft ocean waves, warm golden lighting",
  "size": "1280x720",
  "seconds": 8
}

Request fields

FieldTypeRequiredDescription
modelstringYesVideo model name
promptstringYesVideo description (≤ 2500 characters)
sizestringConditionalResolution, e.g. 1280x720, 720x1280; required for models such as sora-2
secondsint / stringConditionalDuration in seconds; sora-2 allows 4/8/12/16/20
input_referenceobject / fileNoReference image

With reference image (JSON URL):

{
  "model": "sora-2",
  "prompt": "Animate this image with a slight camera move",
  "size": "1280x720",
  "seconds": 8,
  "input_reference": {
    "image_url": "https://example.com/ref.jpg"
  }
}

With reference image (Base64 data URI):

{
  "model": "sora-2",
  "prompt": "Animate this image with a slight camera move",
  "size": "1280x720",
  "seconds": 8,
  "input_reference": {
    "image_url": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."
  }
}

multipart/form-data: input_reference is a file form field; other fields use the same names.

Request example (curl)

JSON:

curl https://www.guid.ai/v1/videos \
  -H "Authorization: Bearer sk-xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sora-2",
    "prompt": "A cinematic shot of a cat walking on the beach at sunset, soft ocean waves, warm golden lighting",
    "size": "1280x720",
    "seconds": 8
  }'

With reference image (JSON):

curl https://www.guid.ai/v1/videos \
  -H "Authorization: Bearer sk-xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sora-2",
    "prompt": "Animate this image with a slight camera move",
    "size": "1280x720",
    "seconds": 8,
    "input_reference": {
      "image_url": "https://example.com/ref.jpg"
    }
  }'

multipart/form-data (upload reference image):

curl https://www.guid.ai/v1/videos \
  -H "Authorization: Bearer sk-xxx" \
  -F "model=sora-2" \
  -F "prompt=Animate this image with a slight camera move" \
  -F "size=1280x720" \
  -F "seconds=8" \
  -F "input_reference=@/path/to/ref.jpg"

Response body

HTTP 200

{
  "id": "task_abc123xyz",
  "status": "queued",
  "progress": 0,
  "created_at": 1712697600
}

Response fields

FieldTypeDescription
idstringTask ID for query and download
statusstringInitially queued
progressintegerProgress 0–100
created_atintegerUnix timestamp (seconds)

Failure response

HTTP 400

{
  "code": "invalid_request",
  "message": "seconds must be one of 4, 8, 12, 16, 20"
}
FieldTypeDescription
codestringError code
messagestringValidation failure reason

See Task errors for the error format.


5. GET /v1/videos/{task_id}

Query video task status.

Auth: Bearer Token

Path parameter: task_id — the id returned when creating the task

Request: No request body

Request example (curl)

curl https://www.guid.ai/v1/videos/task_abc123xyz \
  -H "Authorization: Bearer sk-xxx"

Response body (in progress)

HTTP 200

{
  "id": "task_abc123xyz",
  "object": "video",
  "model": "agnes-video-v2.0",
  "status": "in_progress",
  "progress": 45,
  "created_at": 1712697600,
  "seconds": "5.0",
  "size": "1280x704"
}

Response body (completed)

HTTP 200

{
  "id": "task_abc123xyz",
  "object": "video",
  "model": "agnes-video-v2.0",
  "status": "completed",
  "progress": 100,
  "created_at": 1712697600,
  "completed_at": 1712698200,
  "seconds": "5.0",
  "size": "1280x704",
  "remixed_from_video_id": "https://cdn.example.com/videos/video_abc.mp4",
  "error": null,
  "metadata": {
    "url": "https://cdn.example.com/videos/video_abc.mp4"
  }
}

Response body (failed)

HTTP 200

{
  "id": "task_abc123xyz",
  "object": "video",
  "model": "agnes-video-v2.0",
  "status": "failed",
  "progress": 100,
  "created_at": 1712697600,
  "error": {
    "message": "upstream generation failed",
    "code": "generation_failed"
  }
}

Response fields

FieldTypeDescription
idstringTask ID; same as the create response id
objectstringAlways video
modelstringModel used
statusstringTask status; see Task status
progressintegerProgress 0–100
created_atintegerCreated-at Unix timestamp (seconds)
completed_atintegerCompleted-at Unix timestamp (seconds); omitted while incomplete
expires_atintegerResult expiry Unix timestamp (seconds); returned by some channels
secondsstringVideo duration in seconds, e.g. "5.0"
sizestringVideo resolution, e.g. "1280x704"
remixed_from_video_idstringVideo result URL; some channels (e.g. Agnes AI) return a CDN address here
errorobject / nullError info on failure; null or omitted on success
error.messagestringFailure reason
error.codestringError code, e.g. generation_failed
metadataobjectExtended metadata; common keys below

Common metadata keys:

KeyTypeDescription
urlstringVideo result URL
thumbnail_urlstringThumbnail URL
durationnumberActual duration (seconds)
widthintegerVideo width (pixels)
heightintegerVideo height (pixels)
fpsintegerFrame rate
seedintegerRandom seed

6. GET /v1/videos/{task_id}/content

Download the generated video or thumbnail.

Auth: Bearer Token or admin console Session

Path parameter: task_id

Query parameters:

ParameterDescription
variantOptional. video (default) downloads the video; thumbnail downloads the cover image

Prerequisite: Task status must be completed.

Request example (curl)

Download video (follow 301 redirect):

curl -L https://www.guid.ai/v1/videos/task_abc123xyz/content \
  -H "Authorization: Bearer sk-xxx" \
  -o output.mp4

Download thumbnail:

curl -L "https://www.guid.ai/v1/videos/task_abc123xyz/content?variant=thumbnail" \
  -H "Authorization: Bearer sk-xxx" \
  -o cover.jpg

Response (already stored in object storage)

HTTP 301 Moved Permanently

Location: https://cdn.example.com/users/1/tasks/task_abc123xyz/video.mp4
Header / fieldDescription
LocationObject storage or CDN resource URL; clients should follow the redirect
BodyNo JSON content

Response (gateway proxies upstream)

HTTP 200, body is a binary stream (not JSON).

HeaderDescription
Content-Typevideo/mp4 (video) or image/jpeg / image/png (thumbnail)
Content-LengthFile size in bytes
Content-DispositionMay include filename, e.g. attachment; filename="task_abc123xyz.mp4"
BodyVideo or thumbnail binary data

Error responses

Task not completed yet, HTTP 400:

{
  "error": {
    "message": "Task is not completed yet, current status: in_progress",
    "type": "invalid_request_error"
  }
}

Task not found, HTTP 404:

{
  "error": {
    "message": "Task not found",
    "type": "invalid_request_error"
  }
}

Invalid variant, HTTP 400:

{
  "error": {
    "message": "invalid variant \"cover\", must be \"video\" or \"thumbnail\"",
    "type": "invalid_request_error"
  }
}

Thumbnail unavailable, HTTP 404:

{
  "error": {
    "message": "Thumbnail not available",
    "type": "invalid_request_error"
  }
}

See Standard errors for the error format.


7. POST /v1/guidai/videos

Multimodal video generation. Specify the generation mode with mode, and pass image/video URLs via assets[].

After a successful submit, query with GET /v1/videos/{task_id} and download with GET /v1/videos/{task_id}/content.

Auth: Bearer Token

Content-Type: application/json

Generation modes (mode)

modeDescriptionTypical required assets
t2vText-to-videoNone
i2vImage-to-videoimage
first_frameFirst-frame to videofirst_frame
first_last_frameFirst and last frame to videofirst_frame, last_frame
ref_imageReference-image to videoAt least one reference_images
video_extendVideo extend / continuesource_video
video_editSmart video editsource_video; optional reference_images

Enabled mode values per model follow the admin console Model capabilities → Video capabilities configuration.

Request fields

FieldTypeRequiredDescription
modelstringYesVideo model
modestringYesGeneration mode
promptstringConditionalVideo description; required for most modes
assetsarrayConditional[{ "role": "...", "url": "https://..." }]
resolutionstringNoe.g. 720p, 1080p
duration_secnumberNoDuration (seconds)
aspect_ratiostringNoe.g. 16:9, 3:2
prompt_optimizebooleanNoWhether to enable prompt optimization
gen_tierstringNoGeneration tier
qualitystringNoQuality
audio_modestringNoAudio mode
camera_controlstringNoCamera control
shot_typestringNoShot type
hd_upscalestringNoHD upscale

Request example: text-to-video (t2v)

{
  "model": "agnes-video-v2.0",
  "mode": "t2v",
  "prompt": "A cinematic shot of a cat walking on the beach at sunset, soft ocean waves, warm golden lighting, realistic motion",
  "resolution": "720p",
  "duration_sec": 5,
  "aspect_ratio": "3:2",
  "prompt_optimize": false
}

Request example: first-frame to video (first_frame)

{
  "model": "agnes-video-v2.0",
  "mode": "first_frame",
  "prompt": "The woman slowly turns around and looks back at the camera, natural facial expression, cinematic camera movement",
  "assets": [
    { "role": "first_frame", "url": "https://example.com/image.png" }
  ],
  "duration_sec": 5
}

Request example: reference-image to video (ref_image)

{
  "model": "agnes-video-v2.0",
  "mode": "ref_image",
  "prompt": "Create a smooth transformation scene between the two reference images, cinematic lighting, consistent character identity, natural motion",
  "assets": [
    { "role": "reference_images", "url": "https://example.com/image1.png" },
    { "role": "reference_images", "url": "https://example.com/image2.png" }
  ],
  "duration_sec": 5
}

Request example: video extend (video_extend)

{
  "model": "wan2.6-t2v",
  "mode": "video_extend",
  "prompt": "Continue the scene with the character walking into the sunset",
  "assets": [
    { "role": "source_video", "url": "https://example.com/source.mp4" }
  ],
  "duration_sec": 5,
  "resolution": "720p"
}

Request example (curl)

Text-to-video (t2v):

curl https://www.guid.ai/v1/guidai/videos \
  -H "Authorization: Bearer sk-xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "agnes-video-v2.0",
    "mode": "t2v",
    "prompt": "A cinematic shot of a cat walking on the beach at sunset, soft ocean waves, warm golden lighting, realistic motion",
    "resolution": "720p",
    "duration_sec": 5,
    "aspect_ratio": "3:2",
    "prompt_optimize": false
  }'

First-frame to video (first_frame):

curl https://www.guid.ai/v1/guidai/videos \
  -H "Authorization: Bearer sk-xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "agnes-video-v2.0",
    "mode": "first_frame",
    "prompt": "The woman slowly turns around and looks back at the camera, natural facial expression, cinematic camera movement",
    "assets": [
      {"role": "first_frame", "url": "https://example.com/image.png"}
    ],
    "duration_sec": 5
  }'

Reference-image to video (ref_image):

curl https://www.guid.ai/v1/guidai/videos \
  -H "Authorization: Bearer sk-xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "agnes-video-v2.0",
    "mode": "ref_image",
    "prompt": "Create a smooth transformation scene between the two reference images, cinematic lighting, consistent character identity, natural motion",
    "assets": [
      {"role": "reference_images", "url": "https://example.com/image1.png"},
      {"role": "reference_images", "url": "https://example.com/image2.png"}
    ],
    "duration_sec": 5
  }'

Video extend (video_extend):

curl https://www.guid.ai/v1/guidai/videos \
  -H "Authorization: Bearer sk-xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.6-t2v",
    "mode": "video_extend",
    "prompt": "Continue the scene with the character walking into the sunset",
    "assets": [
      {"role": "source_video", "url": "https://example.com/source.mp4"}
    ],
    "duration_sec": 5,
    "resolution": "720p"
  }'

Response body

HTTP 200

{
  "id": "task_abc123xyz",
  "status": "queued",
  "progress": 0,
  "created_at": 1712697600
}

Response fields

Same as the POST /v1/videos create response.

FieldTypeDescription
idstringTask ID for later query and download
statusstringInitially queued
progressintegerProgress 0–100
created_atintegerCreated-at Unix timestamp (seconds)

Subsequent query and download use GET /v1/videos/{task_id} and GET /v1/videos/{task_id}/content. Response fields are in Section 5 and Section 6.

Failure response

HTTP 400

{
  "code": "invalid_request",
  "message": "model and mode are required"
}
{
  "code": "invalid_request",
  "message": "prompt is required"
}

See Task errors for the error format.


1. POST /v1/videos or POST /v1/guidai/videos
   → obtain task_id

2. Poll GET /v1/videos/{task_id}
   → continue waiting while status = queued / in_progress
   → inspect error when status = failed
   → proceed when status = completed

3. GET /v1/videos/{task_id}/content
   → download the video file

4. (Optional) GET /v1/videos/{task_id}/content?variant=thumbnail
   → download the thumbnail

Suggested polling interval: 3–10 seconds, to avoid rate limiting from overly frequent requests.