doteb
Features

Video Generation

Generate videos with an OpenAI-compatible async API and signed completion callbacks

Video Generation

doteb supports asynchronous video generation through an OpenAI-compatible POST /v1/videos flow.

Currently available models:

  • Veo 3.1 through avalanche (1080p, 4k) and google-vertex (720p, 1080p, 4k)
  • Seedance 2.0, Seedance 2.0 Fast, and Seedance 1.5 Pro through bytedance (720p, 1080p)

You can find the current list of video-capable models on our models page with the video filter enabled or programmatically through the /v1/models endpoint.

What Works Today

  • POST /v1/videos
  • GET /v1/videos/{video_id}
  • GET /v1/videos/{video_id}/content
  • Optional signed callbacks with callback_url and callback_secret

Request Format

doteb currently supports a focused subset of the OpenAI video API.

Supported fields

FieldTypeRequiredDescription
modelstringyesAny video-capable model from the filtered models page
promptstringyesText prompt for the video
secondsnumberyesDuration in seconds. Supported values depend on the model (see below)
sizestringnowidthxheight, limited to the sizes supported by the selected model and provider
audiobooleannoWhether to include audio in the output (default true). Only honored when the model supports both audio and silent output
imageobjectnoOptional first frame for image-to-video generation
last_frameobjectnoOptional ending frame when image is provided
reference_imagesarraynoOne to three provider-specific image inputs
input_referenceobjectnoAlias for one or more reference_images
reference_videosarraynoOne to three reference video HTTPS URLs (Seedance 2.0 only, see below)
reference_audiosarraynoOne to three reference audio HTTPS URLs (Seedance 2.0 only, see below)
callback_urlstringnodoteb extension for completion webhooks
callback_secretstringnodoteb extension used to sign webhook deliveries

Sizes and durations by model

Model familyProviderSupported sizesSupported durations
Veo 3.1google-vertex1280x720, 720x1280, 1920x1080, 1080x1920, 3840x2160, 2160x38404, 6, 8, 10
Veo 3.1avalanche1920x1080, 1080x1920, 3840x2160, 2160x38408
Seedance 2.0 / 2.0 Fast / 1.5 Probytedance1280x720, 720x1280, 1920x1080, 1080x19205, 10

Requests return 400 when the selected provider cannot serve the requested size or seconds. Seedance derives aspect_ratio from the requested size (16:9 for landscape, 9:16 for portrait).

Reference-guided generation (Seedance 2.0)

Seedance 2.0 (seedance-2-0, seedance-2-0-fast) can generate a video that is guided by reference images, videos, and audio — sometimes called omni-reference. You attach references as top-level fields in the same POST /v1/videos payload; the gateway forwards each one to the provider tagged with the correct role, so you don't set roles yourself.

Reference typePayload fieldCountAccepted inputAvailable on
Imagereference_images (input_reference alias)1–3HTTPS URL or base64 data URLSeedance 2.0, Veo 3.1 (google-vertex, avalanche)
Videoreference_videos1–3HTTPS URL onlySeedance 2.0
Audioreference_audios1–3HTTPS URL onlySeedance 2.0

Each list item accepts either a bare URL string or an object form:

  • reference_images: "https://…/subject.png" or { "image_url": "https://…/subject.png" }
  • reference_videos: "https://…/motion.mp4" or { "video_url": "https://…/motion.mp4" }
  • reference_audios: "https://…/track.mp3" or { "audio_url": "https://…/track.mp3" }

You can mix all three reference types in one request. The prompt can be a light instruction (for example "adapt this to show more detail") — the references drive the result.

Rules and limits

  • HTTPS only for video and audio. reference_videos and reference_audios must be publicly reachable HTTPS URLs (the provider fetches them). base64 data URLs are rejected for video/audio; images may be HTTPS URLs or base64 data URLs.
  • Reference video resolution. Seedance requires reference video frames to be at least ~409,600 pixels (roughly 480p or larger). Low-resolution clips such as 360p are rejected with a 400.
  • Not combinable with frames. Reference inputs (reference_images, reference_videos, reference_audios) cannot be combined with the first/last frame inputs (image, last_frame).
  • Provider scope. Reference videos and audio are only supported on Seedance 2.0 models; sending them to other models returns a 400.
  • Moderation still applies. The output is subject to the provider's content moderation. Blocked generations finish as failed and are logged with a content_filter finish reason.

Examples

Reference images only (subjects / style):

curl -X POST "https://api.doteb.com/v1/videos" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-0",
    "prompt": "The subject walks through a neon-lit market at night",
    "seconds": 5,
    "size": "1280x720",
    "reference_images": [
      { "image_url": "https://example.com/subject.png" },
      { "image_url": "https://example.com/style.png" }
    ]
  }'

Reference video only (motion / scene — let the clip drive the output):

curl -X POST "https://api.doteb.com/v1/videos" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-0",
    "prompt": "adapt this to show more detail",
    "seconds": 5,
    "size": "1280x720",
    "reference_videos": ["https://example.com/reference-motion.mp4"]
  }'

All three reference types combined:

curl -X POST "https://api.doteb.com/v1/videos" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-0",
    "prompt": "The subject performs the choreography from the reference video",
    "seconds": 5,
    "size": "1280x720",
    "reference_images": [
      { "image_url": "https://example.com/subject.png" }
    ],
    "reference_videos": [
      "https://example.com/reference-motion.mp4"
    ],
    "reference_audios": [
      "https://example.com/reference-track.mp3"
    ]
  }'

Not supported yet

  • multipart uploads
  • n values other than 1
  • remix/list/delete video endpoints

Create a Video

Video generation requires at least $1.00 in available organization credits before the job is submitted upstream.

Pricing is per second of generated video. For Seedance, enabling audio can increase the per-second rate on models that price audio and video separately.

Veo 3.1:

ModelProviderSupported sizesPrice
veo-3.1-generate-previewgoogle-vertex1280x720, 720x1280, 1920x1080, 1080x1920$0.40 / second
veo-3.1-fast-generate-previewgoogle-vertex1280x720, 720x1280, 1920x1080, 1080x1920$0.15 / second
veo-3.1-generate-previewgoogle-vertex3840x2160, 2160x3840$0.60 / second
veo-3.1-fast-generate-previewgoogle-vertex3840x2160, 2160x3840$0.35 / second
veo-3.1-generate-previewavalanche1920x1080, 1080x1920$0.40 / second
veo-3.1-fast-generate-previewavalanche1920x1080, 1080x1920$0.15 / second
veo-3.1-generate-previewavalanche3840x2160, 2160x3840$0.60 / second
veo-3.1-fast-generate-previewavalanche3840x2160, 2160x3840$0.35 / second

Seedance (ByteDance):

ModelProviderResolutionWith audioVideo only
seedance-2-0bytedance720p$0.1512 / second$0.1512 / second
seedance-2-0bytedance1080p$0.3402 / second$0.3402 / second
seedance-2-0-fastbytedance720p$0.121 / second$0.121 / second
seedance-2-0-fastbytedance1080p$0.2722 / second$0.2722 / second
seedance-1-5-probytedance720p$0.05184 / second$0.02592 / second
seedance-1-5-probytedance1080p$0.1166 / second$0.05832 / second
curl -X POST "https://api.doteb.com/v1/videos" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1-generate-preview",
    "prompt": "A cinematic aerial shot flying above a rainforest waterfall at sunrise",
    "seconds": 8,
    "size": "1920x1080"
  }'

Example response:

{
	"id": "v_123",
	"object": "video",
	"model": "veo-3.1-generate-preview",
	"status": "queued",
	"progress": 0,
	"created_at": 1773600000,
	"completed_at": null,
	"expires_at": null,
	"error": null
}

Retrieve Job Status

curl "https://api.doteb.com/v1/videos/v_123" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY"

Typical statuses:

  • queued
  • in_progress
  • completed
  • failed
  • canceled
  • expired

avalanche requests for 1080p and 4k stay in_progress until the upgraded output is ready. The gateway keeps polling the upstream upgrade endpoints and only marks the job completed once the requested resolution is available.

google-vertex follows Vertex AI's long-running operation flow. The gateway submits Veo generation with predictLongRunning, polls with fetchPredictOperation, and streams the final bytes through the gateway content endpoint once the operation is done.

bytedance uses the ModelArk /contents/generations/tasks endpoint. The gateway submits the job, polls the upstream task status, and exposes the final video bytes through the gateway content endpoint once the task succeeds.

Download the Video

Once the job is complete, stream the resulting video bytes from the content endpoint:

curl "https://api.doteb.com/v1/videos/v_123/content" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  --output video.mp4

Signed Callbacks

doteb can notify your application when the job reaches a terminal state.

curl -X POST "https://api.doteb.com/v1/videos" \
  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1-fast-generate-preview",
    "prompt": "A slow-motion close-up of waves crashing against black volcanic rock",
    "seconds": 8,
    "callback_url": "https://example.com/webhooks/video",
    "callback_secret": "whsec_your_secret_here"
  }'

Delivery behavior

  • Callbacks are sent only for terminal states in v1
  • Event types are video.completed and video.failed
  • Deliveries retry with exponential backoff on network errors, timeouts, and non-2xx responses
  • Each attempt is recorded internally in the webhook delivery log table

Headers

  • webhook-id
  • webhook-timestamp
  • webhook-signature

Signature format

doteb signs the string:

{webhook-id}.{webhook-timestamp}.{raw-request-body}

using HMAC-SHA256 with your callback_secret, then sends:

webhook-signature: v1,{base64_signature}

Verification example

import { createHmac, timingSafeEqual } from "node:crypto";

function verifyWebhook(
	body: string,
	webhookId: string,
	webhookTimestamp: string,
	webhookSignature: string,
	secret: string,
) {
	const expected = createHmac("sha256", secret)
		.update(`${webhookId}.${webhookTimestamp}.${body}`)
		.digest("base64");

	const provided = webhookSignature.replace(/^v1,/, "");

	return timingSafeEqual(Buffer.from(expected), Buffer.from(provided));
}

How is this guide?

Last updated on

On this page

Ready for production?

Ship to production with SSO, audit logs, spend controls, and guardrails your security team will approve.

Explore Enterprise