SoxAIDocs
API Reference

Video Generation

POST /v1/video/generations — generate videos from text or images

Video Generation

POST /v1/video/generations

Generate videos from a text prompt, reference images, or reference videos using supported video generation models.

SoxAI acts as a relay — the upstream provider's raw response is passed through verbatim to the client, with SoxAI's job management fields (id, status, url, etc.) injected directly into the response JSON. No wrapping, no filtering.

Create Video Job

Request

POST /v1/video/generations

Headers

HeaderRequiredDescription
AuthorizationYesBearer sox-your-api-key
Content-TypeYesapplication/json

Request Body Parameters

ParameterTypeRequiredDescription
modelstringYesVideo model ID. See Supported Models below
promptstringYesText description of the desired video. Max ~2500 Chinese characters or ~5000 non-Chinese characters
durationintegerNoVideo duration in seconds. Range: 3–15. Default: 5
resolutionstringNoOutput resolution. Values: 480P, 720P, 1080P. Default varies by model
aspect_ratiostringNoAspect ratio. Values: 16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21, 21:9. Default: 16:9
generate_audiobooleanNoWhether to generate audio for the video. Affects pricing for some models. Default: model-specific
image_urlsstring[]NoReference image URLs. Used for image-to-video (i2v) and reference-to-video (r2v) models. Supports 1–9 images depending on model
image_urlstringNoSingle reference image URL (legacy field, use image_urls instead). If image_urls is empty and this is set, it becomes image_urls[0]
video_urlsstring[]NoReference video URLs. Used for video editing models. Supports 1 video
audio_urlsstring[]NoReference audio URLs. Used for multimodal reference generation (Ark-native only)
watermarkbooleanNoWhether to add watermark to the video. Default: true
fpsintegerNoFrames per second. Rarely used, most models have fixed FPS
callback_urlstringNoWebhook URL. SoxAI POSTs the final job result to this URL on completion or failure. Must be on SSRF allowlist

Example: Text-to-Video (HappyHorse)

curl -X POST https://api.soxai.io/v1/video/generations \
  -H "Authorization: Bearer $SOXAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.1-t2v",
    "prompt": "一只小猫在草地上奔跑",
    "duration": 5,
    "resolution": "720P",
    "aspect_ratio": "16:9",
    "watermark": false
  }'

Example: Image-to-Video (Seedance with reference images)

curl -X POST https://api.soxai.io/v1/video/generations \
  -H "Authorization: Bearer $SOXAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2-0-260128",
    "prompt": "图片1的角色在图片2的场景中奔跑",
    "duration": 4,
    "resolution": "480p",
    "aspect_ratio": "16:9",
    "generate_audio": true,
    "image_urls": [
      "https://example.com/character.png",
      "https://example.com/scene.png"
    ],
    "watermark": false
  }'

Response (201 Created)

Returns the upstream provider's raw submit response with SoxAI fields injected. The response shape depends on which provider the channel is configured to use.

SoxAI Injected Fields

These fields are always present, injected into the upstream JSON:

FieldTypeDescription
idstring (UUID)SoxAI job ID. Use this to poll status
objectstringAlways "video.generation"
statusstringJob status: queued, processing, succeeded, failed, expired
modelstringModel ID used for this job
created_atinteger (unix timestamp)Job creation time
expires_atinteger (unix timestamp)Job expiry time (7 days after creation). Video URL becomes unavailable after this
urlstringSoxAI CDN URL for the generated video. Only present when status is succeeded
duration_secsfloatActual video duration in seconds. Only present when status is succeeded
errorstringError message. Only present when status is failed

Example: Submit Response (HappyHorse via DashScope)

{
  "id": "c1db669d-b412-4f7a-b700-2436c5d52810",
  "object": "video.generation",
  "status": "queued",
  "model": "happyhorse-1.1-t2v",
  "created_at": 1785643294,
  "expires_at": 1786248094,
  "output": {
    "task_id": "113ba373-93be-4204-984a-d4a3440c9e0f",
    "task_status": "PENDING"
  },
  "request_id": "ca8ca029-901c-999e-a8d7-d277bbfd4b19"
}

output, request_id — upstream DashScope fields, passed through as-is.

Example: Submit Response (Seedance via Volcengine Ark)

{
  "id": "bcd16484-8630-4ee2-9ee3-f6fb9b864031",
  "object": "video.generation",
  "status": "queued",
  "model": "doubao-seedance-2-0-260128",
  "created_at": 1785639267,
  "expires_at": 1786244067,
  "id": "task_wklJT1SWIQNXSaZEkfPcEzdDPj8VO4W9",
  "object": "video.generation.task",
  "status": "pending"
}

Note: upstream id and status fields are overridden by SoxAI's injected values.


Get Video Job

GET /v1/video/generations/{job_id}

Poll the status of a video generation job. The video worker automatically polls the upstream provider and stores the result. You should poll every 5–15 seconds until status is succeeded or failed.

Request

Path ParameterTypeRequiredDescription
job_idstring (UUID)YesThe job ID returned by POST /v1/video/generations

Example

curl https://api.soxai.io/v1/video/generations/c1db669d-b412-4f7a-b700-2436c5d52810 \
  -H "Authorization: Bearer $SOXAI_API_KEY"

Response (200 OK)

Returns the upstream provider's raw poll response with SoxAI fields injected.

Status Values

StatusDescription
queuedJob created, waiting for video worker to submit to upstream
processingSubmitted to upstream, waiting for video generation to complete
succeededVideo generation complete, url field has the CDN link
failedGeneration failed, error field has the error message
expiredJob expired (7 days after creation), video URL no longer available

Example: Processing Response

{
  "id": "c1db669d-b412-4f7a-b700-2436c5d52810",
  "object": "video.generation",
  "status": "processing",
  "model": "happyhorse-1.1-t2v",
  "created_at": 1785643294,
  "expires_at": 1786248094
}

Example: Succeeded Response (Seedance)

All upstream fields (data, task_id, duration, video_url, usage, upstream_response, etc.) are passed through as-is:

{
  "id": "c1db669d-b412-4f7a-b700-2436c5d52810",
  "object": "video.generation",
  "status": "succeeded",
  "model": "doubao-seedance-2-0-260128",
  "created_at": 1785643294,
  "expires_at": 1786248094,
  "url": "https://cdn.soxai.io/videos/1/c1db669d-b412-4f7a-b700-2436c5d52810.mp4",
  "duration_secs": 4,
  "data": [
    {
      "url": "https://upstream-cdn.example.com/video.mp4"
    }
  ],
  "task_id": "task_6yWpifeskOZOPL0VHooIC97qL3iUjgKY",
  "duration": 4,
  "tos_key": "ai-open-api/.../video.mp4",
  "trace_id": "11c5fc2f6bb5e6c29000bbfc7a4088a3",
  "video_url": "https://upstream-cdn.example.com/video.mp4",
  "usage": {
    "completion_tokens": 40594,
    "total_tokens": 40594
  },
  "upstream_response": {
    "code": 0,
    "data": {
      "status": "succeeded",
      "duration": 4,
      "generate_audio": true,
      "framespersecond": "24",
      "seed": "37400",
      "video_url": "https://upstream-cdn.example.com/video.mp4",
      "usage": {
        "completion_tokens": 40594,
        "total_tokens": 40594
      }
    },
    "message": "",
    "trace_id": "11c5fc2f6bb5e6c29000bbfc7a4088a3"
  }
}

Field Reference

SoxAI injected fields (always present):

FieldTypePresent WhenDescription
idstringAlwaysSoxAI job UUID
objectstringAlways"video.generation"
statusstringAlwaysqueued / processing / succeeded / failed / expired
modelstringAlwaysModel ID
created_atintegerAlwaysUnix timestamp, job creation time
expires_atintegerAlwaysUnix timestamp, job expiry (7 days)
urlstringsucceededSoxAI CDN URL for the video file
duration_secsfloatsucceededVideo duration in seconds
errorstringfailedError message

Upstream passthrough fields (provider-specific, varies):

FieldProviderDescription
output.task_idDashScope (HappyHorse)Upstream task ID
output.task_statusDashScope (HappyHorse)Upstream task status (PENDING, RUNNING, SUCCEEDED, FAILED)
output.video_urlDashScope (HappyHorse)Upstream video URL
usage.durationDashScope (HappyHorse)Video duration
usage.SRDashScope (HappyHorse)Resolution height (720 = 720P)
usage.ratioDashScope (HappyHorse)Aspect ratio
usage.video_countDashScope (HappyHorse)Number of videos generated
data[].urlSeedance (proxy/Ark)Upstream video URL
task_idSeedance (proxy)Upstream task ID
video_urlSeedance (BytePlus/Ark)Upstream video URL
durationSeedanceVideo duration
usage.completion_tokensSeedance (Ark)Token count for billing
usage.total_tokensSeedance (Ark)Total token count
upstream_responseSeedance (proxy)Full upstream nested response
generate_audioSeedance (Ark)Whether audio was generated
framespersecondSeedance (Ark)Frame rate

These fields come directly from the upstream provider. SoxAI does not modify, filter, or rename them. If the upstream changes their response format, the client sees the change immediately.


List Video Jobs

GET /v1/video/generations

List video generation jobs for the authenticated tenant, ordered by creation time (newest first).

Request

Query ParameterTypeDefaultDescription
limitinteger20Number of jobs to return (max 100)
offsetinteger0Pagination offset

Example

curl "https://api.soxai.io/v1/video/generations?limit=10&offset=0" \
  -H "Authorization: Bearer $SOXAI_API_KEY"

Response (200 OK)

{
  "object": "list",
  "data": [
    {
      "id": "c1db669d-b412-4f7a-b700-2436c5d52810",
      "object": "video.generation",
      "status": "succeeded",
      "model": "happyhorse-1.1-t2v",
      "created_at": 1785643294,
      "expires_at": 1786248094,
      "url": "https://cdn.soxai.io/videos/1/c1db669d-b412-4f7a-b700-2436c5d52810.mp4",
      "duration_secs": 5
    }
  ]
}

Each item in data has the same shape as the Get Video Job response.


Delete Video Job

DELETE /v1/video/generations/{job_id}

Delete a video job and its associated video file. Only jobs belonging to the authenticated tenant can be deleted.

Request

curl -X DELETE "https://api.soxai.io/v1/video/generations/c1db669d-b412-4f7a-b700-2436c5d52810" \
  -H "Authorization: Bearer $SOXAI_API_KEY"

Response (200 OK)

{
  "deleted": true
}

Supported Models

Seedance (ByteDance)

ModelTypeMax DurationResolutions
doubao-seedance-2-0-260128Text/Image-to-Video15s480P, 720P, 1080P
seedance-2Text/Image-to-Video15s480P, 720P, 1080P
seedance-2-fastText/Image-to-Video15s480P, 720P, 1080P
seedance-2-liteText/Image-to-Video15s480P, 720P, 1080P
seedance-2-proText/Image-to-Video15s480P, 720P, 1080P
seedance-1-liteText/Image-to-Video10s480P, 720P
seedance-1-proText/Image-to-Video10s480P, 720P

Access routes (configured as channel base_url):

RouteBase URLBillingNotes
Volcengine Arkhttps://ark.cn-beijing.volces.comCNYChina mainland, multimodal references
BytePlus Internationalhttps://open.byteplusapi.comUSDInternational
Third-party proxyhttps://your-proxy.comVariesOpenAI-compatible format

HappyHorse (Alibaba Bailian)

ModelTypeMax DurationResolutionsReference Images
happyhorse-1.1-t2vText-to-Video15s480P, 720P, 1080P
happyhorse-1.1-i2vImage-to-Video15s480P, 720P, 1080P1 (first frame)
happyhorse-1.1-r2vReference-to-Video15s480P, 720P, 1080P1–9
happyhorse-1.0-t2vText-to-Video15s480P, 720P, 1080P
happyhorse-1.0-i2vImage-to-Video15s480P, 720P, 1080P1 (first frame)
happyhorse-1.0-r2vReference-to-Video15s480P, 720P, 1080P1–9
happyhorse-1.0-video-editVideo Edit15s720P, 1080P0–5 reference images + 1 video

Access route:

RouteBase URLNotes
DashScope APIhttps://dashscope.aliyuncs.comSoxAI automatically sets X-DashScope-Async: enable header

HappyHorse specific constraints:

ConstraintValue
Image formatsJPEG, JPG, PNG, WEBP
Image min resolution300×300 pixels
Image aspect ratio range1:2.5 to 2.5:1
Image max file size20 MB
Reference image min resolution (r2v)400px short side
Video formats (video-edit)MP4, MOV (H.264 recommended)
Video max duration (video-edit)60s (output capped at 15s)
Video max file size (video-edit)100 MB
Video min FPS (video-edit)8
WatermarkAdds "Happy Horse" watermark in bottom-right if watermark: true

Billing

Video generation billing depends on the model's billing_type:

Billing TypeFormulaDriven By
tokencompletion_tokens × price_per_millionusage.completion_tokens from upstream
per_secondactual_duration_seconds × price_per_secondduration / duration_secs from upstream
per_requestFixed price per generationN/A

If the upstream omits completion_tokens (token billing), SoxAI falls back to the pre-consumed estimate locked at job creation time.

Pricing tiers may vary by resolution and whether audio was generated. See the model catalog in the admin console for specific pricing.


Webhook Callbacks

If callback_url is provided in the request body, SoxAI POSTs the final job result to that URL when the job completes (succeeded or failed). The URL must be on the SSRF allowlist.

Callback Payload

{
  "id": "c1db669d-b412-4f7a-b700-2436c5d52810",
  "status": "succeeded",
  "url": "https://cdn.soxai.io/videos/1/c1db669d-b412-4f7a-b700-2436c5d52810.mp4",
  "duration_secs": 4
}

The callback is sent only once, after the video worker has finished downloading and storing the video. If the callback URL is unreachable, SoxAI does not retry — use GET /v1/video/generations/{id} as a fallback.


Error Handling

400 Bad Request

{
  "error": "invalid request body"
}

401 Unauthorized

{
  "error": "invalid api key"
}

402 Payment Required

{
  "error": "insufficient quota for this video generation"
}

404 Not Found

{
  "error": "video job not found"
}