Video Generation
Generate videos from text prompts or input images using Fluxpool's unified API. Multiple video models available — call GET /v1/models for the current catalog.
OpenAI-compatible. This endpoint follows the OpenAI images/generations pattern with video extensions. If you've used the OpenAI SDK, you're ready.
Overview#
Video generation is asynchronous. Video models typically take 30–120 seconds to produce output. The flow is:
- Submit a generation request → receive an id and a presigned S3 URL
- Poll GET /v1/generations/{id} (or the presigned URL) until the video is ready
- Download the video from data[0].url before it expires (1 hour)
Note: Webhook delivery is on the roadmap. Until then, poll the generation-status endpoint every few seconds.
Endpoint#
Request Body#
Text-to-Video#
Generate a video from a text prompt.
{
"model": "seedance-v2",
"prompt": "A drone shot flying through cherry blossom trees, slow motion, cinematic lighting",
"duration": 5,
"resolution": "720p"
} Image-to-Video#
Animate a static image into a video. Pass a reference image URL in the input_images array alongside (or instead of) prompt. The newer inputs field accepts the same URLs plus inline base64 data-URIs — see Image-to-Image for the shape.
{
"model": "seedance-v2",
"prompt": "Camera slowly zooms out, leaves rustling in wind",
"input_images": ["https://your-bucket.s3.amazonaws.com/input-image.png"],
"duration": 5,
"resolution": "720p"
} Not all models support image-to-video. Check the model's advertised capabilities via GET /v1/models.
Available Models#
Video models are discovered via GET /v1/models. One verified example to get you started:
| Model ID | Notes |
|---|---|
| seedance-v2 | Verified example. Confirmed working with resolution: "720p", duration: 5. |
Other video model IDs are also live: seedance-v2.5 (Seedance 2.5), seedance-v2-fast (Seedance 2.0 Fast), seedance-v2-mini (Seedance 2.0 Mini), wan3.0-video-prime (Wan 3.0 Prime), wan3.0-video (Wan 3.0), wan2.7-t2v (Wan Video 2.7), wan2.7-r2v (Wan Video 2.7 · Reference), runway-gen4.5 (Runway Gen4.5). Full catalog: Browse all models →
Response#
A successful POST returns immediately with a generation id, a top-level status of "pending", and a data[] array holding a presigned S3 URL that becomes fetchable once the video is ready.
{
"created": 1785845810,
"id": "6dcc89ce-964e-466e-8100-ba2bdfb6d07c",
"status": "pending",
"model": "seedance-v2",
"type": "video",
"data": [
{
"url": "https://fluxpool-output.s3.ap-southeast-1.amazonaws.com/...?X-Amz-...",
"generation_id": "6dcc89ce-964e-466e-8100-ba2bdfb6d07c",
"status": "pending",
"model": "seedance-v2",
"revised_prompt": null
}
]
} Possible status values:
| Status | Description |
|---|---|
| pending | Generation is queued. |
| processing | Model is running. |
| completed | Video is ready — data[0].url is now fetchable. |
| failed | Generation failed. See error field. |
The presigned URL is valid for 1 hour. Persist the video before it expires.
Polling for Results#
Poll the shared generation-status endpoint until status is "completed":
import time
import requests
API_KEY = "fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
headers = {"Authorization": f"Bearer {API_KEY}"}
# Submit
submit = requests.post(
"https://api.fluxpool.ai/v1/videos/generations",
headers=headers,
json={"model": "seedance-v2", "prompt": "A koi fish transforming into a phoenix, slow motion", "resolution": "720p", "duration": 5}
).json()
gen_id = submit["id"]
# Poll
while True:
status = requests.get(f"https://api.fluxpool.ai/v1/generations/{gen_id}", headers=headers).json()
if status["status"] == "completed":
print(status["data"][0]["url"])
break
time.sleep(3) Polling interval: Wait at least 3 seconds between polls. Alternatively, poll the presigned S3 URL directly with GET and Range: bytes=0-0 (S3 rejects HEAD on presigned GETs).
Webhooks (coming soon)#
Webhook delivery is not shipped yet — polling is the supported pattern today. Track progress on the Async & polling page.
Code Examples#
# The OpenAI SDK doesn't have a videos helper — call the endpoint directly.
import requests
response = requests.post(
"https://api.fluxpool.ai/v1/videos/generations",
headers={"Authorization": "Bearer fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"},
json={
"model": "seedance-v2",
"prompt": "A cyberpunk city street in heavy rain, neon reflections, cinematic",
"duration": 5,
"resolution": "720p"
}
).json()
print(f"Generation ID: {response['id']}")
print(f"Poll URL: {response['data'][0]['url']}") Parameters Reference#
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| model | string | Yes | — | Model ID. See Available Models. |
| prompt | string | Yes | — | Text description of the video to generate. Max 1000 characters. |
| inputs | object[] | No | null | Preferred shape. Each item is {type, source, value}. source: "url" for hosted images, source: "data" for base64 data-URIs (uploaded inline; ~4.5MB decoded cap per item). |
| input_images | string[] | No | null | Legacy. Prefer inputs. Array of https:// URLs for image-to-video workflows, kept for backwards compatibility. |
| duration | integer | No | 5 | Video duration in seconds. Range depends on model. |
| resolution | string | No | Model default | Output resolution. Verified values: "480p", "720p". Higher values (e.g. "1080p") are supported by some models. |
| parameters.seed | integer | No | Random | Seed for reproducibility when the underlying model supports seeding. |
| parameters.negative_prompt | string | No | null | What to avoid in the generation. Ignored by models that don't support it. |
Error Handling#
If a generation fails, the response status will be "failed" with an error object:
{
"id": "gen_abc123xyz",
"status": "failed",
"error": { "code": "content_policy_violation", "message": "The prompt was flagged by the content safety filter." }
} | Code | Description |
|---|---|
| content_policy_violation | Prompt or output flagged by safety filters. |
| model_unavailable | The requested model is temporarily offline. Retry with an alternative model or contact support. |
| invalid_parameters | One or more parameters are invalid for the selected model. |
| insufficient_credits | Your account has insufficient credits. Top up → |
| CONCURRENCY_LIMIT_REACHED | HTTP 429. All of your plan's generations are running. Wait for one to finish. See Limits. |
| generation_timeout | The generation exceeded the maximum processing time. Retry. |
Cost & Billing#
Each video generation deducts credits from your account balance. Cost varies by model, duration, and resolution.
| Factor | Impact |
|---|---|
| Model | Higher-quality / premium provider models cost more per generation. |
| Duration | Longer videos cost more (roughly linear). |
| Resolution | Higher resolution costs more. 1080p > 720p. |
Credits are deducted when generation begins. If a generation fails, credits are refunded automatically.
Limits#
Generations running at once. Each plan sets how many generations can be in progress at the same time for your account, whether they come from the app, the API or an MCP client. Without an active plan, your credits still work, at the lowest plan's limit.
| Plan | Concurrent generations |
|---|---|
| 1-month Trial | 10 |
| Base | 10 |
| Pro | 15 |
| Growth | 20 |
| Hero | 25 |
| Enterprise | Custom |
Connected apps. An app or agent you connect through the MCP connector (OAuth) has its own daily credit limit, 500 by default, over a rolling 24 hours. Change it or pause the connection in the app under API / MCP Access, Connected apps. API keys have no daily limit.
| Status | Code | When |
|---|---|---|
| 429 | CONCURRENCY_LIMIT_REACHED | Your plan's generations are all running. Wait for one to finish. |
| 429 | CONNECTION_LIMIT_REACHED | This connected app would go over its daily credit limit. The message says how much it has used and what the generation needs. |
| 403 | CONNECTION_PAUSED | This connected app is paused. Resume it to generate again. |
Every error uses the same body. Branch on error.code; the message is for people and may change.
{
"error": {
"message": "You have 10 generations running and your plan allows 10 at once. Wait for one to finish, or upgrade for more.",
"type": "invalid_request_error",
"param": null,
"code": "CONCURRENCY_LIMIT_REACHED"
}
}
Through the MCP server, the same object comes back as the text of the create_generation tool result.
The API does not send rate-limit headers.
Need higher limits? Contact us →