Skip to content
Back to skills

Fal Ai

ASecurity

Deploy and run AI models instantly with fal.ai — image generation, video, audio, and custom models. Use when generating images with Flux/SDXL/LoRA, running ML inference at scale, building AI media features, or accessing state-of-the-art generative models via a simple API.

  • 142 stars
  • 0 votes
  • 0 copies
  • 16 views
  • Added May 27, 2026
developmentjavascripttypescriptpythongojavabashnextjsnodeapi

Works with

  • cursor
  • terminal
  • cli
  • api

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned May 27, 2026

npx -y skills add TerminalSkills/skills --skill fal-ai --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fal Ai?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fal Ai
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/terminalskills-fal-ai/badge)](https://www.skillsdirectory.com/skills/terminalskills-fal-ai)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: fal-ai
description: >-
  Deploy and run AI models instantly with fal.ai — image generation, video,
  audio, and custom models. Use when generating images with Flux/SDXL/LoRA,
  running ML inference at scale, building AI media features, or accessing
  state-of-the-art generative models via a simple API.
license: Apache-2.0
compatibility: "Node.js 18+, Python 3.9+, Browser (via @fal-ai/client)"
metadata:
  author: terminal-skills
  version: "1.0.0"
  category: data-ai
  tags: ["fal-ai", "image-generation", "flux", "ml", "inference"]
  use-cases:
    - "Generate product images with Flux Pro for an e-commerce catalog"
    - "Create animated videos from images with AnimateDiff"
    - "Transcribe audio files at scale with Whisper"
  agents: [claude-code, openai-codex, gemini-cli, cursor]
---

# fal.ai

## Overview

fal.ai provides instant serverless inference for AI models — no GPU provisioning, no containers, pay per inference. The API is simple: pick a model ID, pass inputs, get outputs. Supports async jobs with webhooks, real-time streaming, and file uploads. Best-in-class for Flux image generation, video generation, and audio models.

## Install

```bash
npm install @fal-ai/client    # JavaScript/TypeScript
pip install fal-client         # Python
```

## Authentication

```bash
export FAL_KEY="your-api-key"  # Get from fal.ai/dashboard
```

## Quick Start

### TypeScript

```typescript
import * as fal from "@fal-ai/client";

// Configure (reads FAL_KEY from env by default)
fal.config({ credentials: process.env.FAL_KEY });

// Generate an image with Flux Schnell (fastest)
const result = await fal.subscribe("fal-ai/flux/schnell", {
  input: {
    prompt: "A futuristic city at night, neon lights, cyberpunk style",
    image_size: "landscape_4_3",
    num_images: 1,
  },
  logs: true,
  onQueueUpdate: (update) => {
    if (update.status === "IN_PROGRESS") {
      console.log(update.logs?.map(l => l.message).join("\n"));
    }
  },
});

console.log(result.data.images[0].url);
```

### Python

```python
import fal_client

def on_queue_update(update):
    if isinstance(update, fal_client.InProgress):
        for log in update.logs:
            print(log["message"])

result = fal_client.subscribe(
    "fal-ai/flux/schnell",
    arguments={
        "prompt": "A futuristic city at night, neon lights, cyberpunk style",
        "image_size": "landscape_4_3",
        "num_images": 1,
    },
    with_logs=True,
    on_queue_update=on_queue_update,
)

print(result["images"][0]["url"])
```

## Popular Models

### Flux Image Generation

```typescript
// Flux Pro — highest quality
const pro = await fal.subscribe("fal-ai/flux-pro", {
  input: {
    prompt: "Portrait of a robot chef, photorealistic, soft lighting",
    image_size: "portrait_4_3",   // landscape_4_3, square, square_hd
    num_inference_steps: 28,
    guidance_scale: 3.5,
    num_images: 1,
    safety_tolerance: "2",        // 1-6, higher = more permissive
  }
});

// Flux Dev — high quality, faster than Pro
const dev = await fal.subscribe("fal-ai/flux/dev", {
  input: {
    prompt: "...",
    num_inference_steps: 28,
    seed: 42,  // For reproducibility
  }
});

// Flux Schnell — fastest, good quality
const schnell = await fal.subscribe("fal-ai/flux/schnell", {
  input: { prompt: "...", num_inference_steps: 4 }  // Only needs 4 steps
});

// Flux with LoRA
const lora = await fal.subscribe("fal-ai/flux-lora", {
  input: {
    prompt: "A photo of TOK wearing a tuxedo",
    loras: [
      {
        path: "https://huggingface.co/your-lora/model.safetensors",
        scale: 1.0
      }
    ],
    num_inference_steps: 28,
  }
});
```

### Image-to-Image

```typescript
const result = await fal.subscribe("fal-ai/flux/dev/image-to-image", {
  input: {
    prompt: "Transform into oil painting style",
    image_url: "https://example.com/photo.jpg",
    strength: 0.85,  // 0-1, how much to transform (1 = ignore original)
    num_inference_steps: 28,
  }
});
```

### Video Generation

```typescript
// AnimateDiff — animate a still image
const video = await fal.subscribe("fal-ai/animatediff-v2v", {
  input: {
    image_url: "https://example.com/frame.jpg",
    prompt: "Gentle breeze moving through the trees",
    num_frames: 16,
    fps: 8,
  }
});
console.log(video.data.video.url);  // .mp4 URL

// Runway-style video gen
const runway = await fal.subscribe("fal-ai/kling-video/v1/standard/image-to-video", {
  input: {
    image_url: "https://example.com/start.jpg",
    prompt: "Camera slowly pans right",
    duration: "5",
  }
});
```

### Audio — Whisper Transcription

```typescript
// Upload audio file first
const audioUrl = await fal.storage.upload(fs.readFileSync("audio.mp3"), "audio.mp3");

const transcript = await fal.subscribe("fal-ai/whisper", {
  input: {
    audio_url: audioUrl,
    task: "transcribe",  // or "translate" (to English)
    language: "en",      // Optional, auto-detected if omitted
    chunk_level: "segment",
    version: "3",
  }
});

console.log(transcript.data.text);
```

### MusicGen

```python
result = fal_client.subscribe(
    "fal-ai/musicgen",
    arguments={
        "prompt": "Upbeat electronic music for a tech product demo, 120 BPM",
        "duration": 30,   # seconds
        "top_k": 250,
        "top_p": 0.0,
        "temperature": 1.0,
    }
)
print(result["audio"]["url"])
```

## Async Jobs with Webhooks

For long-running jobs, use submit → poll instead of subscribe:

```typescript
// Submit job (returns immediately)
const { request_id } = await fal.queue.submit("fal-ai/flux-pro", {
  input: { prompt: "..." },
  webhookUrl: "https://your-app.com/webhooks/fal",  // Optional
});

// Poll for result
const checkStatus = async () => {
  const status = await fal.queue.status("fal-ai/flux-pro", {
    requestId: request_id,
    logs: true,
  });

  if (status.status === "COMPLETED") {
    const result = await fal.queue.result("fal-ai/flux-pro", {
      requestId: request_id,
    });
    return result.data;
  }

  if (status.status === "FAILED") {
    throw new Error(`Job failed: ${status.error}`);
  }

  // Still in queue, check again in 2s
  await new Promise(r => setTimeout(r, 2000));
  return checkStatus();
};

const result = await checkStatus();
```

### Webhook Handler (Next.js)

```typescript
// app/api/webhooks/fal/route.ts
export async function POST(req: Request) {
  const payload = await req.json();

  if (payload.status === "OK") {
    const imageUrl = payload.payload.images[0].url;
    await db.update({ requestId: payload.request_id, imageUrl, status: "done" });
  } else {
    await db.update({ requestId: payload.request_id, status: "failed" });
  }

  return Response.json({ ok: true });
}
```

## File Uploads

```typescript
import * as fal from "@fal-ai/client";
import * as fs from "fs";

// Upload a file to fal.ai storage
const fileBuffer = fs.readFileSync("my-image.jpg");
const url = await fal.storage.upload(fileBuffer, "image.jpg");
// Returns: "https://fal.run/files/..."

// Use uploaded URL as model input
const result = await fal.subscribe("fal-ai/flux/dev/image-to-image", {
  input: { image_url: url, prompt: "..." }
});
```

```python
# Python file upload
import fal_client

url = fal_client.upload_file("./photo.png")
print(url)  # https://fal.run/files/...
```

## Batch Processing

```typescript
async function generateBatch(prompts: string[]): Promise<string[]> {
  // Submit all jobs in parallel
  const jobs = await Promise.all(
    prompts.map(prompt =>
      fal.queue.submit("fal-ai/flux/schnell", {
        input: { prompt, num_images: 1 }
      })
    )
  );

  // Poll all results
  const results = await Promise.all(
    jobs.map(({ request_id }) =>
      fal.queue.result("fal-ai/flux/schnell", { requestId: request_id })
    )
  );

  return results.map(r => r.data.images[0].url);
}

const urls = await generateBatch([
  "A red sports car",
  "A blue mountain lake",
  "A golden sunset over the ocean",
]);
```

## Guidelines

- Use `fal.subscribe()` for synchronous workflows (waits for completion, handles polling internally)
- Use `fal.queue.submit()` + webhooks for production async pipelines
- Flux Schnell is fastest (4 steps, ~2s); use for prototyping and bulk generation
- Flux Pro gives highest quality; use for final production images
- Always handle `onQueueUpdate` for user-facing apps to show progress
- Uploaded files are stored temporarily — download and persist to your own storage if needed
- Rate limits apply per API key; for high volume use the queue API to avoid timeouts
- Check `fal.ai/models` for the full list of available models (100+)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.