API reference · Media
Video generation
Start rendering a short clip — async, poll for the result.
Video is slow by nature (one to five minutes, longer for 20–30 s takes), so this endpoint is asynchronous: the call charges, starts the render and answers 202 immediately with a job id. Poll GET /v1/videos/generations/{id} every few seconds until status is succeeded or failed.
The money guarantee is unchanged: credits are charged at submit, and a render that fails — or never completes within its engine's window — refunds itself automatically. You only ever pay for a delivered clip.
Pick THE engine with model: Seedance, Veo, Sora, Kling, Hailuo, Wan, Runway and Grok Imagine, plus Motion One, our own uncensored engine. The third-party engines are moderated upstream by their providers; a refused prompt or picture answers 400 content_blocked and bills nothing (the message says what was refused: the prompt, the starting picture, or the clip the engine rendered and then held back, refunded), and a picture the engine cannot read answers 400 invalid_image. Premium engines are plan-gated (403 plan_required before any charge) — GET /v1/engines lists what each engine takes and what your plan unlocks.
Engines are billed per second of clip, by resolution and — where it costs extra upstream — sound; a few also bill per picture sent. GET /v1/models quotes every rate; the response's usage.credits_spent is always the exact charge. Every knob is clamped to the engine BEFORE pricing: an unserved resolution renders (and bills) at the engine's default, a non-native aspect at its nearest native ratio.
Your cast and elements (elements) ride as numbered reference pictures on engines that read them (references in /v1/engines — up to six on Seedance): each character's look sheet holds its identity, @Name in the prompt binds to it. A start frame (references[0], on engines with image→video) takes over the clip instead — the cast then rides as text. With sound on, a cast member's voice rides along: Seedance 2.x and Hailuo 3 hear the voice sample itself (voice in /v1/engines), the others get a description of it. Write dialogue in quotes: @Mina says "we made it".
The finished clip is persisted to your library and served as a short-lived signed URL (or store: true for a permanent public URL, 2 credits / started 10MB on top). private: true writes nothing to your library: the clip is served through a temporary signed URL and its file is deleted 30 minutes after upload — the poll response carries expires_at and deletes_in_seconds.
Request body
The shot: subject, action, dialogue in quotes. @Name mentions bind to your cast and elements.
Video engine id — see GET /v1/models (kind video) and GET /v1/engines. Default eroq-motion-one (every account). Retired ids (seedance-1-lite, kling-2-5-turbo, veo-3-fast, hailuo-02…) render on the model that replaced them. An engine not live on this deployment answers 503 model_unavailable.
Clip length, 1–30. Your PLAN caps it (10s pay-as-you-go, 15/20/30s on Hobby/Creator/Studio+) and the engine's grid snaps it (e.g. Veo 4/6/8, Sora 4–20 by 4, Seedance 2.5 4–30) — billing always matches the clip that renders.
Legacy shorthand (3s/5s/8s/10s) — ignored when seconds is present.
480p, 720p, 768p, 1080p or 2K — each engine serves a subset (see /v1/engines resolutions); anything else renders at the engine's default. Priced per second per resolution.
HD quality (eroq-motion-one only): false runs the full 20-step base model with no turbo distillation instead of the default 8-step turbo — sharper and temporally steadier, slower, and billed at the engine's full rate (30 vs 12 credits/second). A 5-second HD clip is 150 credits. Ignored by every other engine.
16:9, 9:16, 1:1, 21:9, 4:3 or 3:4 — a native parameter on every engine that has it (/v1/engines aspects); a ratio the engine lacks renders at its nearest native one. retain (frame-driven engines, when you send a first frame) makes the canvas follow that frame's own ratio — the picture is never stretched.
Render the soundtrack with the picture — dialogue, ambience, effects (engines flagged in /v1/engines audio). Default on where supported; some engines bill sound per second.
Pictures. On engines with image→video (/v1/engines startFrame) the first one IS the first frame; elsewhere they join the reference pictures. URLs AND base64 data:image/... URIs are accepted — the studio sends a PASTED frame as a data URI; our own ComfyUI engine reads it inline, and on the upstream engines it is uploaded to our Store first.
frame (default) or identity. With identity every picture in references rides as a reference picture — who or what stars, the engine builds the scene around it — never as the first frame (engines with /v1/engines references > 0). Seedance refuses pictures of real-looking people.
END-frame picture — engines flagged in /v1/engines endFrame (Seedance, Veo, Kling, Hailuo, and our own Motion One) render the journey to it. Ignored elsewhere. URL or base64 data:image/....
Cast and ingredients, in order — characters as char:<id>, elements by id, previous image renders as creation:<id>, storage uploads as upload:<id>. Their look sheets/photos ride as numbered reference pictures up to the engine's budget (the rest ride as text); characters must carry an accepted look sheet or the call answers 422 sheet_required (see /v1/sheets).
Reproducibility seed — engines flagged in /v1/engines seed; ignored elsewhere.
What to steer away from — native on engines flagged in /v1/engines negative (Veo, Kling); ignored elsewhere.
Camera move, 24 in the library: static, slow-pan, push-in, tracking, orbit, handheld, close-up, wide, pull-back, dolly-zoom, crane-up, crane-down, whip-pan, fpv, aerial-pullback, pov, snorricam, bullet-time, slider, roll, dutch-angle, overhead, crash-zoom, steadicam.
Film look: noir, documentary, music-video, commercial, arthouse, horror, romance.
Period look, 1920s → futuristic.
Pacing: calm, dreamy, dynamic, tense, chaotic.
Gear look: 35mm, imax, vhs, drone, gopro, cctv, smartphone.
Glass: clean-sharp, anamorphic, vintage-anamorphic, soft-portrait, macro, fisheye.
Depth of field: f1-4 (wide open), f4, f11 (deep focus).
Lighting: silhouette, practicals, window-light, overhead-fall, contre-jour, soft-cross, neon-glow.
Color: neon-noir, candy-pop, film-warm, nostalgic-blue, emerald, pastel-dawn, monochrome, sepia, industrial-fog, twilight, blood-gold, bleach-bypass.
Unlock a permanent public static URL for the clip. +2 credits per started 10MB. Default false.
Library folder the clip lands in — one of yours (GET /v1/folders). Omitted = the Library root; an unknown id answers 404 folder_not_found before anything is billed.
A flow to run on the clip once it lands — one of your flows (GET /v1/flows) that starts « After a render » of clips. Checked before anything is billed (403 plan_required below the plan flows take). Ignored by private renders. See Flows.
Do not retain on our side: the clip is NOT saved to your library. A video is served through a temporary signed URL and its file is deleted 30 minutes after upload (expires_at in the response); images are returned inline once. No creation row, nothing kept in our database. (Prompt retention upstream follows the per-model privacy value — see /v1/engines.) Default false.
Advanced mode (eroq-motion-one only): the prompt rides RAW — no director rack folding, no directives, no enhancement. 400 advanced_requires_comfy on any other model.
curl https://eroq.ai/v1/videos/generations \
-H "Authorization: Bearer $EROQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2-0-mini",
"prompt": "@Mina crosses the neon rooftop and says \"we made it\"",
"seconds": 5,
"resolution": "480p",
"aspect": "9:16",
"shot": "push-in",
"lighting": "neon-glow",
"elements": [
"char:3f1c…"
]
}'Response
{
"id": "b7e6c2d4-…",
"object": "video.generation",
"status": "processing",
"created": 1756118400,
"model": "seedance-2-0-mini",
"duration": "5s",
"poll": "/v1/videos/generations/b7e6c2d4-…",
"usage": { "credits_spent": 45, "credits_remaining": 887 }
}