Video Generation (Seedance 2.0)
Pomex provides an asynchronous video generation API powered by Seedance 2.0. The workflow follows a task-based pattern: submit a generation request, then poll for results or receive a webhook callback when the video is ready.
Asynchronous API — Video generation takes time. The Create endpoint returns immediately with a task object. In the common case the initial status is queued; if upstream already returns a richer snapshot, Pomex will persist and return that status instead. Poll the Get endpoint or provide a callback_url to be notified on completion.
Overview
| Endpoint | Method | Description |
|---|---|---|
| /v1/video/generations | POST |
Create a new video generation task |
| /v1/video/generations | GET |
List your video generation tasks |
| /v1/video/generations/{task_id} | GET |
Get a specific task (poll for status/result) |
| /v1/video/generations/{task_id} | DELETE |
Delete (cancel) a video generation task |
| /v1/video/assets | POST |
Create (upload) a new media asset for use as reference |
| /v1/video/assets/{asset_id} | GET |
Get asset status and details |
Available Models
| Model ID | Description | Capabilities |
|---|---|---|
| byteplus/seedance-2.0 | Seedance 2.0 — BytePlus's state-of-the-art video generation model | Text-to-video, Image-to-video, Video-to-video, Audio-driven |
Task Status Lifecycle
| Status | Description | Terminal? |
|---|---|---|
| queued | Task accepted, waiting for GPU resources | No |
| running | Video is being generated | No |
| succeeded | Generation complete — video URL available in content |
Yes |
| failed | Generation failed — see error field for details |
Yes |
| cancelled | Task was cancelled via DELETE | Yes |
Create Video Generation
Submit a video generation task. The response returns immediately with a task object containing a unique id for polling.
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string |
Yes | Model identifier. Currently: "byteplus/seedance-2.0" |
| content | array |
Yes | Array of content items describing the video to generate (text prompts, reference images/videos/audio). Must contain at least 1 item. |
| duration | integer |
No | Video duration in seconds. Minimum 4 seconds. Maximum depends on the generation mode and upstream configuration. Forwarded as-is when present. |
| ratio | string |
No | Aspect ratio. Supported values: "16:9", "9:16", "1:1". Forwarded to upstream after trimming whitespace. |
| resolution | string |
No | Output resolution. Supported values: "720p", "1080p". Higher resolutions (e.g. "4k") are not supported by the current model and will be rejected by upstream. |
| seed | integer |
No | Optional upstream seed value. Pomex stores nothing special here; it is passed through when present. |
| framespersecond | integer |
No | Optional FPS hint forwarded as-is to upstream. Note the JSON field name is exactly framespersecond. |
| generate_audio | boolean |
No | Optional upstream flag for generating audio. If omitted, Pomex does not inject a default; upstream behavior applies. |
| draft | boolean |
No | Draft mode flag (faster generation with lower quality). Only supported in image-to-video (i2v) mode. Not supported in text-to-video (t2v) — sending draft in t2v mode will be rejected by upstream. |
| service_tier | string |
No | Optional upstream service tier string, forwarded after trimming whitespace. |
| callback_url | string |
No | Customer webhook target stored by Pomex. When the task reaches a terminal state and the URL is HTTPS, Pomex POSTs the task JSON to this URL. This value is platform-only and is not forwarded upstream as-is. |
| execution_expires_after | integer |
No | Requested execution timeout in seconds. If omitted, Pomex computes the effective timeout from provider config or falls back to 172800 seconds (48 hours). |
| metadata | object |
No | Arbitrary JSON metadata attached to the task. Returned in all subsequent responses. |
Request Normalization Rules
Pomex does not reject every unsupported field combination. During create, it builds a sanitized upstream request body and drops unsupported fields or invalid content-item subfields where possible. A request is rejected only when required top-level fields are missing, or when sanitization leaves no valid content items.
| Rule | Behavior |
|---|---|
| Unsupported top-level fields | Ignored for upstream submission. Example: custom fields such as watermark are dropped rather than forwarded. |
| text content role | role is not forwarded on type="text" items. |
| Media item role | Only the matching role is kept: reference_image for image_url, reference_video for video_url, reference_audio for audio_url. Other roles are dropped. |
| Wrong media field on item | Extra fields such as text on a media item, or image_url on a video_url item, are dropped. |
| Invalid content items | Items with unsupported type, missing required text, or missing required media URL are dropped. If all items are dropped, create returns 400. |
| callback_url | The customer callback URL is stored by Pomex. If VIDEO_WEBHOOK_BASE_URL is configured, Pomex separately registers its own official upstream webhook endpoint at /v1/video/result. |
Content Item Structure
Each element in the content array describes an input modality:
| Field | Type | Description |
|---|---|---|
| type | string |
Required. One of: "text", "image_url", "video_url", "audio_url" |
| role | string |
Role for media items. Options: "reference_image", "reference_video", "reference_audio" |
| text | string |
Text content (required when type is "text"). This is your generation prompt. |
| image_url | object |
Image reference (required when type is "image_url"). Contains {"url": "..."} |
| video_url | object |
Video reference (required when type is "video_url"). Contains {"url": "..."} |
| audio_url | object |
Audio reference (required when type is "audio_url"). Contains {"url": "..."} |
Generation Modes
These are common request shapes supported by the current request sanitizer and upstream mapping:
| Mode | Content Configuration | Description |
|---|---|---|
| Text-to-Video | [{type:"text", text:"..."}] |
Generate video from a text prompt alone. |
| Image-to-Video | [{type:"text", text:"..."}, {type:"image_url", role:"reference_image", image_url:{url:"..."}}] |
Animate a reference image with a text prompt. The media role is optional but only reference_image is preserved if provided. |
| Video-to-Video | [{type:"text", text:"..."}, {type:"video_url", role:"reference_video", video_url:{url:"..."}}] |
Transform or extend a reference video. Only reference_video is preserved if a role is provided. |
| Audio-driven | [{type:"text", text:"..."}, {type:"image_url", role:"reference_image", ...}, {type:"audio_url", role:"reference_audio", audio_url:{url:"..."}}] |
Generate video synchronized to reference audio. Audio cannot be the only reference input — you must also include a reference_image or reference_video alongside the audio reference. |
Parameter Constraints
| Constraint | Details |
|---|---|
| duration | Minimum 4 seconds. Maximum depends on generation mode (typically 5–10s for i2v, up to 15s for t2v). |
| ratio | Supported: "16:9", "9:16", "1:1". |
| resolution | Supported: "720p", "1080p". Higher resolutions (e.g. "4k") are not supported. |
| draft | Only supported in image-to-video (i2v) mode. Sending draft in text-to-video (t2v) will be rejected. |
| reference_audio | Cannot be the only reference input. Must be combined with reference_image or reference_video. |
Example: Text-to-Video
curl https://api.pomex.ai/v1/video/generations \
-H "Authorization: Bearer $POMEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "byteplus/seedance-2.0",
"content": [
{
"type": "text",
"text": "A golden retriever running through a field of sunflowers at sunset, cinematic 4K, slow motion"
}
],
"duration": 10,
"ratio": "16:9",
"resolution": "1080p"
}'import requests
resp = requests.post(
"https://api.pomex.ai/v1/video/generations",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"model": "byteplus/seedance-2.0",
"content": [
{
"type": "text",
"text": "A golden retriever running through a field of sunflowers at sunset, cinematic 4K, slow motion"
}
],
"duration": 10,
"ratio": "16:9",
"resolution": "1080p",
},
)
task = resp.json()
print(task["id"], task["status"])
# → "task_abc123..." "queued"Response (200 OK)
{
"id": "task_01JXN4KQWER5678ABCDEFGH",
"object": "video.generation.task",
"created": 1748160000,
"model": "byteplus/seedance-2.0",
"status": "queued",
"metadata": null
}Example: Image-to-Video
curl https://api.pomex.ai/v1/video/generations \
-H "Authorization: Bearer $POMEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "byteplus/seedance-2.0",
"content": [
{
"type": "text",
"text": "The character slowly turns their head and smiles at the camera"
},
{
"type": "image_url",
"role": "reference_image",
"image_url": {
"url": "https://example.com/portrait.jpg"
}
}
],
"duration": 5,
"ratio": "9:16",
"resolution": "1080p"
}'Example: With Audio and Callback
curl https://api.pomex.ai/v1/video/generations \
-H "Authorization: Bearer $POMEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "byteplus/seedance-2.0",
"content": [
{
"type": "text",
"text": "A musician playing piano in a dimly lit jazz club"
},
{
"type": "image_url",
"role": "reference_image",
"image_url": {
"url": "https://example.com/pianist-photo.jpg"
}
},
{
"type": "audio_url",
"role": "reference_audio",
"audio_url": {
"url": "https://example.com/jazz-piano.mp3"
}
}
],
"generate_audio": true,
"duration": 15,
"ratio": "16:9",
"callback_url": "https://myapp.example.com/webhooks/video-done",
"metadata": {"project": "music-video", "scene": 3}
}'Get Video Generation
Retrieve the current status and result of a video generation task. If the task is still non-terminal, Pomex synchronizes the latest upstream snapshot before returning. Poll this endpoint until status reaches a terminal state (succeeded, failed, or cancelled).
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| task_id | string |
The unique task identifier returned by the Create endpoint. |
Example Request
curl https://api.pomex.ai/v1/video/generations/task_01JXN4KQWER5678ABCDEFGH \
-H "Authorization: Bearer $POMEX_API_KEY"import time
import requests
task_id = "task_01JXN4KQWER5678ABCDEFGH"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
# Polling loop
while True:
resp = requests.get(
f"https://api.pomex.ai/v1/video/generations/{task_id}",
headers=headers,
)
task = resp.json()
print(f"Status: {task['status']}")
if task["status"] in ("succeeded", "failed", "cancelled"):
break
time.sleep(5) # poll every 5 seconds
# On success, content contains the video URL
if task["status"] == "succeeded":
print("Video URL:", task["content"]["video_url"])
elif task["status"] == "failed":
print("Failed:", task["error"])Note: The content.video_url is a pre-signed URL with a time-limited expiry (typically 24 hours). Download the video promptly or poll the Get endpoint again to obtain a fresh URL.
Response: Running
{
"id": "task_01JXN4KQWER5678ABCDEFGH",
"object": "video.generation.task",
"created": 1748160000,
"model": "byteplus/seedance-2.0",
"status": "running",
"updated_at": 1748160012
}Response: Succeeded
{
"id": "cgt-20260526115001-ldvq4",
"object": "video.generation.task",
"created": 1779767402,
"model": "byteplus/seedance-2.0",
"status": "succeeded",
"updated_at": 1779767585,
"completed_at": 1779767585,
"content": {
"video_url": "https://ark-acg-ap-southeast-1.tos-ap-southeast-1.volces.com/dreamina-seedance-2-0/example.mp4?X-Tos-Algorithm=TOS4-HMAC-SHA256&..."
},
"metadata": {}
}Note: The content field contains upstream-defined payload. For succeeded tasks, it typically has a video_url field with a pre-signed download URL. The URL is time-limited (usually 24 hours) — download promptly or use the Get endpoint to obtain a fresh URL.
Response: Failed
{
"id": "task_01JXN4KQWER5678ABCDEFGH",
"object": "video.generation.task",
"created": 1748160000,
"model": "byteplus/seedance-2.0",
"status": "failed",
"updated_at": 1748160045,
"completed_at": 1748160045,
"error": {
"code": "content_policy_violation",
"message": "The prompt was rejected due to content policy.",
"type": "video_generation_error",
"param": null
}
}List Video Generations
List all non-deleted video generation tasks for the authenticated API key. This endpoint reads from Pomex storage only and does not synchronize with upstream. Results are ordered by created_at DESC, task_id DESC and support cursor-based pagination.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | integer |
20 | Number of tasks to return. Omitted or 0 becomes 20. Values above 100 are capped at 100. Negative or non-integer values return 400. |
| cursor | string |
— | Opaque pagination cursor from a previous response's next_cursor. |
Example Request
curl "https://api.pomex.ai/v1/video/generations?limit=5" \
-H "Authorization: Bearer $POMEX_API_KEY"Response
{
"object": "list",
"data": [
{
"id": "task_01JXN4KQWER5678ABCDEFGH",
"object": "video.generation.task",
"created": 1748160000,
"model": "byteplus/seedance-2.0",
"status": "succeeded",
"completed_at": 1748160090
},
{
"id": "task_01JXN3ABCDEF1234567890",
"object": "video.generation.task",
"created": 1748159000,
"model": "byteplus/seedance-2.0",
"status": "running"
}
],
"has_more": true,
"next_cursor": "eyJjIjoiMjAyNi0wNS0yNVQxMDowMDowMFoifQ"
}Delete Video Generation
Delete a video generation task. Pomex first calls upstream DELETE, then soft-deletes the local task row and returns a compact delete response.
If upstream returns a final snapshot during delete, Pomex will merge that snapshot and attempt terminal billing settlement before soft deletion.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| task_id | string |
The task identifier to delete. |
Example Request
curl -X DELETE https://api.pomex.ai/v1/video/generations/task_01JXN4KQWER5678ABCDEFGH \
-H "Authorization: Bearer $POMEX_API_KEY"Response (200 OK)
{
"id": "task_01JXN4KQWER5678ABCDEFGH",
"object": "video.generation.task",
"deleted": true
}Webhook Callback
If you provide a callback_url in the Create request, Pomex stores it and may send a POST request when the task reaches a terminal state. The request body is the same task JSON returned by the Get endpoint.
Delivery rules: only HTTPS callback URLs are delivered. The current default retry config is 3 attempts total (initial try plus 2 retries) with backoff delays of 1s and 3s. Network errors and 5xx responses are retried; 4xx responses are not retried.
Callback Request Body
POST https://yourapp.example.com/webhooks/video-done
Content-Type: application/json
{
"id": "task_01JXN4KQWER5678ABCDEFGH",
"object": "video.generation.task",
"created": 1748160000,
"model": "byteplus/seedance-2.0",
"status": "succeeded",
"completed_at": 1748160090,
"content": {
"video_url": "https://ark-acg-ap-southeast-1.tos-ap-southeast-1.volces.com/dreamina-seedance-2-0/example.mp4?X-Tos-Algorithm=TOS4-HMAC-SHA256&..."
},
"metadata": {"project": "music-video", "scene": 3}
}Complete Workflow Example
Here's a full Python example that creates a video, polls for completion, and downloads the result:
import time
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.pomex.ai"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# Step 1: Create the video generation task
create_resp = requests.post(
f"{BASE_URL}/v1/video/generations",
headers=headers,
json={
"model": "byteplus/seedance-2.0",
"content": [
{"type": "text", "text": "A serene ocean wave crashing on a rocky shore at golden hour, 4K cinematic"},
{
"type": "image_url",
"role": "reference_image",
"image_url": {"url": "https://example.com/beach-reference.jpg"},
},
],
"duration": 10,
"ratio": "16:9",
"resolution": "1080p",
"generate_audio": True,
},
)
create_resp.raise_for_status()
task = create_resp.json()
task_id = task["id"]
print(f"Task created: {task_id} (status: {task['status']})")
# Step 2: Poll until terminal state
while task["status"] not in ("succeeded", "failed", "cancelled"):
time.sleep(5)
poll_resp = requests.get(f"{BASE_URL}/v1/video/generations/{task_id}", headers=headers)
poll_resp.raise_for_status()
task = poll_resp.json()
print(f" Status: {task['status']}")
# Step 3: Handle result
if task["status"] == "succeeded":
video_url = task["content"]["video_url"]
print(f"Video URL: {video_url}")
# Download the video (URL is time-limited, typically 24h)
video_data = requests.get(video_url).content
with open("output.mp4", "wb") as f:
f.write(video_data)
print("Saved to output.mp4")
elif task["status"] == "failed":
print(f"Generation failed: {task['error']['message']}")
elif task["status"] == "cancelled":
print("Task was cancelled")Error Responses
Error responses use the same top-level OpenAI-style error envelope as the rest of Pomex. The exact type string varies by code path, so the table below focuses on status and trigger conditions that are confirmed in the implementation.
{
"error": {
"message": "content must contain at least one item",
"type": "invalid_request_error",
"param": null,
"code": null
}
}| HTTP Status | Cause |
|---|---|
| 400 | Invalid request body, missing model, empty content, invalid list cursor, invalid list limit, missing task_id, or sanitized request with no valid content items remaining. |
| 401 | Missing or invalid API key |
| 402 | Insufficient credit balance for prepaid accounts |
| 404 | Unsupported model on create, or task_id not found for get/delete |
| 413 | Request body too large |
| 429 | Rate limit exceeded during create |
| 503 | Store/upstream not configured, billing unavailable, persistence failure, or other service-side dependency failure |
Video Assets
The Video Assets API allows you to upload media files (images, videos, audio) to the asset library for use as references in video generation. Assets are uploaded via URL, processed and moderated by upstream, then become available for use in generation requests.
| Endpoint | Method | Description |
|---|---|---|
| /v1/video/assets | POST |
Create (upload) a new asset |
| /v1/video/assets/{asset_id} | GET |
Get asset status and details |
Asset Status Lifecycle
| Status | Description |
|---|---|
| processing | Asset uploaded and being processed/moderated by upstream |
| active | Asset is ready for use in video generation requests |
| failed | Processing or moderation failed — see error field for details |
Create Asset
Upload a media file by providing its HTTPS URL. The asset will be processed and moderated by the upstream service. The response returns immediately with the asset ID and a processing status.
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string |
Yes | HTTPS URL of the media file to upload. Must be a valid https:// URL. |
| asset_type | string |
Yes | Type of the asset. Must be one of: "Image", "Video", "Audio" (case-sensitive). |
| name | string |
No | Optional human-readable name for the asset. Maximum 64 characters. |
Example Request
curl https://api.pomex.ai/v1/video/assets \
-H "Authorization: Bearer $POMEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/my-reference-image.jpg",
"asset_type": "Image",
"name": "Beach portrait reference"
}'import requests
resp = requests.post(
"https://api.pomex.ai/v1/video/assets",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"url": "https://example.com/my-reference-image.jpg",
"asset_type": "Image",
"name": "Beach portrait reference",
},
)
asset = resp.json()
print(asset["id"], asset["status"])
# → "asset_abc123..." "processing"Response (200 OK)
{
"id": "asset_01JXN5ABC1234567890DEF",
"object": "video.asset",
"status": "processing"
}Get Asset
Retrieve the current status and details of an asset. Poll this endpoint to check when an asset becomes active and ready for use in video generation requests.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| asset_id | string |
The unique asset identifier returned by the Create endpoint. |
Example Request
curl https://api.pomex.ai/v1/video/assets/asset_01JXN5ABC1234567890DEF \
-H "Authorization: Bearer $POMEX_API_KEY"Response: Processing
{
"id": "asset_01JXN5ABC1234567890DEF",
"object": "video.asset",
"name": "Beach portrait reference",
"asset_type": "Image",
"status": "processing",
"created_at": "2026-05-25T10:00:00Z",
"updated_at": "2026-05-25T10:00:00Z"
}Response: Active
{
"id": "asset_01JXN5ABC1234567890DEF",
"object": "video.asset",
"name": "Beach portrait reference",
"url": "https://cdn.example.com/assets/processed_abc123.jpg",
"asset_type": "Image",
"status": "active",
"created_at": "2026-05-25T10:00:00Z",
"updated_at": "2026-05-25T10:00:15Z"
}Response: Failed
{
"id": "asset_01JXN5ABC1234567890DEF",
"object": "video.asset",
"name": "Beach portrait reference",
"asset_type": "Image",
"status": "failed",
"error": {
"code": "moderation_rejected",
"message": "Asset rejected during content moderation"
},
"created_at": "2026-05-25T10:00:00Z",
"updated_at": "2026-05-25T10:00:20Z"
}Asset Error Responses
| HTTP Status | Cause |
|---|---|
| 400 | Missing or invalid url (must be HTTPS), missing or invalid asset_type (must be Image/Video/Audio), name exceeds 64 characters, missing asset_id in path |
| 401 | Missing or invalid API key |
| 404 | Asset not found (wrong asset_id or asset belongs to a different organization) |
| 413 | Request body too large |
| 503 | Asset service unavailable, organization asset library not configured, admin credentials not configured, upstream failure, or persistence failure |
Using Assets in Video Generation
Once an asset reaches active status, use the asset://{asset_id} protocol URL in your video generation request's media fields. The gateway resolves the asset reference automatically:
# Step 1: Create an image asset
curl https://api.pomex.ai/v1/video/assets \
-H "Authorization: Bearer $POMEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/my-portrait.jpg",
"asset_type": "Image",
"name": "Portrait reference"
}'
# → {"id":"asset-20260524233646-v76gs","object":"video.asset","status":"processing"}
# Step 2: Poll until active
curl https://api.pomex.ai/v1/video/assets/asset-20260524233646-v76gs \
-H "Authorization: Bearer $POMEX_API_KEY"
# → {"id":"asset-20260524233646-v76gs","object":"video.asset","status":"active",...}
# Step 3: Use asset:// protocol URL in video generation
curl https://api.pomex.ai/v1/video/generations \
-H "Authorization: Bearer $POMEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "byteplus/seedance-2.0",
"content": [
{
"type": "text",
"text": "The person slowly turns their head and smiles warmly at the camera"
},
{
"type": "image_url",
"role": "reference_image",
"image_url": {
"url": "asset://asset-20260524233646-v76gs"
}
}
],
"duration": 5,
"ratio": "9:16"
}'import time
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.pomex.ai"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# Step 1: Upload an image asset
asset_resp = requests.post(
f"{BASE_URL}/v1/video/assets",
headers=headers,
json={
"url": "https://example.com/my-portrait.jpg",
"asset_type": "Image",
"name": "Portrait reference",
},
)
asset_resp.raise_for_status()
asset_id = asset_resp.json()["id"]
print(f"Asset created: {asset_id}")
# Step 2: Poll until the asset is active
while True:
get_resp = requests.get(f"{BASE_URL}/v1/video/assets/{asset_id}", headers=headers)
get_resp.raise_for_status()
asset = get_resp.json()
print(f" Asset status: {asset['status']}")
if asset["status"] == "active":
break
elif asset["status"] == "failed":
raise RuntimeError(f"Asset failed: {asset.get('error', {}).get('message')}")
time.sleep(3)
print(f"Asset ready: {asset_id}")
# Step 3: Use asset:// protocol URL in video generation
gen_resp = requests.post(
f"{BASE_URL}/v1/video/generations",
headers=headers,
json={
"model": "byteplus/seedance-2.0",
"content": [
{
"type": "text",
"text": "The person slowly turns their head and smiles warmly at the camera",
},
{
"type": "image_url",
"role": "reference_image",
"image_url": {"url": f"asset://{asset_id}"},
},
],
"duration": 5,
"ratio": "9:16",
},
)
gen_resp.raise_for_status()
task = gen_resp.json()
print(f"Video task created: {task['id']} (status: {task['status']})")
# Step 4: Poll video generation until complete
while task["status"] not in ("succeeded", "failed", "cancelled"):
time.sleep(5)
poll_resp = requests.get(f"{BASE_URL}/v1/video/generations/{task['id']}", headers=headers)
poll_resp.raise_for_status()
task = poll_resp.json()
print(f" Video status: {task['status']}")
if task["status"] == "succeeded":
print("Video URL:", task["content"]["video_url"])Key point: Use the asset://{asset_id} protocol URL to reference uploaded assets in video generation requests. The gateway resolves asset references to the underlying processed media automatically. You can also use direct HTTPS URLs to publicly accessible media without creating assets first.
Rate Limits & Billing
- Rate limits are enforced during create. Pomex estimates token usage and checks QoS limits before submitting the upstream task.
- Prepaid credit is reserved during create when the organization uses prepaid billing. If upstream submission or persistence fails, Pomex rolls the reservation back.
- Terminal settlement happens when a terminal snapshot is observed via Get, webhook, or delete-time merge.
- Daily quota hooks are executed around create and terminal settlement when quota management is enabled for the deployment.
- Timeouts are part of billing and lifecycle: if a queued/running task passes its effective timeout, Pomex can mark it failed with
error.code = "video_timeout".