Don't have an API key yet? Create an account → 1-month Trial plan included.

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:

  1. Submit a generation request → receive an id and a presigned S3 URL
  2. Poll GET /v1/generations/{id} (or the presigned URL) until the video is ready
  3. 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#

POST https://api.fluxpool.ai/v1/videos/generations

Request Body#

Text-to-Video#

Generate a video from a text prompt.

JSON
{
  "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.

JSON
{
  "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 IDNotes
seedance-v2Verified 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.

JSON — Initial response
{
  "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:

StatusDescription
pendingGeneration is queued.
processingModel is running.
completedVideo is ready — data[0].url is now fetchable.
failedGeneration 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":

GET https://api.fluxpool.ai/v1/generations/{id}
Python
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#

ParameterTypeRequiredDefaultDescription
modelstringYes—Model ID. See Available Models.
promptstringYes—Text description of the video to generate. Max 1000 characters.
inputsobject[]NonullPreferred 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_imagesstring[]NonullLegacy. Prefer inputs. Array of https:// URLs for image-to-video workflows, kept for backwards compatibility.
durationintegerNo5Video duration in seconds. Range depends on model.
resolutionstringNoModel defaultOutput resolution. Verified values: "480p", "720p". Higher values (e.g. "1080p") are supported by some models.
parameters.seedintegerNoRandomSeed for reproducibility when the underlying model supports seeding.
parameters.negative_promptstringNonullWhat 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:

JSON — Error Response
{
  "id": "gen_abc123xyz",
  "status": "failed",
  "error": { "code": "content_policy_violation", "message": "The prompt was flagged by the content safety filter." }
}
CodeDescription
content_policy_violationPrompt or output flagged by safety filters.
model_unavailableThe requested model is temporarily offline. Retry with an alternative model or contact support.
invalid_parametersOne or more parameters are invalid for the selected model.
insufficient_creditsYour account has insufficient credits. Top up →
CONCURRENCY_LIMIT_REACHEDHTTP 429. All of your plan's generations are running. Wait for one to finish. See Limits.
generation_timeoutThe 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.

FactorImpact
ModelHigher-quality / premium provider models cost more per generation.
DurationLonger videos cost more (roughly linear).
ResolutionHigher resolution costs more. 1080p > 720p.

Credits are deducted when generation begins. If a generation fails, credits are refunded automatically.

See full pricing details →


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.

429 response body
{
  "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 →