Skip to main content

Video API

Generate video from text or images. 62 models, each priced before you spend. Async with polling and webhooks.

Async API. Video generation is asynchronous. You submit a job and poll GET /v1/jobs/:id for the result, or use a webhook callback.

POST /v1/generations/video

Submit a video generation job. Returns a job ID for async polling.

Request body

FieldTypeRequiredDescription
modelstringYesModel key (e.g. "seedance-2-fast", "kling-3-0-std", "veo-3-1-quality"). See Model Catalog.
inputobjectYesThe fields below go inside input.
input.promptstringYesText description of the video to generate.
input.image_urlstring (URL)NoFirst-frame image for image-to-video.
input.last_image_urlstring (URL)NoLast-frame image, on models that support first+last frame.
input.image_urlsstring[] (URLs)NoReference images, on models that support references. The mode (text-to-video, first frame, first+last frame, references) is inferred from which image fields you send.
input.duration_secnumberNoDuration in seconds. Model-dependent. Default: the model's default length.
input.aspect_ratiostringNo"16:9", "9:16", "1:1". Default varies by model.
input.resolutionstringNoA tier the model offers, e.g. "720p" or "1080p". See GET /v1/models/:id/params.
confirmbooleanNoSet to false for cost estimate only. Default: true.

Response fields (on submit)

FieldTypeDescription
idstringJob ID (job_ prefix). Use with GET /v1/jobs/:id.
statusstring"queued" on submit.
cost.estimated_creditsintegerEstimated cost in microdollars (credits_used is 0 until the job completes).

Response fields (on completion)

FieldTypeDescription
idstringJob ID.
statusstring"completed" or "failed".
urlstringCDN URL of the generated MP4.
cost.credits_usedintegerActual cost charged, in microdollars.
cost.estimated_creditsintegerEstimated cost, in microdollars.
cost.currencystringAlways "microdollars".
metadata.durationnumberVideo duration in seconds.
metadata.widthintegerVideo width in pixels.
metadata.heightintegerVideo height in pixels.
metadata.fpsintegerFrames per second.

Code examples

curl

curl -X POST https://api.fairstack.ai/v1/generations/video \
  -H "Authorization: Bearer $FAIRSTACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "vidu-q3-turbo-t2v",
    "input": {
      "prompt": "A golden retriever running on a beach at sunset, slow motion",
      "duration_sec": 5
    }
  }'

Submit response:

{
  "id": "job_xyz789",
  "status": "queued",
  "cost": {
    "credits_used": 0,
    "estimated_credits": 462000,
    "currency": "microdollars"
  }
}

Python

from fairstack import FairStack

client = FairStack(api_key="fs_live_YOUR_KEY")

# Submit async video generation
job = client.generate.video(
    model="vidu-q3-turbo-t2v",
    prompt="A golden retriever running on a beach at sunset, slow motion",
    duration=5
)

# Poll for result
result = job.wait()  # blocks until complete
print(result.url)    # https://media.fairstack.ai/video/...
print(result.cost)   # $0.462

Node.js

import { FairStack } from "fairstack";

const client = new FairStack({ apiKey: "fs_live_YOUR_KEY" });

// Submit async video generation
const job = await client.generate.video({
  model: "vidu-q3-turbo-t2v",
  prompt: "A golden retriever running on a beach at sunset, slow motion",
  duration: 5,
});

// Poll for result
const result = await job.wait();
console.log(result.url);   // https://media.fairstack.ai/video/...
console.log(result.cost);  // { credits_used: 462000, estimated_credits: 462000, currency: "microdollars" }

Completed response

{
  "id": "job_xyz789",
  "status": "completed",
  "url": "https://media.fairstack.ai/video/.../output.mp4",
  "model": "vidu-q3-turbo-t2v",
  "modality": "video",
  "cost": {
    "credits_used": 462000,
    "estimated_credits": 462000,
    "currency": "microdollars"
  },
  "metadata": {
    "width": 1280,
    "height": 720,
    "duration": 5,
    "fps": 24
  }
}

Cost units. Every value inside cost is an integer in microdollars, as flagged by currency: "microdollars". The conversion is 1 USD = 1,000,000 microdollars. So credits_used: 30000 = $0.03, and the example above (462000) = $0.462. The field is named credits_used for backward compatibility with existing SDKs — always read it as microdollars and convert as needed.

Cost estimation

Set confirm: false to get the exact cost without submitting the job.

curl -X POST https://api.fairstack.ai/v1/generations/video \
  -H "Authorization: Bearer $FAIRSTACK_API_KEY" \
  -d '{
    "model": "vidu-q3-turbo-t2v",
    "input": { "prompt": "test", "duration_sec": 5 },
    "confirm": false
  }'

# Response (no video generated, no charge):
# { "cost": { "credits_used": 0, "estimated_credits": 462000, "currency": "microdollars" } }

Image-to-video

Many models support image-to-video generation. Include a source image URL:

{
  "model": "seedance-2-fast",
  "input": {
    "prompt": "Camera slowly zooms in, soft wind blowing hair",
    "image_url": "https://example.com/photo.jpg",
    "duration_sec": 5,
    "aspect_ratio": "16:9"
  }
}

Webhooks

Instead of polling, register a webhook endpoint once (admin key) and receive a POST when each generation completes or fails:

curl -X POST https://api.fairstack.ai/v1/webhooks \
  -H "Authorization: Bearer $FAIRSTACK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/hooks/fairstack",
    "events": ["generation.completed", "generation.failed"]
  }'

See the Jobs API for the webhook payload shape and signature verification.

Quality tiers

TierExample ModelPriceSpeedBest For
StandardKling 3.0 Standard$0.12/s~60sMarketing, product demos
PremiumSeedance 2.0$0.246/s (720p, text-to-video)~90sProfessional, cinematic
Low-costVidu Q3 Turbo$0.0924/s (720p)~30sPrototyping, social clips

Next steps