
Fal Api Reference
- 52 installs
- 50 repo stars
- Updated June 18, 2026
- josiahsiegel/claude-plugin-marketplace
Helps with backend & apis tasks.
About
fal-api-reference is a Claude Code skill for backend & apis. It helps solo builders move faster with AI-assisted development.
- fal-api-reference
- Backend & APIs
- AI-coding skill
Fal Api Reference by the numbers
- 52 all-time installs (skills.sh)
- +4 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #3,221 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill fal-api-referenceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 52 |
|---|---|
| repo stars | ★ 50 |
| Last updated | June 18, 2026 |
| Repository | josiahsiegel/claude-plugin-marketplace ↗ |
What it does
Helps with backend & apis tasks.
Files
Quick Reference
| Method | Use Case | Code |
|---|---|---|
fal.subscribe() | Queue-based (recommended) | await fal.subscribe("model", { input }) |
fal.run() | Fast endpoints (<30s) | await fal.run("model", { input }) |
fal.stream() | Progressive output | for await (const event of stream) {} |
fal.realtime.connect() | WebSocket interactive | fal.realtime.connect("model", callbacks) |
| Queue Method | Purpose |
|---|---|
fal.queue.submit() | Submit job, get request_id |
fal.queue.status() | Check job status |
fal.queue.result() | Get completed result |
fal.queue.cancel() | Cancel pending job |
| Auth | Header | Format |
|---|---|---|
| API Key | Authorization | Key YOUR_FAL_KEY |
When to Use This Skill
Use for API integration fundamentals:
- Setting up fal.ai client in JavaScript/TypeScript
- Setting up fal_client in Python
- Choosing between subscribe, run, and stream methods
- Implementing webhook callbacks
- Uploading files to fal.media CDN
Related skills:
- For model selection: see
fal-model-guide - For performance optimization: see
fal-optimization - For custom model deployment: see
fal-serverless-guide
---
fal.ai API Reference
Complete API reference for fal.ai client libraries and REST endpoints.
Client Libraries
JavaScript/TypeScript (@fal-ai/client)
npm install @fal-ai/clientConfiguration
import { fal } from "@fal-ai/client";
// Configure credentials (reads FAL_KEY from environment by default)
fal.config({
credentials: process.env.FAL_KEY,
// Optional: custom proxy URL for browser apps
proxyUrl: "https://your-server.com/api/fal-proxy"
});Core Methods
fal.subscribe(endpoint, options) Queue-based execution with automatic polling. Recommended for most use cases.
const result = await fal.subscribe("fal-ai/flux/dev", {
input: {
prompt: "A beautiful landscape"
},
logs: true,
pollInterval: 1000, // Poll every second (default: 1000)
onQueueUpdate: (update) => {
// update.status: "IN_QUEUE" | "IN_PROGRESS" | "COMPLETED"
if (update.status === "IN_PROGRESS") {
update.logs?.forEach(log => console.log(log.message));
}
}
});fal.run(endpoint, options) Direct/synchronous execution. Use only for fast endpoints (< 30 seconds).
const result = await fal.run("fal-ai/fast-sdxl", {
input: { prompt: "A cat" }
});fal.stream(endpoint, options) Server-sent events for progressive output.
const stream = await fal.stream("fal-ai/flux/dev", {
input: { prompt: "A landscape" }
});
for await (const event of stream) {
console.log("Progress:", event);
}
const finalResult = await stream.done();fal.realtime.connect(endpoint, callbacks) WebSocket connection for real-time interactive applications.
const connection = fal.realtime.connect("fal-ai/lcm-sd15-i2i", {
connectionKey: "unique-session-id",
throttleInterval: 128, // Debounce inputs (ms)
onResult: (result) => console.log("Generated:", result),
onError: (error) => console.error("Error:", error),
onOpen: () => console.log("Connected"),
onClose: () => console.log("Disconnected")
});
// Send inputs
connection.send({
prompt: "A cute cat",
image_url: "https://example.com/base.jpg"
});
// Close when done
connection.close();Queue Methods
Manual queue management for advanced control.
// Submit to queue
const { request_id } = await fal.queue.submit("fal-ai/flux/dev", {
input: { prompt: "Test" },
webhookUrl: "https://your-server.com/webhook" // Optional
});
// Check status
const status = await fal.queue.status("fal-ai/flux/dev", {
requestId: request_id,
logs: true
});
// status.status: "IN_QUEUE" | "IN_PROGRESS" | "COMPLETED"
// Get result (blocks until complete)
const result = await fal.queue.result("fal-ai/flux/dev", {
requestId: request_id
});
// Cancel request
await fal.queue.cancel("fal-ai/flux/dev", {
requestId: request_id
});Storage Methods
Upload files to fal.media CDN.
// Upload File object
const file = new File([blob], "image.png", { type: "image/png" });
const url = await fal.storage.upload(file);
// Upload from URL
const response = await fetch("https://example.com/image.jpg");
const blob = await response.blob();
const url = await fal.storage.upload(new File([blob], "image.jpg"));Python (fal-client)
pip install fal-clientSynchronous API
import fal_client
# Simple run
result = fal_client.run(
"fal-ai/flux/dev",
arguments={
"prompt": "A beautiful landscape",
"image_size": "landscape_16_9"
}
)
# Subscribe with status updates
def on_update(update):
if isinstance(update, fal_client.InProgress):
for log in update.logs:
print(log["message"])
result = fal_client.subscribe(
"fal-ai/flux/dev",
arguments={"prompt": "Test"},
with_logs=True,
on_queue_update=on_update
)
# Manual queue management
handler = fal_client.submit(
"fal-ai/flux/dev",
arguments={"prompt": "Test"}
)
print(f"Request ID: {handler.request_id}")
status = handler.status() # Check status
result = handler.get() # Block until completeAsync API
import asyncio
import fal_client
async def generate():
# Async run
result = await fal_client.run_async(
"fal-ai/flux/dev",
arguments={"prompt": "Test"}
)
# Async subscribe
result = await fal_client.subscribe_async(
"fal-ai/flux/dev",
arguments={"prompt": "Test"},
with_logs=True
)
# Async queue management
handler = await fal_client.submit_async(
"fal-ai/flux/dev",
arguments={"prompt": "Test"}
)
status = await handler.status_async()
result = await handler.get_async()
return result
result = asyncio.run(generate())File Upload
# Upload file from path
url = fal_client.upload_file("path/to/image.png")
# Upload bytes
with open("image.png", "rb") as f:
url = fal_client.upload(f.read(), "image/png")
# Encode as data URL (small files only)
data_url = fal_client.encode_file("small_image.png")REST API
Base URLs
| Purpose | URL Pattern |
|---|---|
| Queue Submit | https://queue.fal.run/{model_id} |
| Queue Status | https://queue.fal.run/{model_id}/requests/{request_id}/status |
| Queue Result | https://queue.fal.run/{model_id}/requests/{request_id} |
| Queue Cancel | https://queue.fal.run/{model_id}/requests/{request_id}/cancel |
| Direct Run | https://fal.run/{model_id} |
| WebSocket | wss://fal.run/{model_id} |
Authentication
Authorization: Key YOUR_FAL_KEYQueue Workflow
# 1. Submit to queue
curl -X POST "https://queue.fal.run/fal-ai/flux/dev" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A beautiful landscape",
"image_size": "landscape_16_9"
}'
# Response:
# {
# "request_id": "abc123-def456",
# "status": "IN_QUEUE",
# "queue_position": 0
# }
# 2. Check status
curl "https://queue.fal.run/fal-ai/flux/dev/requests/abc123-def456/status" \
-H "Authorization: Key $FAL_KEY"
# Response (in progress):
# {
# "status": "IN_PROGRESS",
# "logs": [{"message": "Loading model...", "timestamp": "..."}]
# }
# Response (completed):
# {
# "status": "COMPLETED"
# }
# 3. Get result
curl "https://queue.fal.run/fal-ai/flux/dev/requests/abc123-def456" \
-H "Authorization: Key $FAL_KEY"
# Response:
# {
# "images": [{"url": "https://fal.media/...", "width": 1024, "height": 576}],
# "seed": 12345,
# "prompt": "A beautiful landscape"
# }Webhooks
Submit with webhook URL to receive results via POST:
curl -X POST "https://queue.fal.run/fal-ai/flux/dev" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Test",
"webhook_url": "https://your-server.com/webhook"
}'Webhook payload:
{
"request_id": "abc123",
"status": "COMPLETED",
"payload": {
"images": [{"url": "https://fal.media/..."}]
}
}Direct Execution
For fast endpoints (< 30 seconds):
curl -X POST "https://fal.run/fal-ai/fast-sdxl" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "A cat"}'Common Model Parameters
FLUX Models
interface FluxInput {
prompt: string; // Required
image_size?:
| "square_hd" // 1024x1024
| "square" // 512x512
| "portrait_4_3" // 768x1024
| "portrait_16_9" // 576x1024
| "landscape_4_3" // 1024x768
| "landscape_16_9" // 1024x576
| { width: number; height: number };
num_inference_steps?: number; // 1-50, default: 28
guidance_scale?: number; // 1-20, default: 3.5
num_images?: number; // 1-4, default: 1
seed?: number; // For reproducibility
enable_safety_checker?: boolean; // Default: true
output_format?: "jpeg" | "png"; // Default: jpeg
sync_mode?: boolean; // Wait for completion
}
interface FluxOutput {
images: Array<{
url: string;
width: number;
height: number;
content_type: string;
}>;
seed: number;
prompt: string;
has_nsfw_concepts?: boolean[];
timings?: {
inference: number;
};
}Video Models
interface VideoInput {
prompt: string;
negative_prompt?: string;
duration?: number; // seconds
aspect_ratio?: "16:9" | "9:16" | "1:1" | "4:3" | "21:9";
cfg_scale?: number; // 0.0-1.0
seed?: number;
// Model-specific options...
}
interface VideoOutput {
video: {
url: string;
content_type: string;
file_size?: number;
};
audio?: {
url: string;
};
seed: number;
}Audio Models (Whisper)
interface WhisperInput {
audio_url: string;
task?: "transcribe" | "translate";
language?: string; // ISO code
chunk_level?: "segment";
version?: "3";
}
interface WhisperOutput {
text: string;
chunks?: Array<{
text: string;
timestamp: [number, number];
}>;
}Error Responses
// 400 Bad Request - Validation error
{
"detail": "Invalid input",
"errors": [
{"field": "prompt", "message": "Field is required"}
]
}
// 401 Unauthorized
{
"detail": "Invalid API key"
}
// 429 Too Many Requests
{
"detail": "Rate limit exceeded",
"retry_after": 60
}
// 500 Internal Server Error
{
"detail": "Internal server error",
"request_id": "abc123"
}Rate Limits
- Rate limits vary by subscription tier
- Implement exponential backoff for 429 responses
- Use webhooks for high-volume applications
- Contact fal.ai for enterprise rate limits
SDK Versions
| Library | Latest Version | Install |
|---|---|---|
| @fal-ai/client | 0.15+ | npm install @fal-ai/client |
| fal-client (Python) | 0.4+ | pip install fal-client |
| fal (Serverless) | 0.13+ | pip install fal |
Always check https://docs.fal.ai for the latest API documentation and updates.
FLUX Kontext Image Editing Reference
Overview
FLUX Kontext is an instruction-based image editing model that modifies images using natural language commands without requiring masks or manual region selection. It understands context and can make precise edits while preserving unrelated areas.
Basic Usage
JavaScript
import { fal } from "@fal-ai/client";
const result = await fal.subscribe("fal-ai/flux-kontext", {
input: {
prompt: "Change the car color to red",
image_url: "https://example.com/blue-car.jpg",
guidance_scale: 7.5,
num_inference_steps: 28
}
});
console.log("Edited image:", result.data.images[0].url);Python
import fal_client
result = fal_client.subscribe(
"fal-ai/flux-kontext",
arguments={
"prompt": "Add sunglasses to the person",
"image_url": "https://example.com/portrait.jpg",
"guidance_scale": 7.5,
"num_inference_steps": 28
}
)
print(f"Edited: {result['images'][0]['url']}")Edit Types
Color Changes
// Change object colors
{ prompt: "Make the dress blue instead of red" }
{ prompt: "Change hair color to blonde" }
{ prompt: "Turn the sky to sunset orange" }Adding Elements
// Add objects or features
{ prompt: "Add a hat to the person" }
{ prompt: "Put a coffee cup on the table" }
{ prompt: "Add mountains in the background" }Removing Elements
// Remove unwanted objects
{ prompt: "Remove the person in the background" }
{ prompt: "Remove text/watermark from the image" }
{ prompt: "Remove the car from the street" }Style Transfer
// Apply artistic styles
{ prompt: "Convert to watercolor painting style" }
{ prompt: "Make it look like a vintage photograph" }
{ prompt: "Apply cyberpunk aesthetic" }Background Changes
// Modify backgrounds
{ prompt: "Change the background to a beach sunset" }
{ prompt: "Replace the sky with a starry night" }
{ prompt: "Blur the background for portrait effect" }Clothing/Appearance
// Modify clothing and appearance
{ prompt: "Change the outfit to a business suit" }
{ prompt: "Add a winter jacket" }
{ prompt: "Make the person look older" }Advanced Parameters
const result = await fal.subscribe("fal-ai/flux-kontext", {
input: {
prompt: "Your edit instruction",
image_url: "https://example.com/image.jpg",
// Guidance scale: how closely to follow the prompt
// Higher = more literal, Lower = more creative
guidance_scale: 7.5, // Default: 7.5, Range: 1-20
// Inference steps: quality vs speed tradeoff
num_inference_steps: 28, // Default: 28, Range: 1-50
// Output format
output_format: "png", // "png" or "jpeg"
// Seed for reproducibility
seed: 12345 // Optional
}
});Multi-Step Editing Pipeline
// Step 1: Initial edit
const step1 = await fal.subscribe("fal-ai/flux-kontext", {
input: {
prompt: "Change the background to a modern office",
image_url: originalImageUrl
}
});
// Step 2: Refine the edit
const step2 = await fal.subscribe("fal-ai/flux-kontext", {
input: {
prompt: "Add a laptop on the desk",
image_url: step1.data.images[0].url
}
});
// Step 3: Final touches
const final = await fal.subscribe("fal-ai/flux-kontext", {
input: {
prompt: "Improve lighting to look more professional",
image_url: step2.data.images[0].url
}
});Best Practices
Prompt Writing
Good prompts:
- "Change the car from blue to red" (specific)
- "Add a subtle smile to the person's face" (precise)
- "Replace the cloudy sky with clear blue sky" (clear target)
Avoid:
- "Make it better" (too vague)
- "Fix the image" (no specific instruction)
- "Change everything" (too broad)
Preserving Quality
1. Use high-resolution source images (1024x1024 or higher) 2. Set appropriate inference steps (28 for balanced, 40+ for quality) 3. Adjust guidance scale based on edit type:
- Color changes: 5-7 (more creative)
- Adding objects: 7-10 (balanced)
- Precise edits: 10-15 (more literal)
Handling Complex Edits
For complex edits, break them into steps:
// Instead of: "Add sunglasses and change hair to blonde and add a hat"
// Do this:
const step1 = await edit("Add sunglasses", imageUrl);
const step2 = await edit("Change hair color to blonde", step1.url);
const step3 = await edit("Add a stylish hat", step2.url);Comparison with Other Models
| Feature | FLUX Kontext | SDXL Inpainting | DALL-E 3 |
|---|---|---|---|
| Mask required | No | Yes | No |
| Natural language | Yes | Limited | Yes |
| Context understanding | Excellent | Good | Good |
| Fine control | Good | Excellent | Limited |
| Price/edit | ~$0.03 | ~$0.02 | ~$0.04 |
Error Handling
try {
const result = await fal.subscribe("fal-ai/flux-kontext", {
input: {
prompt: "Your edit",
image_url: imageUrl
}
});
} catch (error) {
if (error.message.includes("NSFW")) {
console.error("Content flagged as inappropriate");
} else if (error.message.includes("invalid image")) {
console.error("Could not process image - check URL/format");
} else {
console.error("Edit failed:", error.message);
}
}Use Cases
1. E-commerce: Product color variations, background removal 2. Marketing: Ad creative variations, A/B testing visuals 3. Social Media: Quick edits, style applications 4. Photography: Retouching, background replacement 5. Design: Concept iteration, mood board generation
fal.ai Real-time WebSocket API Reference
Overview
fal.ai provides WebSocket-based real-time connections for streaming inference, enabling low-latency interactive applications like live image generation, real-time video processing, and interactive AI chat.
JavaScript Client Setup
import { fal } from "@fal-ai/client";
// Configure client
fal.config({
credentials: process.env.FAL_KEY
});
// Create real-time connection
const connection = fal.realtime.connect("fal-ai/flux-lora-realtime", {
connectionKey: "unique-session-id",
throttleInterval: 64, // ms between sends (default: 64)
onResult: (result) => {
console.log("Generated:", result.images[0].url);
},
onError: (error) => {
console.error("Stream error:", error.message);
},
onOpen: () => {
console.log("WebSocket connected");
},
onClose: () => {
console.log("WebSocket disconnected");
}
});
// Send generation request
connection.send({
prompt: "a serene mountain landscape at sunset",
image_size: "landscape_16_9",
num_inference_steps: 4,
guidance_scale: 3.5
});
// Close when done
connection.close();Python Real-time Client
import fal_client
import asyncio
async def realtime_generation():
"""Stream real-time image generations."""
async def on_result(result):
print(f"Generated: {result['images'][0]['url']}")
async def on_error(error):
print(f"Error: {error}")
# Connect to real-time endpoint
connection = await fal_client.realtime.connect(
"fal-ai/flux-lora-realtime",
on_result=on_result,
on_error=on_error,
throttle_interval=0.064 # 64ms
)
# Send requests
await connection.send({
"prompt": "cyberpunk cityscape with neon lights",
"image_size": "landscape_16_9"
})
# Keep connection alive
await asyncio.sleep(5)
await connection.close()
asyncio.run(realtime_generation())Connection Configuration
throttleInterval
Controls rate limiting for input sends:
- Default: 64ms (roughly 15 requests/second)
- Minimum recommended: 32ms
- Use higher values for rate-limited scenarios
connectionKey
Unique identifier for the connection session:
- Use for reconnection scenarios
- Helps with debugging and logging
- Required for multi-user applications
Event Handlers
| Handler | Purpose | Required |
|---|---|---|
| onResult | Receives generation results | Yes |
| onError | Handles errors and failures | Recommended |
| onOpen | Connection established callback | Optional |
| onClose | Connection closed callback | Optional |
Real-time Model Endpoints
Image Generation
fal-ai/flux-lora-realtime- FLUX with LoRA, 4-step generationfal-ai/lcm-sd15-i2i- LCM for fast image-to-imagefal-ai/sdxl-turbo-realtime- SDXL Turbo for interactive generation
Video Streaming (Preview)
fal-ai/ltx-video-realtime- LTX Video streaming previewfal-ai/cogvideox-realtime- CogVideoX streaming
Error Handling
const connection = fal.realtime.connect("fal-ai/flux-lora-realtime", {
onError: (error) => {
switch (error.code) {
case "RATE_LIMITED":
// Increase throttleInterval
break;
case "CONNECTION_LOST":
// Implement reconnection logic
break;
case "INVALID_INPUT":
// Validate input parameters
break;
default:
console.error("Unknown error:", error);
}
}
});Best Practices
1. Connection Management
- Reuse connections for multiple requests
- Close connections when no longer needed
- Implement reconnection logic for production
2. Rate Limiting
- Start with default throttleInterval (64ms)
- Increase if receiving rate limit errors
- Monitor connection health
3. Error Recovery
- Always implement onError handler
- Log errors for debugging
- Gracefully degrade on connection loss
4. Resource Cleanup
- Call
connection.close()when done - Handle page unload events in browsers
- Clean up connections on component unmount (React)
fal.ai Serverless Scaling Configuration
Overview
fal.ai's serverless platform (fal.App) provides auto-scaling infrastructure for custom AI models with GPU support, configurable concurrency, and cost optimization features.
Basic Serverless App
import fal
class TextToImage(fal.App, keep_alive=300):
"""Custom image generation model."""
machine_type = "GPU-A100"
requirements = ["torch", "diffusers", "transformers"]
def setup(self):
"""Load model on cold start."""
import torch
from diffusers import StableDiffusionXLPipeline
self.pipe = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
use_safetensors=True
).to("cuda")
@fal.endpoint("/generate")
def generate(self, prompt: str, steps: int = 30) -> dict:
"""Generate image from prompt."""
image = self.pipe(prompt, num_inference_steps=steps).images[0]
# Save and return URL
url = self.save_image(image)
return {"image_url": url}Machine Types and Pricing (2025)
| Machine Type | GPU | VRAM | Cost/sec | Use Case |
|---|---|---|---|---|
| GPU-T4 | NVIDIA T4 | 16GB | $0.000164 | Small models, inference |
| GPU-A10G | NVIDIA A10G | 24GB | $0.000306 | Medium models, SDXL |
| GPU-A100 | NVIDIA A100 | 40GB | $0.000556 | Large models, training |
| GPU-A100-80GB | NVIDIA A100 | 80GB | $0.000833 | 70B models |
| GPU-H100 | NVIDIA H100 | 80GB | $0.001389 | Maximum performance |
| GPU-H200 | NVIDIA H200 | 141GB | $0.001389 | Largest models |
| GPU-B200 | NVIDIA B200 | 180GB+ | $0.001736 | Next-gen workloads |
Scaling Configuration
keep_alive
Time in seconds to keep container warm after last request:
class MyModel(fal.App, keep_alive=300): # 5 minutes
pass- Default: 60 seconds
- Set to 0 for immediate scale-to-zero
- Higher values = lower cold start latency, higher cost
min_concurrency / max_concurrency
Control parallel request handling:
class HighThroughput(fal.App):
machine_type = "GPU-H100"
min_concurrency = 2 # Always have 2 containers ready
max_concurrency = 10 # Scale up to 10 containersnum_gpus
Multi-GPU configuration for large models:
class LargeModel(fal.App):
machine_type = "GPU-H100"
num_gpus = 4 # 4x H100 = 320GB VRAMVolume Mounts
Persistent storage for model weights and data:
class ModelWithStorage(fal.App):
machine_type = "GPU-A100"
volumes = {
"/models": fal.Volume("model-cache"),
"/data": fal.Volume("user-data")
}
def setup(self):
# Models persist across cold starts
self.model = load_model("/models/my-model")Environment Variables and Secrets
class SecureModel(fal.App):
machine_type = "GPU-A10G"
# Public environment variables
env = {
"MODEL_VERSION": "v2.0",
"DEBUG": "false"
}
# Secrets (encrypted)
secrets = ["HF_TOKEN", "API_KEY"]
def setup(self):
import os
hf_token = os.environ["HF_TOKEN"]
# Use token for private model accessProduction Patterns
Health Checks
class ProductionModel(fal.App):
machine_type = "GPU-A100"
@fal.endpoint("/health")
def health(self) -> dict:
"""Health check endpoint."""
return {
"status": "healthy",
"gpu_available": torch.cuda.is_available(),
"model_loaded": hasattr(self, 'model')
}Batched Processing
class BatchProcessor(fal.App):
machine_type = "GPU-H100"
@fal.endpoint("/batch")
def process_batch(self, items: list[str]) -> list[dict]:
"""Process multiple items efficiently."""
results = []
for item in items:
result = self.process_single(item)
results.append(result)
return resultsError Handling
class RobustModel(fal.App):
machine_type = "GPU-A100"
@fal.endpoint("/generate")
def generate(self, prompt: str) -> dict:
try:
result = self._generate(prompt)
return {"success": True, "result": result}
except torch.cuda.OutOfMemoryError:
return {"success": False, "error": "GPU OOM - reduce input size"}
except Exception as e:
return {"success": False, "error": str(e)}Deployment Commands
# Deploy to fal.ai
fal deploy my_app.py
# Deploy with specific name
fal deploy my_app.py --name my-custom-model
# Check deployment status
fal list
# View logs
fal logs my-custom-model
# Delete deployment
fal delete my-custom-modelCost Optimization Tips
1. Right-size GPU: Use smallest GPU that fits your model 2. Scale to zero: Set keep_alive=0 for infrequent workloads 3. Batch requests: Process multiple items per invocation 4. Cache models: Use volumes to avoid re-downloading 5. Monitor usage: Check fal.ai dashboard for optimization opportunities
fal.ai Video Generation Reference
Overview
fal.ai provides access to the latest video generation models including Veo 3, Sora 2, Kling 2.6, and open-source alternatives like LTX Video and CogVideoX.
Model Comparison (2025)
| Model | Max Duration | Resolution | Native Audio | Price/sec | Best For |
|---|---|---|---|---|---|
| Veo 3.1 | 8s | 1080p | Yes | ~$0.40 | Cinematic quality |
| Sora 2 Pro | 20s | 1080p | No | ~$0.35 | Long-form content |
| GPT-Image 1.5 | 5s | 1080p | No | ~$0.25 | Creative animation |
| Kling 2.6 Pro | 10s | 1080p | Yes | ~$0.15 | Cost-effective |
| LTX Video | 5s | 720p | No | ~$0.07 | Budget option |
| CogVideoX | 6s | 720p | No | ~$0.08 | Open-source |
Text-to-Video Generation
Kling 2.6 Pro (Recommended)
import { fal } from "@fal-ai/client";
const result = await fal.subscribe("fal-ai/kling-video/v2.6/pro/text-to-video", {
input: {
prompt: "A majestic eagle soaring through golden sunset clouds, cinematic slow motion",
negative_prompt: "blurry, low quality, distorted",
duration: "10", // 5 or 10 seconds
aspect_ratio: "16:9", // 16:9, 9:16, 1:1
cfg_scale: 0.5, // Creativity (0.0-1.0)
},
logs: true,
onQueueUpdate: (update) => {
if (update.status === "IN_PROGRESS") {
console.log("Progress:", update.logs);
}
}
});
console.log("Video URL:", result.data.video.url);Veo 3.1 (Premium Quality)
const result = await fal.subscribe("fal-ai/veo-3.1", {
input: {
prompt: "Cinematic drone shot flying through a mystical forest, rays of sunlight filtering through ancient trees",
aspect_ratio: "16:9",
duration: 8,
generate_audio: true // Native audio generation
}
});
console.log("Video:", result.data.video.url);
console.log("Audio:", result.data.audio?.url);Sora 2 (Long-form)
const result = await fal.subscribe("fal-ai/sora-2-pro", {
input: {
prompt: "A timelapse of a flower blooming from seed to full bloom, macro photography",
duration: 20,
resolution: "1080p"
}
});Image-to-Video Generation
Starting from FLUX Image
// Step 1: Generate base image with FLUX.2
const imageResult = await fal.subscribe("fal-ai/flux-pro/v1.1", {
input: {
prompt: "Portrait of a woman with flowing hair, studio lighting",
image_size: "landscape_16_9",
num_inference_steps: 28
}
});
const baseImageUrl = imageResult.data.images[0].url;
// Step 2: Animate with Kling 2.6
const videoResult = await fal.subscribe("fal-ai/kling-video/v2.6/pro/image-to-video", {
input: {
prompt: "Hair flowing gently in the wind, subtle smile",
image_url: baseImageUrl,
duration: "5"
}
});
console.log("Video:", videoResult.data.video.url);LTX Video (Budget Option)
import fal_client
result = fal_client.subscribe(
"fal-ai/ltx-video/image-to-video",
arguments={
"prompt": "Gentle camera push-in, subtle movement",
"image_url": "https://example.com/my-image.jpg",
"num_frames": 97, # ~4 seconds at 24fps
"fps": 24
}
)
print(f"Video: {result['video']['url']}")Video-to-Video (Style Transfer)
const result = await fal.subscribe("fal-ai/cogvideox-5b/video-to-video", {
input: {
prompt: "Convert to anime style, vibrant colors",
video_url: "https://example.com/original.mp4",
strength: 0.7 // How much to modify (0.0-1.0)
}
});Native Audio Generation
Models with native audio support generate synchronized soundscapes:
// Veo 3 with native audio
const result = await fal.subscribe("fal-ai/veo-3", {
input: {
prompt: "Ocean waves crashing on rocky shore at sunset, seagulls flying",
duration: 8,
generate_audio: true // Enable native audio
}
});
// Video has synchronized ocean/seagull sounds
console.log("Video with audio:", result.data.video.url);// Kling 2.6 with native audio
const result = await fal.subscribe("fal-ai/kling-video/v2.6/pro/text-to-video", {
input: {
prompt: "Thunderstorm with lightning over a city skyline",
duration: "10",
enable_audio: true // Native thunder/rain sounds
}
});Python Queue-based Execution
For long-running video generation:
import fal_client
import time
# Submit job to queue
handler = fal_client.submit(
"fal-ai/veo-3",
arguments={
"prompt": "Astronaut walking on Mars surface",
"duration": 8,
"generate_audio": True
}
)
print(f"Request ID: {handler.request_id}")
# Poll for status
while True:
status = fal_client.status("fal-ai/veo-3", handler.request_id)
print(f"Status: {status['status']}")
if status["status"] == "COMPLETED":
result = fal_client.result("fal-ai/veo-3", handler.request_id)
print(f"Video: {result['video']['url']}")
break
elif status["status"] == "FAILED":
print(f"Error: {status.get('error')}")
break
time.sleep(5)Webhook Notifications
For production workflows:
const result = await fal.queue.submit("fal-ai/kling-video/v2.6/pro/text-to-video", {
input: {
prompt: "Cinematic scene of a spaceship landing",
duration: "10"
},
webhookUrl: "https://your-server.com/webhook"
});
// Your webhook receives:
// {
// "request_id": "abc123",
// "status": "COMPLETED",
// "result": { "video": { "url": "..." } }
// }Cost Optimization
1. Start with LTX/CogVideoX for prototyping (~$0.07-0.08/sec) 2. Use Kling 2.6 for production balance (~$0.15/sec) 3. Reserve Veo 3/Sora 2 for final renders (~$0.35-0.40/sec) 4. Use shorter durations when possible (5s vs 10s) 5. Generate image first with FLUX, then animate - often cheaper