Create video
Submit a video generation task. The request returns 202 Accepted immediately with a task id and a polling URL — generation runs asynchronously. Poll the task or receive a webhook, then read the result with Get video status.
POST https://api.ofox.ai/v1/videosRequest parameters
frame_images[] element
Each element pins one frame of the output. frame_type is first_frame or last_frame.
{
"type": "image_url",
"image_url": { "url": "https://example.com/first.jpg" },
"frame_type": "first_frame"
}input_references[] element
Pass image / audio / video references by type — these guide subject, style, and consistency, not precise frame anchors:
{ "type": "image_url", "image_url": { "url": "https://example.com/subject.jpg" } }
{ "type": "audio_url", "audio_url": { "url": "https://example.com/voice.mp3" } }
{ "type": "video_url", "video_url": { "url": "https://example.com/ref.mp4" } }Exceeding any limit returns 400 too_many_references (see Errors).
frame_images and input_references are mutually exclusive — a single request uses one or the other, never both. Sending both returns 400 references_conflict.
real_person: Real-person reference images
For the one-step Ofox workflow, the comparison with Seedance asset enrollment, and practical retry guidance, see Real-person reference images.
Set the top-level real_person field to true when a reference image contains an identifiable real person. Ofox applies privacy-preserving preprocessing to every image in the selected reference field before submitting the generation request. The default is false, so existing requests are unchanged.
{
"model": "bytedance/seedance-2.0",
"prompt": "The person walks through a cinematic night market",
"real_person": true,
"input_references": [
{
"type": "image_url",
"image_url": { "url": "https://example.com/person.jpg" }
}
]
}You can use real_person with images in either frame_images or input_references; those two fields remain mutually exclusive. At least one image reference is required, otherwise the API returns 400 invalid_request.
Preprocessing can reduce false rejections by upstream anti-deepfake checks, but it does not bypass the provider’s content policy or guarantee acceptance. The provider may still reject the request; a rejected job is not charged, and you can correct the input or retry. See real_person preprocessing errors for input errors you can fix directly.
Generation mode (implicit)
There is no gen_mode field. The mode is inferred from which inputs you send:
Response
202 Accepted — the task is accepted with status: "pending" and a polling_url:
{
"id": "9bcf3c60-7db2-4e1a-a1b2-c3d4e5f60718",
"status": "pending",
"polling_url": "https://api.ofox.ai/v1/videos/9bcf3c60-7db2-4e1a-a1b2-c3d4e5f60718"
}Poll polling_url (or wait for a webhook) until the task reaches a terminal state — see Get video status.
Request examples
One /v1/videos schema covers every generation mode; the mode is chosen implicitly from your inputs. Each example below runs as-is.
Text to video
No frame_images / input_references → text-to-video.
# Optional: pin a provider. Omit it and the platform routes for you
# "provider": { "type": "byteplus" }
curl -X POST https://api.ofox.ai/v1/videos \
-H "Authorization: Bearer $OFOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bytedance/seedance-2.5",
"prompt": "A golden retriever running on the beach at sunset",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"generate_audio": true
}'Stackable options
The fields below are orthogonal to the generation mode — add any of them to any request body above.
Webhook (callback_url)
Receive a POST at your endpoint when the task reaches a terminal state instead of polling.
{
"model": "bytedance/seedance-2.5",
"prompt": "...",
"callback_url": "https://your-app.example/webhooks/ofox-video"
}callback_url must be HTTPS. See Webhooks for the payload and signature.