---
name: fal
description: Use when calling 1,000+ AI models for image, video, audio, and
  multimodal generation, or when deploying custom models on serverless GPU
  infrastructure. Agents should reach for this skill when building AI
  applications, integrating generative models into workflows, deploying
  inference endpoints, or managing model inference at scale.
metadata:
  mintlify-proj: fal
  version: "1.0"
---

# fal Skill Reference

## Product Summary

fal is a generative media platform with two core capabilities: **Model APIs** (call 1,000+ production-ready models for image, video, audio, and multimodal generation) and **Serverless** (deploy your own models on autoscaling GPU infrastructure). Both use the same queue-based inference system, client SDKs (Python, JavaScript), and REST API. Key files: `fal.App` class for serverless apps, `pyproject.toml` for configuration. CLI: `fal deploy`, `fal run`, `fal auth`. Primary docs: https://fal.ai/docs

## When to Use

Reach for this skill when:
- **Calling models**: User wants to generate images, video, audio, or other media from text or images using pre-built models (FLUX, Kling, Sora, Whisper, etc.)
- **Deploying custom models**: User has their own model or pipeline and needs to expose it as an API endpoint with autoscaling
- **Building AI workflows**: User is integrating generative AI into a larger application (Next.js app, backend service, automation tool)
- **Managing inference at scale**: User needs queue-based reliability, automatic retries, webhook notifications, or real-time WebSocket connections
- **Optimizing cold starts**: User is deploying on serverless and needs to reduce startup time or costs
- **Observability**: User needs logs, analytics, error tracking, or metrics for their deployed models

## Quick Reference

### Essential CLI Commands

| Command | Purpose |
|---------|---------|
| `fal auth login` | Authenticate with your fal account |
| `fal run path/to/app.py::AppClass` | Test app on temporary GPU runner (ephemeral) |
| `fal deploy path/to/app.py::AppClass` | Deploy app to production (persistent endpoint) |
| `fal apps list` | List your deployed applications |
| `fal apps runners` | View active runners for an app |
| `fal secrets set NAME=VALUE` | Store secrets (API keys, tokens) |
| `fal environments` | Manage staging/production environments |
| `fal queue status <request_id>` | Check status of a queued request |

### API Key Setup

```bash
# Get key from https://fal.ai/dashboard/keys
export FAL_KEY="key_id:key_secret"
```

### Calling a Model (Model APIs)

**Python:**
```python
import fal_client

result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
    "prompt": "a sunset over mountains"
})
print(result["images"][0]["url"])
```

**JavaScript:**
```javascript
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/flux/schnell", {
  input: { prompt: "a sunset over mountains" }
});
console.log(result.data.images[0].url);
```

### Deploying a Custom Model (Serverless)

```python
import fal
from pydantic import BaseModel

class Input(BaseModel):
    prompt: str

class MyModel(fal.App):
    machine_type = "GPU-A100"
    requirements = ["torch", "diffusers"]
    
    def setup(self):
        from diffusers import StableDiffusionXLPipeline
        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0"
        ).to("cuda")
    
    @fal.endpoint("/")
    def generate(self, input: Input):
        image = self.pipe(input.prompt).images[0]
        return {"image": image}
```

### Inference Methods

| Method | Use Case | Blocking | Retries |
|--------|----------|----------|---------|
| `run()` | Direct HTTP, fastest path | Yes | No |
| `subscribe()` | Simple blocking call with queue reliability | Yes | Yes |
| `submit()` | Async queue, full control, webhooks | No | Yes |
| `stream()` | Progressive output (LLMs, generation progress) | Yes | No |
| `realtime()` | WebSocket, sub-100ms latency | Persistent | No |

### Configuration File (pyproject.toml)

```toml
[tool.fal.apps.my-app]
auth = "private"  # or "public", "shared"
machine_type = "GPU-A100"
keep_alive = 60  # seconds idle before shutdown
min_concurrency = 1  # warm runners to keep
max_concurrency = 10  # max parallel runners

[tool.fal.apps.my-app.image]
dockerfile = "Dockerfile"
```

## Decision Guidance

### When to Use Model APIs vs Serverless

| Scenario | Model APIs | Serverless |
|----------|-----------|-----------|
| Want to call existing models (FLUX, Kling, etc.) | ✓ | — |
| Have your own model to deploy | — | ✓ |
| Need fast time-to-market | ✓ | — |
| Need full control over code/environment | — | ✓ |
| Want pay-per-use billing | ✓ | ✓ |
| Need to publish to marketplace | — | ✓ |

### When to Use Each Inference Method

| Method | Scenario |
|--------|----------|
| `run()` | Scripts, prototyping, one-off calls, no retry needed |
| `subscribe()` | Simple integrations, backend scripts, blocking calls with reliability |
| `submit()` | Production workloads, parallel requests, webhooks, full queue control |
| `stream()` | LLM token generation, showing progress to users |
| `realtime()` | Chat, real-time video processing, sub-100ms latency required |

### Authentication Modes for Deployed Apps

| Mode | Who Can Call | Who Pays | Use Case |
|------|-------------|---------|----------|
| `private` | Team members only | App owner | Internal tools, private APIs |
| `public` | Anyone with URL | App owner | Open demos, internal access control |
| `shared` | Anyone with API key | Each caller | Marketplace, revenue sharing |

## Workflow

### Calling a Model (Model APIs)

1. **Get API key**: Visit https://fal.ai/dashboard/keys and create a key
2. **Set environment**: `export FAL_KEY="your-key"`
3. **Install client**: `pip install fal-client` or `npm install @fal-ai/client`
4. **Choose model**: Browse https://fal.ai/models or check model-api-reference docs
5. **Make request**: Use `fal_client.subscribe()` or `fal.subscribe()` with model ID and input
6. **Handle response**: Extract media URLs from result JSON
7. **Verify**: Check response status and error fields before using output

### Deploying a Custom Model (Serverless)

1. **Write app**: Create `fal.App` class with `setup()` and `@fal.endpoint()` methods
2. **Define inputs/outputs**: Use Pydantic models for type safety
3. **Declare hardware**: Set `machine_type` (GPU-A100, GPU-H100, etc.)
4. **List dependencies**: Add `requirements` list or use custom Dockerfile
5. **Test locally**: Run `fal run path/to/app.py::AppClass` on temporary GPU
6. **Fix errors**: Address import, model-loading, or setup failures
7. **Deploy**: Run `fal deploy path/to/app.py::AppClass`
8. **Test in dashboard**: Open app in https://fal.ai/dashboard/apps, test endpoint
9. **Monitor**: Check logs, analytics, and error rates in dashboard
10. **Scale**: Adjust `keep_alive`, `min_concurrency`, `max_concurrency` as needed

### Managing Secrets and Environments

1. **Set secret**: `fal secrets set HF_TOKEN=your_token`
2. **Scope to environment**: `fal secrets set HF_TOKEN=staging_token --env staging`
3. **Use in code**: Access via `os.getenv("HF_TOKEN")` in setup() or endpoints
4. **Deploy to environment**: `fal deploy app.py::App --env staging`
5. **Verify**: Check that runner receives correct secret value

## Common Gotchas

- **Endpoint input must be Pydantic model**: A bare scalar parameter like `def run(self, prompt: str)` is treated as a query parameter, not JSON body. Always use `class Input(BaseModel): prompt: str` and `def run(self, input: Input)`.
- **setup() is billed**: Every cold start charges for the full setup() duration, not just request time. Optimize setup() time to reduce costs.
- **FAL_KEY not set**: Client SDKs read `FAL_KEY` environment variable automatically. If not set, requests fail with 401. Set it before running code.
- **Model weights not cached**: First request downloads model weights (slow). Use persistent storage (`/data`) or `keep_alive` to avoid repeated downloads.
- **Synchronous calls don't retry**: `run()` and `stream()` skip the queue and don't retry on failure. Use `subscribe()` or `submit()` for production reliability.
- **Cold starts on every request**: If `keep_alive=0` or no `min_concurrency`, every request triggers a new runner. Increase `keep_alive` or set `min_concurrency > 0` to keep runners warm.
- **Status codes matter**: Return 500 for app errors (runner stays alive), 503 for bad state (runner killed, request retried), 504 for timeout (retried). Wrong codes kill healthy runners.
- **Secrets not available at build time**: Environment variables and secrets are only injected at runtime, not during Docker image build. Use build args for build-time config.
- **Webhook URLs must be HTTPS**: Webhook notifications only work with HTTPS endpoints. HTTP URLs are rejected.
- **Request timeout default is 600s**: Long-running models may hit the default timeout. Increase with `request_timeout` parameter or optimize model performance.

## Verification Checklist

Before submitting work with fal:

- [ ] **API key set**: `echo $FAL_KEY` returns a non-empty value
- [ ] **Model ID correct**: Verify model exists at https://fal.ai/models or in model-api-reference docs
- [ ] **Input schema matches**: Check model's input parameters in playground or docs
- [ ] **fal run succeeds**: For serverless apps, `fal run` completes without errors before deploying
- [ ] **Endpoint input is Pydantic**: Custom apps use `class Input(BaseModel)` for endpoint parameters
- [ ] **setup() completes**: Model weights load and initialization succeeds in test run
- [ ] **Response parsed correctly**: Extract media URLs or data from result JSON structure
- [ ] **Error handling in place**: Check response status and error fields before using output
- [ ] **Secrets scoped correctly**: Verify secrets are set for the target environment
- [ ] **Scaling parameters reasonable**: `keep_alive` and `min_concurrency` match expected traffic patterns
- [ ] **Cold start acceptable**: For latency-sensitive apps, verify startup time is within SLA
- [ ] **Monitoring enabled**: Dashboard logs and analytics are accessible for deployed apps

## Resources

**Comprehensive navigation**: https://fal.ai/docs/llms.txt

**Critical documentation pages**:
- [Model APIs Overview](https://fal.ai/docs/documentation/model-apis/overview) — How to call 1,000+ models
- [Serverless Quickstart](https://fal.ai/docs/documentation/development/getting-started/quick-start) — Deploy your first app in 2 minutes
- [Deploy to Production](https://fal.ai/docs/documentation/deployment/deploy-to-production) — Full deployment guide with auth modes and rollout strategies

---

> For additional documentation and navigation, see: https://fal.ai/docs/llms.txt