Documentation Navigation
Getting Started
API Reference
Resources
Video API
Generate video from text or images. 62 models, each priced before you spend. Async with polling and webhooks.
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
| Field | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model key (e.g. "seedance-2-fast", "kling-3-0-std", "veo-3-1-quality"). See Model Catalog. |
input | object | Yes | The fields below go inside input. |
input.prompt | string | Yes | Text description of the video to generate. |
input.image_url | string (URL) | No | First-frame image for image-to-video. |
input.last_image_url | string (URL) | No | Last-frame image, on models that support first+last frame. |
input.image_urls | string[] (URLs) | No | Reference 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_sec | number | No | Duration in seconds. Model-dependent. Default: the model's default length. |
input.aspect_ratio | string | No | "16:9", "9:16", "1:1". Default varies by model. |
input.resolution | string | No | A tier the model offers, e.g. "720p" or "1080p". See GET /v1/models/:id/params. |
confirm | boolean | No | Set to false for cost estimate only. Default: true. |
Response fields (on submit)
| Field | Type | Description |
|---|---|---|
id | string | Job ID (job_ prefix). Use with GET /v1/jobs/:id. |
status | string | "queued" on submit. |
cost.estimated_credits | integer | Estimated cost in microdollars (credits_used is 0 until the job completes). |
Response fields (on completion)
| Field | Type | Description |
|---|---|---|
id | string | Job ID. |
status | string | "completed" or "failed". |
url | string | CDN URL of the generated MP4. |
cost.credits_used | integer | Actual cost charged, in microdollars. |
cost.estimated_credits | integer | Estimated cost, in microdollars. |
cost.currency | string | Always "microdollars". |
metadata.duration | number | Video duration in seconds. |
metadata.width | integer | Video width in pixels. |
metadata.height | integer | Video height in pixels. |
metadata.fps | integer | Frames 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
| Tier | Example Model | Price | Speed | Best For |
|---|---|---|---|---|
| Standard | Kling 3.0 Standard | $0.12/s | ~60s | Marketing, product demos |
| Premium | Seedance 2.0 | $0.246/s (720p, text-to-video) | ~90s | Professional, cinematic |
| Low-cost | Vidu Q3 Turbo | $0.0924/s (720p) | ~30s | Prototyping, social clips |
Next steps
- Video Guide -- text-to-video, image-to-video, extend, restyle
- Jobs API -- poll async jobs
- Video Models -- browse all 62 video models
- Error Handling -- retries and idempotency