

# https://fal.ai/docs/api-reference/cli/api.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal api

Call any model on fal directly from the command line. Useful for quick testing without writing code.

## Usage

```bash theme={null}
fal api <model_id> [key=value ...]
```

**Arguments:**

| Argument   | Description                                                      |
| ---------- | ---------------------------------------------------------------- |
| `model_id` | The model endpoint to call (e.g., `fal-ai/flux/schnell`)         |
| `params`   | Key-value pairs for the request body (e.g., `prompt="a sunset"`) |

## Examples

**Generate an image:**

```bash theme={null}
fal api fal-ai/flux/schnell prompt="a cat wearing sunglasses"
```

The CLI shows real-time status updates (queued, in progress) and logs while the request is processing, then prints the result.

**Nested parameters:**

Use bracket notation for nested values:

```bash theme={null}
fal api fal-ai/flux/schnell prompt="a sunset" image_size[width]:=1280 image_size[height]:=720
```

Use `:=` for non-string values (numbers, booleans):

```bash theme={null}
fal api fal-ai/flux/schnell prompt="a sunset" num_images:=4 seed:=42
```

**Streaming endpoints:**

If the model ID ends with `/stream`, the CLI streams output as it's generated:

```bash theme={null}
fal api fal-ai/any-llm/stream prompt="What is the meaning of life?" model=google/gemini-flash-1.5
```

## How It Works

* For regular endpoints: submits via the queue, polls for status with live log display, then prints the result
* For `/stream` endpoints: connects via streaming and prints output as it arrives
* Uses your configured `FAL_KEY` for authentication


# https://fal.ai/docs/api-reference/cli/apps/delete.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps delete

```bash theme={null}
Usage: fal apps delete [-h] [--debug] [--pdb] [--cprofile] [--env ENV] app_name

Delete application.

Positional Arguments:
  app_name    Application name.

Options:
  -h, --help  show this help message and exit
  --env ENV   Target environment (defaults to main).

Examples:
  fal apps delete my-app
  fal apps delete my-app --env staging
```


# https://fal.ai/docs/api-reference/cli/apps/delete-rev.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps delete-rev

```bash theme={null}
Usage: fal apps delete-rev [-h] [--debug] [--pdb] [--cprofile] app_rev

Delete application revision.

Positional Arguments:
  app_rev     Application revision.

Options:
  -h, --help  show this help message and exit
```


# https://fal.ai/docs/api-reference/cli/apps/list.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps list

```bash theme={null}
Usage: fal apps list [-h] [--debug] [--pdb] [--cprofile]
                     [--sort-by-runners] [--filter FILTER]
                     [--env ENV] [--regions REGIONS [REGIONS ...]]
                     [--output {pretty,json}] [--json]

List applications.

Options:
  -h, --help            show this help message and exit
  --sort-by-runners     Sort by number of runners ascending.
  --filter FILTER       Filter applications by alias contents.
  --env ENV             Target environment (defaults to main).
  --regions REGIONS [REGIONS ...]
                        Valid regions (pass several items to filter on multiple).

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)

Examples:
  fal apps list
  fal apps list --env staging
  fal apps list --filter myapp --sort-by-runners
  fal apps list --json
```


# https://fal.ai/docs/api-reference/cli/apps/list-rev.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps list-rev

```bash theme={null}
Usage: fal apps list-rev [-h] [--debug] [--pdb] [--cprofile] [--env ENV]
                         [app_name]

List application revisions.

Positional Arguments:
  app_name    Application name (optional).

Options:
  -h, --help  show this help message and exit
  --env ENV   Target environment (defaults to main).
```


# https://fal.ai/docs/api-reference/cli/apps/rollout.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps rollout

```bash theme={null}
Usage: fal apps rollout [-h] [--debug] [--pdb] [--cprofile] [--team TEAM] 
                        [--force] [--env ENV] app_name

Rollout application by restarting all active runners.

Positional Arguments:
  app_name     Application name.

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
  --force      Force rollout by killing runners immediately instead of 
               gracefully stopping them.
  --env ENV    Target environment (defaults to main).

Debug:
  --debug      Show verbose errors.
  --pdb        Start pdb on error.
  --cprofile   Show cProfile report.
```

## When to Use

Use `fal apps rollout` when you need to restart all runners for an application without redeploying:

* **Environment variable changes**: Force runners to pick up updated secrets or environment variables
* **Bad state recovery**: Restart runners that may be in an unhealthy state
* **Memory cleanup**: Force garbage collection and memory cleanup across all runners
* **Configuration updates**: Apply changes that require a runner restart

## Graceful vs Force Rollout

### Graceful Rollout (Default)

```bash theme={null}
fal apps rollout myapp
```

Gracefully stops all active runners, allowing them to finish processing current requests before shutting down. This is the recommended approach for most situations.

**How it works:**

1. Identifies all active runners for the application
2. Sends a graceful stop signal to each runner
3. Runners finish their current requests
4. New runners are automatically started by the auto-scaling system as needed

### Force Rollout

```bash theme={null}
fal apps rollout myapp --force
```

Immediately kills all active runners without waiting for current requests to complete. Use this when runners are unresponsive or when you need an immediate restart.

**How it works:**

1. Identifies all active runners for the application
2. Immediately terminates all runners
3. New runners are automatically started by the auto-scaling system

<Warning>
  Force rollout will terminate in-flight requests, potentially causing errors for active users. Use the graceful rollout (without `--force`) unless absolutely necessary.
</Warning>

## Examples

### Rollout after updating a secret

```bash theme={null}
# Update a secret
fal secrets set MY_API_KEY new_value

# Gracefully rollout to pick up the new secret
fal apps rollout myapp
```

### Rollout in a specific environment

```bash theme={null}
# Update a secret in staging
fal secrets set MY_API_KEY staging_value --env staging

# Rollout the staging environment
fal apps rollout myapp --env staging
```

### Force rollout to recover from frozen runners

```bash theme={null}
# Check runners status
fal apps runners myapp

# Force immediate restart if runners are unresponsive
fal apps rollout myapp --force
```

## Difference from Redeployment

`fal apps rollout` is different from `fal deploy`:

* **`fal apps rollout`**: Restarts existing runners without changing the application code or configuration. Useful for applying environment changes or recovering from bad states.
* **`fal deploy`**: Creates a new revision of your application with updated code and configuration. Use this when you've made code changes.

## See Also

* [fal deploy](/serverless/cli/deploy) - Deploy a new revision of your application
* [fal apps scale](/serverless/cli/apps/scale) - Adjust scaling parameters
* [fal apps runners](/serverless/cli/apps/runners) - View active runners for an application


# https://fal.ai/docs/api-reference/cli/apps/runners.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps runners

```bash theme={null}
Usage: fal apps runners [-h] [--team TEAM] [--env ENV]
                        [--since SINCE]
                        [--state {all,idle,running,pending,setup,failure_delay,terminated} [...]]
                        [--output {pretty,json}] [--json]
                        app_name

List application runners.

Positional Arguments:
  app_name              Application name.

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --env ENV             Target environment (defaults to main).
  --since SINCE         Show terminated runners since the given time. Accepts 'now', relative like '30m', '1h', '1d', or an ISO timestamp. Max 24 hours.
  --state {all,idle,running,pending,setup,failure_delay,terminated} [{all,idle,running,pending,setup,failure_delay,terminated} ...]
                        Filter by runner state(s). Choose one or more, or 'all' (default).

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)

Examples:
  fal apps runners my-app
  fal apps runners my-app --env staging
```

The runner table displays the following columns:

* **Alias** -- Application name
* **Machine Type** -- Hardware type (e.g. `GPU-A100`, `GPU-H100`)
* **Runner ID** -- Unique runner identifier
* **In Flight Requests** -- Number of active requests
* **Expires In** -- Time until runner expires
* **Uptime** -- How long the runner has been running
* **Revision** -- Application revision
* **State** -- Current runner state


# https://fal.ai/docs/api-reference/cli/apps/scale.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps scale

```bash theme={null}
Usage: fal apps scale [-h] [--debug] [--pdb] [--cprofile]
                      [--keep-alive KEEP_ALIVE]
                      [--max-multiplexing MAX_MULTIPLEXING]
                      [--max-concurrency MAX_CONCURRENCY]
                      [--min-concurrency MIN_CONCURRENCY]
                      [--concurrency-buffer CONCURRENCY_BUFFER]
                      [--concurrency-buffer-perc CONCURRENCY_BUFFER_PERC]
                      [--scaling-delay SCALING_DELAY]
                      [--request-timeout REQUEST_TIMEOUT]
                      [--startup-timeout STARTUP_TIMEOUT]
                      [--machine-types MACHINE_TYPES [MACHINE_TYPES ...]]
                      [--regions REGIONS [REGIONS ...]]
                      [--env ENV]
                      app_name

Scale application.

Positional Arguments:
  app_name              Application name.

Options:
  -h, --help            show this help message and exit
  --keep-alive KEEP_ALIVE
                        Keep alive (seconds).
  --max-multiplexing MAX_MULTIPLEXING
                        Maximum multiplexing
  --max-concurrency MAX_CONCURRENCY
                        Maximum concurrency.
  --min-concurrency MIN_CONCURRENCY
                        Minimum concurrency
  --concurrency-buffer CONCURRENCY_BUFFER
                        Concurrency buffer (minimum extra capacity).
  --concurrency-buffer-perc CONCURRENCY_BUFFER_PERC
                        Concurrency buffer expressed as a percentage.
  --scaling-delay SCALING_DELAY
                        Scaling delay (seconds).
  --request-timeout REQUEST_TIMEOUT
                        Request timeout (seconds). If a request takes longer, it is aborted and the runner gracefully stopped as it could be in a bad state.
  --startup-timeout STARTUP_TIMEOUT
                        Startup timeout (seconds).
  --machine-types MACHINE_TYPES [MACHINE_TYPES ...]
                        Machine types (pass several items to set multiple).
  --regions REGIONS [REGIONS ...]
                        Valid regions (pass several items to set multiple).
  --env ENV             Target environment (defaults to main).
```

<Note>
  **Note:**

  Redeploying the application, by default, will not reset these settings, except for the code-specific settings. See [Code-Specific Settings (Reset on Deploy)](/serverless/deployment-operations/scale-your-application#code-specific-settings-reset-on-deploy) for details.
</Note>


# https://fal.ai/docs/api-reference/cli/apps/set-rev.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal apps set-rev

```bash theme={null}
Usage: fal apps set-rev [-h] [--debug] [--pdb] [--cprofile]
                        [--team TEAM] [--auth {public,private,shared}]
                        [--strategy {recreate,rolling}] [--env ENV] app_name
                        app_rev

Set application to a particular revision.

Positional Arguments:
  app_name              Application name.
  app_rev               Application revision.

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --auth {public,private,shared}
                        Application authentication mode.
  --strategy {recreate,rolling}
                        Deployment strategy.
  --env ENV             Target environment (defaults to main). Can also be set via FAL_ENV environment variable.

Debug:
  --debug               Show verbose errors.
  --pdb                 Start pdb on error.
  --cprofile            Show cProfile report.
```


# https://fal.ai/docs/api-reference/cli/auth.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal auth

```bash theme={null}
fal auth [-h] [--debug] [--pdb] [--cprofile] command ...

Authenticate with fal.

Options:
  -h, --help  show this help message and exit

Commands:
  command
    login     Log in a user.
    logout    Log out the currently logged-in user.
    whoami    Show the currently authenticated user.
```

## Login

```bash theme={null}
Usage: fal auth login [-h] [--debug] [--pdb] [--cprofile]
                      [--connection CONNECTION] [--no-browser]

Log in a user.

Options:
  -h, --help               show this help message and exit
  --connection CONNECTION  Auth connection (e.g. github, google, or an SSO domain). Skips the interactive prompt.
  --no-browser             Don't attempt to open a browser. Just print the URL to visit.
```

When `--connection` is omitted, the CLI prompts you to choose between GitHub, Google, or your enterprise SSO domain. The previously used choice is remembered and offered as the default on subsequent logins.

## Logout

```bash theme={null}
Usage: fal auth logout [-h] [--debug] [--pdb] [--cprofile] [--no-browser]

Log out the currently logged-in user.

Options:
  -h, --help    show this help message and exit
  --no-browser  Don't attempt to open a browser. Just print the URL to visit.
```

## Whoami

```bash theme={null}
Usage: fal auth whoami [-h] [--debug] [--pdb] [--cprofile]

Show the currently authenticated user.

Options:
  -h, --help  show this help message and exit

Debug:
  --debug     Show verbose errors.
  --pdb       Start pdb on error.
  --cprofile  Show cProfile report.
```


# https://fal.ai/docs/api-reference/cli/create.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal create

```bash theme={null}
Usage: fal create [-h] [--debug] [--pdb] [--cprofile] project_type

Create fal applications.

Positional Arguments:
  project_type  Type of project to create.

Options:
  -h, --help    show this help message and exit
```


# https://fal.ai/docs/api-reference/cli/deploy.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal deploy

```bash theme={null}
Usage: fal deploy [-h] [--output {pretty,json}] [--json] [--team TEAM] [--app-name APP_NAME]
                  [--auth AUTH] [--strategy {recreate,rolling}] [--no-scale] [--reset-scale]
                  [--check] [--yes] [--no-cache] [--env ENV]
                  [app_ref]

Deploy a fal application. If no app reference is provided, the command will look for a pyproject.toml file with a [tool.fal.apps] section and deploy the application specified with the provided app name.

Positional Arguments:
  app_ref               Application reference. Either a file path or a file path and a function name separated by '::'. If no reference is provided, the command will look for a pyproject.toml file with a [tool.fal.apps] section and deploy the application specified with the provided app name.
                        File path example: path/to/myfile.py::MyApp
                        App name example: my-app (configure team in pyproject.toml)

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --app-name APP_NAME   Application name to deploy with.
  --auth AUTH           Application authentication mode (private, public, shared).
  --strategy {recreate,rolling}
                        Deployment strategy.
  --no-scale            Use the previous deployment of the application for scale settings. This is the default behavior.
  --reset-scale         Use the application code for scale settings.
  --check               Show a pre-deployment summary before deploying. Prompts for confirmation unless --yes is also set.
  --yes                 Skip interactive deploy confirmation prompts. When combined with --check, the summary is still shown.
  --no-cache            Do not use the cache for the environment build.
  --env ENV             Target environment (defaults to main). Can also be set via FAL_ENV environment variable.

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)

Examples:
  fal deploy
  fal deploy path/to/myfile.py
  fal deploy path/to/myfile.py::MyApp
  fal deploy path/to/myfile.py::MyApp --app-name myapp --auth public
  fal deploy path/to/myfile.py::MyApp --check
  fal deploy path/to/myfile.py::MyApp --check --yes
  fal deploy path/to/myfile.py::MyApp --env staging
  fal deploy my-app
```


# https://fal.ai/docs/api-reference/cli/doctor.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal doctor

```bash theme={null}
Usage: fal doctor [-h] [--debug] [--pdb] [--cprofile]
                  [--output {pretty,json}] [--json]

fal version and misc environment information.

Options:
  -h, --help            show this help message and exit

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)
```

Outputs the installed `fal` and `isolate` versions, the Python version and platform, and the configured `FAL_HOST` and the prefix of the active `FAL_KEY`. Useful when filing bug reports.


# https://fal.ai/docs/api-reference/cli/environments.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal environments

```bash theme={null}
Usage: fal environments [-h] [--debug] [--pdb] [--cprofile] command ...

Manage fal environments.

Options:
  -h, --help  show this help message and exit

Commands:
  command
    list      List environments.
    create    Create an environment.
    delete    Delete an environment.
```

<Note>
  The `environments` command also has an alias `envs` for convenience:

  ```bash theme={null}
  fal envs list
  ```
</Note>

## List

```bash theme={null}
Usage: fal environments list [-h] [--debug] [--pdb] [--cprofile]
                             [--output {pretty,json}] [--json]

List environments.

Options:
  -h, --help            show this help message and exit

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)

Examples:
  fal environments list
  fal envs list --output json
```

## Create

```bash theme={null}
Usage: fal environments create [-h] [--debug] [--pdb] [--cprofile]
                               [--description DESCRIPTION]
                               name

Create an environment.

Positional Arguments:
  name                  Environment name.

Options:
  -h, --help            show this help message and exit
  --description DESCRIPTION
                        Environment description.

Examples:
  fal environments create staging
  fal envs create dev --description "Development environment"
```

## Delete

```bash theme={null}
Usage: fal environments delete [-h] [--debug] [--pdb] [--cprofile] [--yes]
                               name

Delete an environment.

Positional Arguments:
  name        Environment name.

Options:
  -h, --help  show this help message and exit
  --yes       Skip confirmation prompt.

Debug:
  --debug     Show verbose errors.
  --pdb       Start pdb on error.
  --cprofile  Show cProfile report.
```

<Warning>
  Deleting an environment permanently removes all apps and secrets in that environment. You will be prompted to confirm by typing the environment name unless `--yes` is provided.
</Warning>

## Using Environments with Other Commands

Once you've created environments, you can target them using the `--env` flag in other commands:

```bash theme={null}
# Deploy to an environment
fal deploy path/to/myapp.py::MyApp --env staging

# Manage secrets per environment
fal secrets set API_KEY=value --env staging
fal secrets list --env staging

# Manage apps per environment
fal apps list --env staging
fal apps scale my-app --min-concurrency 1 --env staging
fal apps runners my-app --env staging
fal apps delete my-app --env staging

# Run functions with environment-specific secrets
fal run path/to/myapp.py::MyApp --env staging
```


# https://fal.ai/docs/api-reference/cli/files.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal files

```bash theme={null}
fal files [-h] [--debug] [--pdb] [--cprofile] command ...

Manage fal files.

Options:
  -h, --help  show this help message and exit
Commands:
  command
    list (ls)
              List files.
    download  Download files.
    upload    Upload files.
    upload-url
              Upload file from URL.
    mv        Move or rename a remote file or directory.
    rm        Recursively remove a remote file or directory.
```

## List

```bash theme={null}
fal files list [-h] [--debug] [--pdb] [--cprofile] [--team TEAM] [path]

List files.

Positional Arguments:
  path         The path to list

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.

```

## Download

```bash theme={null}
fal files download [-h] [--debug] [--pdb] [--cprofile] [--team TEAM]
                          remote_path local_path

Download files.

Positional Arguments:
  remote_path  Remote path to download
  local_path   Local path to download to

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
```

## Upload

```bash theme={null}
fal files upload [-h] [--debug] [--pdb] [--cprofile] [--team TEAM]
                        local_path remote_path

Upload files.

Positional Arguments:
  local_path   Local path to upload
  remote_path  Remote path to upload to

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.

```

## Upload URL

```bash theme={null}
fal files upload-url [-h] [--debug] [--pdb] [--cprofile] [--team TEAM]
                            url remote_path

Upload file from URL.

Positional Arguments:
  url          URL to upload
  remote_path  Remote path to upload to

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
```

## Move

```bash theme={null}
fal files mv [-h] [--team TEAM] source destination

Move or rename a remote file or directory.

Positional Arguments:
  source       Remote source path
  destination  Remote destination path

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
```

## Remove

```bash theme={null}
fal files rm [-h] [--team TEAM] path

Recursively remove a remote file or directory.

Positional Arguments:
  path         Remote path

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
```


# https://fal.ai/docs/api-reference/cli/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI Reference

> Complete reference for the fal command-line interface

The fal CLI is the primary tool for deploying and managing your fal applications.

## Installation

```bash theme={null}
pip install fal
```

## Authentication

```bash theme={null}
fal auth login
```

## Commands

| Command                                               | Description                      |
| ----------------------------------------------------- | -------------------------------- |
| [`fal auth`](/api-reference/cli/auth)                 | Authenticate with fal            |
| [`fal deploy`](/api-reference/cli/deploy)             | Deploy an application            |
| [`fal run`](/api-reference/cli/run)                   | Run a function                   |
| [`fal apps`](/api-reference/cli/apps/list)            | Manage applications              |
| [`fal environments`](/api-reference/cli/environments) | Manage environments              |
| [`fal keys`](/api-reference/cli/keys)                 | Manage API keys                  |
| [`fal secrets`](/api-reference/cli/secrets)           | Manage secrets                   |
| [`fal files`](/api-reference/cli/files)               | Manage files in /data            |
| [`fal queue`](/api-reference/cli/queue)               | Manage queued requests           |
| [`fal runners`](/api-reference/cli/runners)           | Manage runners                   |
| [`fal api`](/api-reference/cli/api)                   | Call a fal API endpoint directly |
| [`fal account`](/api-reference/cli/teams)             | Manage accounts                  |
| [`fal doctor`](/api-reference/cli/doctor)             | Diagnose issues                  |
| [`fal create`](/api-reference/cli/create)             | Create a new project             |
| [`fal profile`](/api-reference/cli/profile)           | Manage profiles                  |


# https://fal.ai/docs/api-reference/cli/installation.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

## Install latest official version

```bash theme={null}
pip install fal
```

## Install upstream version

```bash theme={null}
pip install git+https://github.com/fal-ai/fal#subdirectory=projects/fal
```

## Install development version from a git revision

```bash theme={null}
pip install git+https://github.com/fal-ai/fal@75fe22f19cf61c7b6488d919d9a8c4bcb3433b42#subdirectory=projects/fal
```

## Install development version from a git tag

```bash theme={null}
pip install git+https://github.com/fal-ai/fal@fal_v1.10.0#subdirectory=projects/fal
```

## Install development version from a git branch

```bash theme={null}
pip install git+https://github.com/fal-ai/fal@main#subdirectory=projects/fal
```


# https://fal.ai/docs/api-reference/cli/keys.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal keys

```bash theme={null}
Usage: fal keys [-h] [--debug] [--pdb] [--cprofile] command ...

Manage fal keys.

Options:
  -h, --help  show this help message and exit
Commands:
  command
    create    Create a key.
    list      List keys.
    revoke    Revoke key.
```

## Create

```bash theme={null}
Usage: fal keys create [-h] [--debug] [--pdb] [--cprofile] --scope {ADMIN,API}
                       [--desc DESC]

Create a key.

Options:
  -h, --help           show this help message and exit
  --scope {ADMIN,API}  The privilege scope of the key.
  --desc DESC          Key description (e.g. "My Test Key")
```

## List

```bash theme={null}
Usage: fal keys list [-h] [--debug] [--pdb] [--cprofile]

List keys.

Options:
  -h, --help  show this help message and exit
```

## Revoke

```bash theme={null}
Usage: fal keys revoke [-h] [--debug] [--pdb] [--cprofile] key_id

Revoke key.

Positional Arguments:
  key_id      Key ID.

Options:
  -h, --help  show this help message and exit
```


# https://fal.ai/docs/api-reference/cli/profile.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal profile

### Managing Profiles

The `fal` CLI allows you to manage multiple profiles, making it easy to switch between different fal accounts. This is particularly useful if you have multiple environments or projects.

#### Adding a New Profile

To add a new profile, set it as the default and then add the key:

```sh theme={null}
❯ fal profile set example
Default profile set to example.
No key set for profile. Use fal profile key to set a key.

❯ fal profile key
Enter the key: invalid
Invalid key. The key must be in the format key:value.
Enter the key: 112f05b4-6ee8-4d06-bdb1-7ba38789ef8e:954285993fa8e651dac37a03ea2efbc9
Key set for profile example.
```

<Note>
  **Note:**

  The key used in the example above is no longer valid. 😉
</Note>

#### Listing Profiles

To list all available profiles, use the `fal profile list` command:

```sh theme={null}
❯ fal profile list
```

| Default | Profile | Settings |
| ------- | ------- | -------- |
|         | me      | key      |
|         | comfy   | key      |
| \*      | example | key      |

#### Setting a Default Profile

To set a default profile, use the `fal profile set` command followed by the profile name:

```sh theme={null}
❯ fal profile set comfy
Default profile set to comfy.

❯ fal profile list
```

| Default | Profile | Settings |
| ------- | ------- | -------- |
|         | me      | key      |
| \*      | comfy   | key      |
|         | example | key      |

After setting the default profile, you can directly access the account information without specifying the profile name.

```sh theme={null}
❯ fal app list
```

| Name   | Revision           | Auth   | Min Concurrency | Max Concurrency | Max Multiplexing | Keep Alive | Request Timeout | Startup Timeout | Machine Type | Runners | Regions |
| ------ | ------------------ | ------ | --------------- | --------------- | ---------------- | ---------- | --------------- | --------------- | ------------ | ------- | ------- |
| my-app | 11111111-2222-333… | shared | 0               | 10              | 1                | 300        | 3600            | 600             | ........     | 0       |         |

#### Deleting a Profile

To delete a profile, use the `fal profile delete` command followed by the profile name:

```sh theme={null}
❯ fal profile delete example
Profile example deleted.
```

## Command Reference

```bash theme={null}
Usage: fal profile [-h] command ...

Profile management.

Commands:
  command
    list      List all profiles.
    set       Set default profile. If the profile doesn't exist, you'll be prompted to create it.
    unset     Unset default profile.
    key       Set key for profile.
    host      Set fal host.
    create    Create a new profile.
    delete    Delete profile.
```

<Note>
  `fal profiles` is an alias for `fal profile`.
</Note>

### create

Create a new named profile and set it as the default:

```bash theme={null}
fal profile create <PROFILE>
```

If the profile already exists the command is a no-op. After creation you'll typically run `fal profile key` to attach an API key.

### unset

Clear the default profile selection:

```bash theme={null}
fal profile unset
```

After unsetting, `fal` falls back to environment variables (`FAL_KEY`, `FAL_HOST`).

### host

Override the fal API host for the active profile. Most users don't need this — it's primarily useful for self-hosted or staging deployments:

```bash theme={null}
fal profile host <HOST>
```

### list

```bash theme={null}
Usage: fal profile list [-h] [--output {pretty,json}] [--json]
```

Supports JSON output for scripting:

```bash theme={null}
fal profile list --json
```


# https://fal.ai/docs/api-reference/cli/queue.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal queue

> Manage application queues.

```bash theme={null}
Usage: fal queue [-h] command ...

Manage application queues.

Options:
  -h, --help  show this help message and exit

Commands:
  command
    size      Get queue size for an application.
    flush     Flush all pending requests in an application queue.
```

## Size

```bash theme={null}
Usage: fal queue size [-h] [--output {pretty,json}] [--json] [--team TEAM]
                      [--by-user] app_name

Get queue size for an application.

Positional Arguments:
  app_name              Application name (do not prefix with owner).

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --by-user             Group queue size by user.

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)
```

## Flush

```bash theme={null}
Usage: fal queue flush [-h] [--team TEAM] [--caller-user-id CALLER_USER_ID] app_name

Flush all pending requests in an application queue.

Positional Arguments:
  app_name              Application name.

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --caller-user-id CALLER_USER_ID
                        Only flush requests from this user ID. If not provided, all requests will be flushed.
```


# https://fal.ai/docs/api-reference/cli/run.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal run

```bash theme={null}
Usage: fal run [-h] [--team TEAM] [--no-cache] [--app-name APP_NAME]
               [--auth AUTH] [--env ENV] [--local]
               [--machine-type MACHINE_TYPE]
               [--limit-max-requests LIMIT_MAX_REQUESTS]
               func_ref

Run fal function.

Positional Arguments:
  func_ref              Function reference. Configure team in pyproject.toml for app names.

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --no-cache            Do not use the cache for the environment build.
  --app-name APP_NAME   Application name to run with.
  --auth AUTH           Application authentication mode (private, public, shared), defaults to public.
  --env ENV             Target environment (defaults to main).
  --local               Run locally without serverless.
  --machine-type MACHINE_TYPE
                        Machine type to use for this run.
  --limit-max-requests LIMIT_MAX_REQUESTS
                        For fal.App runs, gracefully stop the server after serving N requests.

Examples:
  fal run path/to/myfile.py::myfunc
  fal run path/to/myfile.py::myfunc --env staging
  fal run path/to/myfile.py::MyApp --auth private
  fal run path/to/myfile.py::MyApp --local
  fal run path/to/myfile.py::MyApp --machine-type GPU-A100
```

<Warning>
  `fal run` ignores the `auth` set on `fal.App` and in `pyproject.toml` and defaults to `public` so the app is reachable for testing. Pass `--auth` to override. In a future major release the default will become `private` and the `fal.App`/`pyproject.toml` value will be respected.
</Warning>

## Authentication Modes

The `--auth` flag controls who can access your app while it's running:

* **`public`** (default for `fal run`): Anyone can call your app without authentication. You pay for all usage.
* **`private`**: Only you (or your team) can call the app. Requires a valid API key.
* **`shared`**: Any authenticated fal user can call the app.

By default, `fal run` uses `public` mode for easy testing during development.


# https://fal.ai/docs/api-reference/cli/runners.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal runners

```bash theme={null}
Usage: fal runners [-h] command ...

Manage fal runners.

Options:
  -h, --help  show this help message and exit

Commands:
  command
    stop        Stop a runner gracefully.
    kill        Kill a runner.
    list        List runners.
    logs (log)  Show logs for a runner.
    shell       Open a shell on a runner.
    exec        Execute a command on a runner.
```

## List

```bash theme={null}
Usage: fal runners list [-h] [--team TEAM] [--since SINCE]
                        [--state {all,idle,running,pending,setup,failure_delay,terminated} [...]]
                        [--output {pretty,json}] [--json]

List runners.

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --since SINCE         Show terminated runners since the given time. Accepts 'now', relative like '30m', '1h', '1d', or an ISO timestamp. Max 24 hours.
  --state {all,idle,running,pending,setup,failure_delay,terminated} [{all,idle,running,pending,setup,failure_delay,terminated} ...]
                        Filter by runner state(s). Choose one or more, or 'all' (default).

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)
```

The runner table displays the following columns:

* **Alias** — Application name
* **Machine Type** — Hardware type (e.g. `GPU-A100`, `GPU-H100`)
* **Runner ID** — Unique runner identifier
* **In Flight Requests** — Number of active requests
* **Expires In** — Time until runner expires
* **Uptime** — How long the runner has been running
* **Revision** — Application revision
* **State** — Current runner state

## Logs

```bash theme={null}
Usage: fal runners logs [-h] [--output {pretty,json}] [--json] [--team TEAM]
                        [--search SEARCH] [--since SINCE] [--until UNTIL]
                        [--follow] [--lines LINES]
                        id

Show logs for a runner.

Positional Arguments:
  id                    Runner ID.

Options:
  -h, --help            show this help message and exit
  --team TEAM           The team to use.
  --search SEARCH       Search for string in logs.
  --since SINCE         Show logs since the given time. Accepts 'now', relative like '30m', '1h', or an ISO timestamp. Defaults to runner start time or to '1m ago' in --follow mode.
  --until UNTIL         Show logs until the given time. Accepts 'now', relative like '30m', '1h', or an ISO timestamp. Defaults to runner finish time or 'now' if it is still running.
  --follow, -f          Follow logs live. If --since is not specified, implies '--since 1m ago'.
  --lines, -n LINES     Only show latest N log lines. If '+' prefix is used, show oldest N log lines. Ignored if --follow is used.

Output:
  --output {pretty,json}
                        Modify the command output
  --json                Output in JSON format (same as --output json)
```

## Stop

```bash theme={null}
Usage: fal runners stop [-h] [--team TEAM] id

Stop a runner gracefully.

Positional Arguments:
  id           Runner ID.

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
```

## Kill

```bash theme={null}
Usage: fal runners kill [-h] [--team TEAM] id

Kill a runner.

Positional Arguments:
  id           Runner ID.

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
```

## Shell

```bash theme={null}
Usage: fal runners shell [-h] [--team TEAM] id

Open an interactive shell session inside a running runner.

Positional Arguments:
  id           Runner ID.

Options:
  -h, --help   show this help message and exit
  --team TEAM  The team to use.
```

### Use Cases

* **Debug running code**: Inspect the runtime environment of a live runner
* **Check dependencies**: Verify installed packages and their versions
* **Examine state**: Inspect files, environment variables, and runtime state
* **Troubleshoot issues**: Diagnose problems in production runners

### Example

Connect to a running runner:

```bash theme={null}
# Get runner ID from runners list
fal runners list

# Connect to the runner
fal runners shell runner_abc123xyz
```

Once connected, you have full shell access within the runner's container environment. Press `Ctrl+D` or type `exit` to disconnect.

## Exec

Run a one-off command on a runner without opening an interactive shell.

```bash theme={null}
Usage: fal runners exec [-h] [--team TEAM] [-it] id [command ...]

Execute a command on a runner.

Positional Arguments:
  id                  Runner ID.
  command             Command to execute (after `--`).

Options:
  -h, --help          show this help message and exit
  --team TEAM         The team to use.
  -it, --interactive  Allocate a TTY and attach stdin (interactive mode).
```

The command and its arguments are passed after a `--` separator so they aren't parsed as flags by the `fal` CLI.

### Examples

```bash theme={null}
# Print environment variables on the runner
fal runners exec runner_abc123xyz -- env

# Tail an arbitrary log file inside the container
fal runners exec runner_abc123xyz -- tail -f /var/log/my-app.log

# Run an interactive Python REPL
fal runners exec runner_abc123xyz -it -- python
```


# https://fal.ai/docs/api-reference/cli/secrets.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal secrets

```bash theme={null}
Usage: fal secrets [-h] [--debug] [--pdb] [--cprofile] command ...

Manage fal secrets.

Options:
  -h, --help  show this help message and exit
Commands:
  command
    set       Set a secret.
    list      List secrets.
    unset     Unset a secret.
```

## Set

```bash theme={null}
Usage: fal secrets set [-h] [--debug] [--pdb] [--cprofile] [--env ENV]
                       NAME=VALUE [NAME=VALUE ...]

Set a secret.

Positional Arguments:
  NAME=VALUE  Secret NAME=VALUE pairs.

Options:
  -h, --help  show this help message and exit
  --env ENV   Target environment (defaults to main).

Examples:
  fal secrets set HF_TOKEN=hf_***
  fal secrets set API_KEY=key123 --env staging
```

## List

```bash theme={null}
Usage: fal secrets list [-h] [--debug] [--pdb] [--cprofile] [--env ENV]

List secrets.

Options:
  -h, --help  show this help message and exit
  --env ENV   Target environment (defaults to main).

Examples:
  fal secrets list
  fal secrets list --env staging
```

## Unset

```bash theme={null}
Usage: fal secrets unset [-h] [--debug] [--pdb] [--cprofile] [--env ENV] NAME

Unset a secret.

Positional Arguments:
  NAME        Secret's name.

Options:
  -h, --help  show this help message and exit
  --env ENV   Target environment (defaults to main).

Debug:
  --debug     Show verbose errors.
  --pdb       Start pdb on error.
  --cprofile  Show cProfile report.

Examples:
  fal secrets unset HF_TOKEN
  fal secrets unset API_KEY --env staging
```


# https://fal.ai/docs/api-reference/cli/teams.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal account

Manage and switch between the personal, team, and organization accounts you belong to. Useful when you're a member of multiple accounts and need to deploy or manage apps under a specific one.

## fal account list

List all accounts you belong to:

```bash theme={null}
fal account list
```

Shows your personal account along with any team and organization accounts, indicating which is currently active.

Supports `--output {pretty,json}` and `--json` for machine-readable output.

## fal account set

Switch to a specific account:

```bash theme={null}
fal account set <account>
```

`<account>` may be either an account nickname or the index shown by `fal account list`. After switching, all CLI operations (`fal deploy`, `fal apps`, `fal secrets`, etc.) run under the selected account.

If no `<account>` is provided, you'll be prompted interactively.

**Arguments:**

| Argument  | Description                                       |
| --------- | ------------------------------------------------- |
| `account` | The account nickname (or list index) to switch to |

**Example:**

```bash theme={null}
# Switch to your company team
fal account set my-company

# Deploy under that team
fal deploy my_app.py::MyApp
```

## fal account unset

Switch back to your personal account:

```bash theme={null}
fal account unset
```


# https://fal.ai/docs/api-reference/client-libraries/dart/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Dart Client

> fal client library for Flutter applications

The `fal_client` package provides a Dart interface for calling fal AI models in Flutter applications.

## Installation

```bash theme={null}
flutter pub add fal_client
```

## Quick Start

```dart theme={null}
import 'package:fal_client/fal_client.dart';

final fal = FalClient.withCredentials("YOUR_FAL_KEY");

final result = await fal.subscribe("fal-ai/flux/dev", input: {
  "prompt": "a cat",
  "seed": 6252023,
  "image_size": "landscape_4_3",
  "num_images": 4
});

print(result);
```

## Supported Platforms

* Flutter (iOS, Android, Web, Desktop)
* Dart (standalone)

## API Reference

<Card title="Dart API Reference" icon="book" href="https://pub.dev/documentation/fal_client/latest">
  Full API documentation on pub.dev
</Card>

<Card title="GitHub Repository" icon="github" href="https://github.com/fal-ai/fal-dart">
  Source code and examples
</Card>

<Card title="Example App" icon="mobile" href="https://pub.dev/packages/fal_client/example">
  Simple Flutter app using fal image inference
</Card>


# https://fal.ai/docs/api-reference/client-libraries/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Client Libraries

> Libraries for calling fal AI models from your applications

Use these libraries to call fal AI models from your applications. Available for multiple languages and platforms.

<CardGroup cols={2}>
  <Card title="Python" icon="python" href="/reference/client-libraries/python">
    Python client for fal AI models
  </Card>

  <Card title="JavaScript" icon="js" href="/reference/client-libraries/javascript">
    JS/TS client for web and Node.js
  </Card>
</CardGroup>

## Mobile & Other Platforms

<CardGroup cols={3}>
  <Card title="Swift" icon="swift" href="/reference/client-libraries/swift">
    iOS, macOS, tvOS, watchOS
  </Card>

  <Card title="Kotlin / Java" icon="java" href="/reference/client-libraries/kotlin">
    Android and JVM
  </Card>

  <Card title="Dart" icon="flutter" href="/reference/client-libraries/dart">
    Flutter apps
  </Card>
</CardGroup>


# https://fal.ai/docs/api-reference/client-libraries/javascript/auth.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# auth

> API reference for @fal-ai/client auth

***

## Functions

### getTemporaryAuthToken

```typescript theme={null}
async function getTemporaryAuthToken(app: string, config: RequiredConfig): Promise<string>
```

Get a token to connect to the realtime endpoint.

| Parameter | Type             | Description |
| :-------- | :--------------- | :---------- |
| `app`     | `string`         | -           |
| `config`  | `RequiredConfig` | -           |

**Returns:** `Promise<string>`

***

## Types

### TokenProvider

```typescript theme={null}
type TokenProvider = (app: string) => Promise<string>
```

A function that provides a temporary authentication token.


# https://fal.ai/docs/api-reference/client-libraries/javascript/client.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# client

> API reference for @fal-ai/client client

## Classes & Interfaces

### FalClient

```typescript theme={null}
interface FalClient
```

The main client type, it provides access to simple API model usage,
as well as access to the `queue` and `storage` APIs.

<Accordion title="Properties" defaultOpen>
  | Name        | Type                        | Description                                                                                                                                                                                       |
  | :---------- | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | `queue`     | `QueueClient`               | The queue client to interact with the queue API.                                                                                                                                                  |
  | `realtime`  | `RealtimeClient`            | The realtime client to interact with the realtime API and receive updates in real-time.                                                                                                           |
  | `storage`   | `StorageClient`             | The storage client to interact with the storage API.                                                                                                                                              |
  | `streaming` | `StreamingClient`           | The streaming client to interact with the streaming API.                                                                                                                                          |
  | `stream`    | `StreamingClient["stream"]` | Calls a fal app that supports streaming and provides a streaming-capable object as a result, that can be used to get partial results through either `AsyncIterator` or through an event listener. |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### run

  ```typescript theme={null}
  run(endpointId: Id, options: RunOptions<InputType<Id>>): Promise<Result<OutputType<Id>>>
  ```

  Runs a fal endpoint identified by its `endpointId`.

  | Parameter    | Type                        | Description                                       |
  | :----------- | :-------------------------- | :------------------------------------------------ |
  | `endpointId` | `Id`                        | The endpoint id, e.g. `fal-ai/fast-sdxl`.         |
  | `options`    | `RunOptions<InputType<Id>>` | The request options, including the input payload. |

  **Returns:** `Promise<Result<OutputType<Id>>>`

  #### subscribe

  ```typescript theme={null}
  subscribe(endpointId: Id, options: RunOptions<InputType<Id>> & QueueSubscribeOptions): Promise<Result<OutputType<Id>>>
  ```

  Subscribes to updates for a specific request in the queue.

  | Parameter    | Type                                                | Description                                                                 |
  | :----------- | :-------------------------------------------------- | :-------------------------------------------------------------------------- |
  | `endpointId` | `Id`                                                | - The ID of the API endpoint.                                               |
  | `options`    | `RunOptions<InputType<Id>> & QueueSubscribeOptions` | - Options to configure how the request is run and how updates are received. |

  **Returns:** `Promise<Result<OutputType<Id>>>`
</Accordion>

***

## Functions

### createFalClient

```typescript theme={null}
function createFalClient(userConfig?: Config): FalClient
```

Creates a new reference of the `FalClient`.

| Parameter    | Type     | Description                                              |
| :----------- | :------- | :------------------------------------------------------- |
| `userConfig` | `Config` | Optional configuration to override the default settings. |

**Returns:** `FalClient`


# https://fal.ai/docs/api-reference/client-libraries/javascript/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript Client

> API reference for @fal-ai/client

The `@fal-ai/client` package provides a TypeScript/JavaScript interface for calling fal AI models.

## Installation

```bash theme={null}
npm install @fal-ai/client
```

## Quick Start

```typescript theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/flux/dev", {
  input: {
    prompt: "a cat wearing a hat",
    image_size: "landscape_4_3"
  },
  logs: true,
  onQueueUpdate: (status) => console.log(`Status: ${status.status}`)
});

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

## API Overview

| Method                   | Description                        |
| :----------------------- | :--------------------------------- |
| `fal.run()`              | Run a model synchronously          |
| `fal.subscribe()`        | Run via queue with status updates  |
| `fal.stream()`           | Stream partial results             |
| `fal.queue.submit()`     | Submit to queue, get request ID    |
| `fal.queue.status()`     | Check request status               |
| `fal.queue.result()`     | Get completed result               |
| `fal.realtime.connect()` | Open realtime WebSocket connection |
| `fal.storage.upload()`   | Upload file to fal CDN             |

## API Reference

The following pages contain the auto-generated API reference for all public classes and functions in the `@fal-ai/client` package.


# https://fal.ai/docs/api-reference/client-libraries/javascript/middleware.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# middleware

> API reference for @fal-ai/client middleware

***

## Functions

### withMiddleware

```typescript theme={null}
function withMiddleware(middlewares: RequestMiddleware[]): RequestMiddleware
```

Setup a execution chain of middleware functions.

| Parameter     | Type                  | Description                       |
| :------------ | :-------------------- | :-------------------------------- |
| `middlewares` | `RequestMiddleware[]` | one or more middleware functions. |

**Returns:** `RequestMiddleware`

### withProxy

```typescript theme={null}
function withProxy(config: RequestProxyConfig): RequestMiddleware
```

| Parameter | Type                 | Description |
| :-------- | :------------------- | :---------- |
| `config`  | `RequestProxyConfig` | -           |

**Returns:** `RequestMiddleware`

***

## Types

### RequestConfig

```typescript theme={null}
type RequestConfig = {
  url: string;
  method: string;
  headers?: Record<string, string | string[]>;
}
```

A request configuration object.

**Note:** This is a simplified version of the `RequestConfig` type from the
`fetch` API. It contains only the properties that are relevant for the
fal client. It also works around the fact that the `fetch` API `Request`
does not support mutability, its clone method has critical limitations
to our use case.

### RequestMiddleware

```typescript theme={null}
type RequestMiddleware = (
  request: RequestConfig,
) => Promise<RequestConfig>
```

### RequestProxyConfig

```typescript theme={null}
type RequestProxyConfig = {
  targetUrl: string;
}
```


# https://fal.ai/docs/api-reference/client-libraries/javascript/queue.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# queue

> API reference for @fal-ai/client queue

## Classes & Interfaces

### QueueClient

```typescript theme={null}
interface QueueClient
```

Represents a request queue with methods for submitting requests,
checking their status, retrieving results, and subscribing to updates.

<Accordion title="Methods" defaultOpen>
  #### submit

  ```typescript theme={null}
  submit(endpointId: Id, options: SubmitOptions<InputType<Id>>): Promise<InQueueQueueStatus>
  ```

  Submits a request to the queue.

  | Parameter    | Type                           | Description                                    |
  | :----------- | :----------------------------- | :--------------------------------------------- |
  | `endpointId` | `Id`                           | - The ID of the function web endpoint.         |
  | `options`    | `SubmitOptions<InputType<Id>>` | - Options to configure how the request is run. |

  **Returns:** `Promise<InQueueQueueStatus>`

  #### status

  ```typescript theme={null}
  status(endpointId: string, options: QueueStatusOptions): Promise<QueueStatus>
  ```

  Retrieves the status of a specific request in the queue.

  | Parameter    | Type                 | Description                                    |
  | :----------- | :------------------- | :--------------------------------------------- |
  | `endpointId` | `string`             | - The ID of the function web endpoint.         |
  | `options`    | `QueueStatusOptions` | - Options to configure how the request is run. |

  **Returns:** `Promise<QueueStatus>`

  #### streamStatus

  ```typescript theme={null}
  streamStatus(endpointId: string, options: QueueStatusStreamOptions): Promise<FalStream<unknown, QueueStatus>>
  ```

  Subscribes to updates for a specific request in the queue using HTTP streaming events.

  | Parameter    | Type                       | Description                                                                 |
  | :----------- | :------------------------- | :-------------------------------------------------------------------------- |
  | `endpointId` | `string`                   | - The ID of the function web endpoint.                                      |
  | `options`    | `QueueStatusStreamOptions` | - Options to configure how the request is run and how updates are received. |

  **Returns:** `Promise<FalStream<unknown, QueueStatus>>`

  #### subscribeToStatus

  ```typescript theme={null}
  subscribeToStatus(endpointId: string, options: QueueStatusSubscriptionOptions): Promise<CompletedQueueStatus>
  ```

  Subscribes to updates for a specific request in the queue using polling or streaming.
  See `options.mode` for more details.

  | Parameter    | Type                             | Description                                                                 |
  | :----------- | :------------------------------- | :-------------------------------------------------------------------------- |
  | `endpointId` | `string`                         | - The ID of the function web endpoint.                                      |
  | `options`    | `QueueStatusSubscriptionOptions` | - Options to configure how the request is run and how updates are received. |

  **Returns:** `Promise<CompletedQueueStatus>`

  #### result

  ```typescript theme={null}
  result(endpointId: Id, options: BaseQueueOptions): Promise<Result<OutputType<Id>>>
  ```

  Retrieves the result of a specific request from the queue.

  | Parameter    | Type               | Description                                    |
  | :----------- | :----------------- | :--------------------------------------------- |
  | `endpointId` | `Id`               | - The ID of the function web endpoint.         |
  | `options`    | `BaseQueueOptions` | - Options to configure how the request is run. |

  **Returns:** `Promise<Result<OutputType<Id>>>`

  #### cancel

  ```typescript theme={null}
  cancel(endpointId: string, options: BaseQueueOptions): Promise<void>
  ```

  Cancels a request in the queue.

  | Parameter    | Type               | Description                                                                 |
  | :----------- | :----------------- | :-------------------------------------------------------------------------- |
  | `endpointId` | `string`           | - The ID of the function web endpoint.                                      |
  | `options`    | `BaseQueueOptions` | - Options to configure how the request is run and how updates are received. |

  **Returns:** `Promise<void>`
</Accordion>

***

## Types

### QueuePriority

```typescript theme={null}
type QueuePriority = "low" | "normal"
```

### QueueStatusSubscriptionOptions

```typescript theme={null}
type QueueStatusSubscriptionOptions = QueueStatusOptions &
  QueueModeOptions &
  Omit<QueueCommonSubscribeOptions, "onEnqueue" | "webhookUrl">
```

### QueueSubscribeOptions

```typescript theme={null}
type QueueSubscribeOptions = QueueCommonSubscribeOptions &
  QueueModeOptions
```

Options for subscribing to the request queue.

### SubmitOptions

```typescript theme={null}
type SubmitOptions = RunOptions<Input> & {
  /**
   * The URL to send a webhook notification to when the request is completed.
   * @see WebHookResponse
   */
  webhookUrl?: string;

  /**
   * The priority of the request. It defaults to `normal`.
   * This will be sent as the `x-fal-queue-priority` header.
   *
   * @see QueuePriority
   */
  priority?: QueuePriority;

  /**
   * A hint for the runner to use when processing the request.
   * This will be sent as the `x-fal-runner-hint` header.
   */
  hint?: string;

  /**
   * Server-side request timeout in seconds. Limits total time spent waiting
   * before processing starts (includes queue wait, retries, and routing).
   * Does not apply once the application begins processing.
   *
   * This will be sent as the `x-fal-request-timeout` header.
   */
  startTimeout?: number;

  /**
   * Additional HTTP headers to include in the submit request.
   *
   * Note: `priority`, `hint`, `startTimeout`, and `objectLifecycle` will override the following headers:
   *  - `x-fal-queue-priority`
   *  - `x-fal-runner-hint`
   *  - `x-fal-request-timeout`
   *  - `x-fal-object-lifecycle-preference`
   */
  headers?: Record<string, string>;
}
```

Options for submitting a request to the queue.

### QueueStatusOptions

```typescript theme={null}
type QueueStatusOptions = BaseQueueOptions & {
  /**
   * If `true`, the response will include the logs for the request.
   * Defaults to `false`.
   */
  logs?: boolean;
}
```

### QueueStatusStreamOptions

```typescript theme={null}
type QueueStatusStreamOptions = QueueStatusOptions & {
  /**
   * The connection mode to use for streaming updates. It defaults to `server`.
   * Set to `client` if your server proxy doesn't support streaming.
   */
  connectionMode?: StreamingConnectionMode;
}
```


# https://fal.ai/docs/api-reference/client-libraries/javascript/realtime.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# realtime

> API reference for @fal-ai/client realtime

## Classes & Interfaces

### RealtimeConnection

```typescript theme={null}
interface RealtimeConnection
```

A connection object that allows you to `send` request payloads to a
realtime endpoint.

<Accordion title="Methods" defaultOpen>
  #### send

  ```typescript theme={null}
  send(input: Input & Partial<WithRequestId>): void
  ```

  | Parameter | Type                             | Description |
  | :-------- | :------------------------------- | :---------- |
  | `input`   | `Input & Partial<WithRequestId>` | -           |

  #### close

  ```typescript theme={null}
  close(): void
  ```
</Accordion>

### RealtimeConnectionHandler

```typescript theme={null}
interface RealtimeConnectionHandler
```

Options for connecting to the realtime endpoint.

<Accordion title="Properties" defaultOpen>
  | Name                      | Type                                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                |
  | :------------------------ | :------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `connectionKey?`          | `string`                               | The connection key. This is used to reuse the same connection across multiple calls to `connect`. This is particularly useful in contexts where the connection is established as part of a component lifecycle (e.g. React) and the component is re-rendered multiple times.                                                                                                                                                               |
  | `clientOnly?`             | `boolean`                              | If `true`, the connection will only be established on the client side. This is useful for frameworks that reuse code for both server-side rendering and client-side rendering (e.g. Next.js). This is set to `true` by default when running on React in the server. Otherwise, it is set to `false`. Note that more SSR frameworks might be automatically detected in the future. In the meantime, you can set this to `true` when needed. |
  | `throttleInterval?`       | `number`                               | The throtle duration in milliseconds. This is used to throtle the calls to the `send` function. Realtime apps usually react to user input, which can be very frequent (e.g. fast typing or mouse/drag movements). The default value is `128` milliseconds.                                                                                                                                                                                 |
  | `maxBuffering?`           | `number`                               | Configures the maximum amount of frames to store in memory before starting to drop old ones for in favor of the newer ones. It must be between `1` and `60`. The recommended is `2`. The default is `undefined` so it can be determined by the app (normally is set to the recommended setting).                                                                                                                                           |
  | `path?`                   | `string`                               | Optional path to append after the app id. Defaults to `/realtime`.                                                                                                                                                                                                                                                                                                                                                                         |
  | `encodeMessage?`          | `(input: any) => Uint8Array \| string` | Optional encoder for outgoing messages. Defaults to msgpack. Should return either a `Uint8Array` (binary) or string (text frame).                                                                                                                                                                                                                                                                                                          |
  | `decodeMessage?`          | `(data: any) => Promise<any> \| any`   | Optional decoder for incoming messages. Defaults to msgpack with JSON support for string payloads.                                                                                                                                                                                                                                                                                                                                         |
  | `tokenProvider?`          | `TokenProvider`                        | A custom token provider function. When provided, this function will be used to fetch authentication tokens instead of the default internal token fetching mechanism. This is useful when you want to fetch tokens through your own backend proxy. If not provided, the default `getTemporaryAuthToken` will be used.                                                                                                                       |
  | `tokenExpirationSeconds?` | `number`                               | The token expiration time in seconds. This is used to determine when to refresh the token. The token will be refreshed at 90% of this value. Only relevant when using a custom `tokenProvider`. If a custom `tokenProvider` is used without specifying this value, automatic token refresh will be disabled.                                                                                                                               |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### onResult

  ```typescript theme={null}
  onResult(result: Output & WithRequestId): void
  ```

  Callback function that is called when a result is received.

  | Parameter | Type                     | Description                  |
  | :-------- | :----------------------- | :--------------------------- |
  | `result`  | `Output & WithRequestId` | - The result of the request. |

  #### onError

  ```typescript theme={null}
  onError(error: ApiError<any>): void
  ```

  Callback function that is called when an error occurs.

  | Parameter | Type            | Description                |
  | :-------- | :-------------- | :------------------------- |
  | `error`   | `ApiError<any>` | - The error that occurred. |
</Accordion>

### RealtimeClient

```typescript theme={null}
interface RealtimeClient
```

<Accordion title="Methods" defaultOpen>
  #### connect

  ```typescript theme={null}
  connect(app: string, handler: RealtimeConnectionHandler<Output>): RealtimeConnection<Input>
  ```

  Connect to the realtime endpoint. The default implementation uses
  WebSockets to connect to fal function endpoints that support WSS.

  | Parameter | Type                                | Description                  |
  | :-------- | :---------------------------------- | :--------------------------- |
  | `app`     | `string`                            | the app alias or identifier. |
  | `handler` | `RealtimeConnectionHandler<Output>` | the connection handler.      |

  **Returns:** `RealtimeConnection<Input>`
</Accordion>

***

## Functions

### createRealtimeClient

```typescript theme={null}
function createRealtimeClient({ config, }: RealtimeClientDependencies): RealtimeClient
```

| Parameter     | Type                         | Description |
| :------------ | :--------------------------- | :---------- |
| `{ config, }` | `RealtimeClientDependencies` | -           |

**Returns:** `RealtimeClient`


# https://fal.ai/docs/api-reference/client-libraries/javascript/response.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# response

> API reference for @fal-ai/client response

## Classes & Interfaces

### ApiError

```typescript theme={null}
interface ApiError
```

<Accordion title="Properties" defaultOpen>
  | Name           | Type     | Description |
  | :------------- | :------- | :---------- |
  | `status`       | `number` | -           |
  | `body`         | `Body`   | -           |
  | `requestId`    | `string` | -           |
  | `timeoutType?` | `string` | -           |
</Accordion>

### ValidationError

```typescript theme={null}
interface ValidationError
```

<Accordion title="Methods" defaultOpen>
  #### getFieldErrors

  ```typescript theme={null}
  getFieldErrors(field: string): ValidationErrorInfo[]
  ```

  | Parameter | Type     | Description |
  | :-------- | :------- | :---------- |
  | `field`   | `string` | -           |

  **Returns:** `ValidationErrorInfo[]`
</Accordion>

***

## Functions

### defaultResponseHandler

```typescript theme={null}
async function defaultResponseHandler(response: Response): Promise<Output>
```

| Parameter  | Type       | Description |
| :--------- | :--------- | :---------- |
| `response` | `Response` | -           |

**Returns:** `Promise<Output>`

### resultResponseHandler

```typescript theme={null}
async function resultResponseHandler(response: Response): Promise<Result<Output>>
```

| Parameter  | Type       | Description |
| :--------- | :--------- | :---------- |
| `response` | `Response` | -           |

**Returns:** `Promise<Result<Output>>`

***

## Types

### ResponseHandler

```typescript theme={null}
type ResponseHandler = (response: Response) => Promise<Output>
```

### ResponseHandlerCreator

```typescript theme={null}
type ResponseHandlerCreator = (
  config: RequiredConfig,
) => ResponseHandler<Output>
```


# https://fal.ai/docs/api-reference/client-libraries/javascript/retry.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# retry

> API reference for @fal-ai/client retry

## Classes & Interfaces

### RetryMetrics

```typescript theme={null}
interface RetryMetrics
```

Retry metrics for tracking retry attempts

<Accordion title="Properties" defaultOpen>
  | Name            | Type     | Description |
  | :-------------- | :------- | :---------- |
  | `totalAttempts` | `number` | -           |
  | `totalDelay`    | `number` | -           |
  | `lastError?`    | `any`    | -           |
</Accordion>

***

## Functions

### isRetryableError

```typescript theme={null}
function isRetryableError(error: any, retryableStatusCodes: number[]): boolean
```

Determines if an error is retryable based on the status code.
User-specified timeouts (504 with X-Fal-Request-Timeout-Type: user) are NOT retryable.

| Parameter              | Type       | Description |
| :--------------------- | :--------- | :---------- |
| `error`                | `any`      | -           |
| `retryableStatusCodes` | `number[]` | -           |

**Returns:** `boolean`

### calculateBackoffDelay

```typescript theme={null}
function calculateBackoffDelay(attempt: number, baseDelay: number, maxDelay: number, backoffMultiplier: number, enableJitter: boolean): number
```

Calculates the backoff delay for a given attempt using exponential backoff

| Parameter           | Type      | Description |
| :------------------ | :-------- | :---------- |
| `attempt`           | `number`  | -           |
| `baseDelay`         | `number`  | -           |
| `maxDelay`          | `number`  | -           |
| `backoffMultiplier` | `number`  | -           |
| `enableJitter`      | `boolean` | -           |

**Returns:** `number`

### executeWithRetry

```typescript theme={null}
async function executeWithRetry(operation: () => Promise<T>, options: RetryOptions, onRetry?: (attempt: number, error: any, delay: number) => void): Promise<{ result: T; metrics: RetryMetrics }>
```

Executes an operation with retry logic and returns both result and metrics

| Parameter   | Type                                                   | Description |
| :---------- | :----------------------------------------------------- | :---------- |
| `operation` | `() => Promise<T>`                                     | -           |
| `options`   | `RetryOptions`                                         | -           |
| `onRetry`   | `(attempt: number, error: any, delay: number) => void` | -           |

**Returns:** `Promise<{ result: T; metrics: RetryMetrics }>`

***

## Types

### RetryOptions

```typescript theme={null}
type RetryOptions = {
  maxRetries: number;
  baseDelay: number;
  maxDelay: number;
  backoffMultiplier: number;
  retryableStatusCodes: number[];
  enableJitter: boolean;
}
```


# https://fal.ai/docs/api-reference/client-libraries/javascript/storage.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# storage

> API reference for @fal-ai/client storage

## Classes & Interfaces

### StorageSettings

```typescript theme={null}
interface StorageSettings
```

Configuration for object lifecycle and storage behavior.

<Accordion title="Properties" defaultOpen>
  | Name        | Type               | Description                                                                                                                           |
  | :---------- | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
  | `expiresIn` | `ObjectExpiration` | The expiration time for the stored files (images, videos, etc.). You can specify one of the enumerated values or a number of seconds. |
</Accordion>

### StorageClient

```typescript theme={null}
interface StorageClient
```

File support for the client. This interface establishes the contract for
uploading files to the server and transforming the input to replace file
objects with URLs.

<Accordion title="Properties" defaultOpen>
  | Name             | Type                                                           | Description                                                                                                                                                                                   |
  | :--------------- | :------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `upload`         | `(file: Blob, options?: UploadOptions) => Promise<string>`     | Upload a file to the server. Returns the URL of the uploaded file.                                                                                                                            |
  | `transformInput` | `(input: Record<string, any>) => Promise<Record<string, any>>` | Transform the input to replace file objects with URLs. This is used to transform the input before sending it to the server and ensures that the server receives URLs instead of file objects. |
</Accordion>

***

## Functions

### getExpirationDurationSeconds

```typescript theme={null}
function getExpirationDurationSeconds(lifecycle: StorageSettings): number | undefined
```

Converts an `StorageSettings` to the expiration duration in seconds.

| Parameter   | Type              | Description              |
| :---------- | :---------------- | :----------------------- |
| `lifecycle` | `StorageSettings` | the lifecycle preference |

**Returns:** `number | undefined`

### buildObjectLifecycleHeaders

```typescript theme={null}
function buildObjectLifecycleHeaders(lifecycle: StorageSettings | undefined): Record<string, string>
```

Builds the headers for the Object Lifecycle preference to be used in API requests.
This is used by the queue and run APIs to control the lifecycle of generated objects.

| Parameter   | Type                           | Description              |
| :---------- | :----------------------------- | :----------------------- |
| `lifecycle` | `StorageSettings \| undefined` | the lifecycle preference |

**Returns:** `Record<string, string>`

### createStorageClient

```typescript theme={null}
function createStorageClient({ config, }: StorageClientDependencies): StorageClient
```

| Parameter     | Type                        | Description |
| :------------ | :-------------------------- | :---------- |
| `{ config, }` | `StorageClientDependencies` | -           |

**Returns:** `StorageClient`

***

## Types

### UploadOptions

```typescript theme={null}
type UploadOptions = {
  /**
   * Custom lifecycle configuration for the uploaded file.
   * This object will be sent as the X-Fal-Object-Lifecycle header.
   */
  lifecycle?: StorageSettings;
}
```

Options for uploading a file.


# https://fal.ai/docs/api-reference/client-libraries/javascript/streaming.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# streaming

> API reference for @fal-ai/client streaming

## Classes & Interfaces

### FalStream

```typescript theme={null}
interface FalStream
```

The class representing a streaming response. With t

<Accordion title="Properties" defaultOpen>
  | Name                 | Type                                      | Description                                                                                                                                                                                                                                                                                  |
  | :------------------- | :---------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `config`             | `RequiredConfig`                          | -                                                                                                                                                                                                                                                                                            |
  | `endpointId`         | `string`                                  | -                                                                                                                                                                                                                                                                                            |
  | `url`                | `string`                                  | -                                                                                                                                                                                                                                                                                            |
  | `options`            | `StreamOptions<Input>`                    | -                                                                                                                                                                                                                                                                                            |
  | `listeners`          | `Map<FalStreamEventType, EventHandler[]>` | -                                                                                                                                                                                                                                                                                            |
  | `buffer`             | `Output[]`                                | -                                                                                                                                                                                                                                                                                            |
  | `currentData`        | `Output \| undefined`                     | -                                                                                                                                                                                                                                                                                            |
  | `lastEventTimestamp` | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `streamClosed`       | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `_requestId`         | `string \| null`                          | -                                                                                                                                                                                                                                                                                            |
  | `donePromise`        | `Promise<Output>`                         | -                                                                                                                                                                                                                                                                                            |
  | `abortController`    | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `start`              | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `handleResponse`     | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `handleError`        | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `on`                 | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `emit`               | `any`                                     | -                                                                                                                                                                                                                                                                                            |
  | `done`               | `any`                                     | Gets a reference to the `Promise` that indicates whether the streaming is done or not. Developers should always call this in their apps to ensure the request is over. An alternative to this, is to use `on('done')` in case your application architecture works best with event listeners. |
  | `abort`              | `any`                                     | Aborts the streaming request. **Note:** This method is noop in case the request is already done.                                                                                                                                                                                             |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### `[Symbol.asyncIterator]`

  ```typescript theme={null}
  async [Symbol.asyncIterator](): any
  ```

  **Returns:** `any`
</Accordion>

### StreamingClient

```typescript theme={null}
interface StreamingClient
```

The streaming client interface.

<Accordion title="Methods" defaultOpen>
  #### stream

  ```typescript theme={null}
  stream(endpointId: Id, options: StreamOptions<InputType<Id>>): Promise<FalStream<InputType<Id>, OutputType<Id>>>
  ```

  Calls a fal app that supports streaming and provides a streaming-capable
  object as a result, that can be used to get partial results through either
  `AsyncIterator` or through an event listener.

  | Parameter    | Type                           | Description                                       |
  | :----------- | :----------------------------- | :------------------------------------------------ |
  | `endpointId` | `Id`                           | the endpoint id, e.g. `fal-ai/llavav15-13b`.      |
  | `options`    | `StreamOptions<InputType<Id>>` | the request options, including the input payload. |

  **Returns:** `Promise<FalStream<InputType<Id>, OutputType<Id>>>`
</Accordion>

***

## Functions

### createStreamingClient

```typescript theme={null}
function createStreamingClient({ config, storage, }: StreamingClientDependencies): StreamingClient
```

| Parameter              | Type                          | Description |
| :--------------------- | :---------------------------- | :---------- |
| `{ config, storage, }` | `StreamingClientDependencies` | -           |

**Returns:** `StreamingClient`

***

## Types

### StreamingConnectionMode

```typescript theme={null}
type StreamingConnectionMode = "client" | "server"
```

### StreamOptions

```typescript theme={null}
type StreamOptions = {
  /**
   * The endpoint URL. If not provided, it will be generated from the
   * `endpointId` and the `queryParams`.
   */
  readonly url?: string;

  /**
   * The API input payload.
   */
  readonly input?: Input;

  /**
   * The query parameters to be sent with the request.
   */
  readonly queryParams?: Record<string, string>;

  /**
   * The maximum time interval in milliseconds between stream chunks. Defaults to 15s.
   */
  readonly timeout?: number;

  /**
   * Whether it should auto-upload File-like types to fal's storage
   * or not.
   */
  readonly autoUpload?: boolean;

  /**
   * The HTTP method, defaults to `post`;
   */
  readonly method?: "get" | "post" | "put" | "delete" | string;

  /**
   * The content type the client accepts as response.
   * By default this is set to `text/event-stream`.
   */
  readonly accept?: string;

  /**
   * The streaming connection mode. This is used to determine
   * whether the streaming will be done from the browser itself (client)
   * or through your own server, either when running on NodeJS or when
   * using a proxy that supports streaming.
   *
   * It defaults to `server`. Set to `client` if your server proxy doesn't
   * support streaming.
   */
  readonly connectionMode?: StreamingConnectionMode;

  /**
   * The signal to abort the request.
   */
  readonly signal?: AbortSignal;

  /**
   * A custom token provider function. Only used when `connectionMode` is `"client"`.
   * When provided, this function will be used to fetch authentication tokens
   * instead of the default internal token fetching mechanism.
   */
  readonly tokenProvider?: TokenProvider;
}
```

The stream API options. It requires the API input and also
offers configuration options.


# https://fal.ai/docs/api-reference/client-libraries/javascript/types.client.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# types.client

> API reference for @fal-ai/client types.client

***

## Types

### EndpointType

```typescript theme={null}
type EndpointType = keyof EndpointTypeMap | (string & {})
```

### InputType

```typescript theme={null}
type InputType = T extends keyof EndpointTypeMap
  ? EndpointTypeMap[T]["input"]
  : Record<string, any>
```

### OutputType

```typescript theme={null}
type OutputType = T extends keyof EndpointTypeMap
  ? EndpointTypeMap[T]["output"]
  : any
```


# https://fal.ai/docs/api-reference/client-libraries/javascript/types.common.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# types.common

> API reference for @fal-ai/client types.common

## Classes & Interfaces

### InQueueQueueStatus

```typescript theme={null}
interface InQueueQueueStatus
```

<Accordion title="Properties" defaultOpen>
  | Name             | Type         | Description |
  | :--------------- | :----------- | :---------- |
  | `status`         | `"IN_QUEUE"` | -           |
  | `queue_position` | `number`     | -           |
</Accordion>

### InProgressQueueStatus

```typescript theme={null}
interface InProgressQueueStatus
```

<Accordion title="Properties" defaultOpen>
  | Name     | Type            | Description |
  | :------- | :-------------- | :---------- |
  | `status` | `"IN_PROGRESS"` | -           |
  | `logs`   | `RequestLog[]`  | -           |
</Accordion>

### CompletedQueueStatus

```typescript theme={null}
interface CompletedQueueStatus
```

<Accordion title="Properties" defaultOpen>
  | Name       | Type           | Description |
  | :--------- | :------------- | :---------- |
  | `status`   | `"COMPLETED"`  | -           |
  | `logs`     | `RequestLog[]` | -           |
  | `metrics?` | `Metrics`      | -           |
</Accordion>

***

## Functions

### isQueueStatus

```typescript theme={null}
function isQueueStatus(obj: any): obj is QueueStatus
```

| Parameter | Type  | Description |
| :-------- | :---- | :---------- |
| `obj`     | `any` | -           |

**Returns:** `obj is QueueStatus`

### isCompletedQueueStatus

```typescript theme={null}
function isCompletedQueueStatus(obj: any): obj is CompletedQueueStatus
```

| Parameter | Type  | Description |
| :-------- | :---- | :---------- |
| `obj`     | `any` | -           |

**Returns:** `obj is CompletedQueueStatus`

***

## Types

### Result

```typescript theme={null}
type Result = {
  data: T;
  requestId: string;
}
```

Represents an API result, containing the data,
the request ID and any other relevant information.

### RunOptions

```typescript theme={null}
type RunOptions = {
  /**
   * The function input. It will be submitted either as query params
   * or the body payload, depending on the `method`.
   */
  readonly input?: Input;

  /**
   * The HTTP method, defaults to `post`;
   */
  readonly method?: "get" | "post" | "put" | "delete" | string;

  /**
   * The abort signal to cancel the request.
   */
  readonly abortSignal?: AbortSignal;

  /**
   * Object lifecycle configuration for controlling how long generated objects
   * (images, files, etc.) remain available before expiring.
   *
   * @see StorageSettings
   * @see https://docs.fal.ai/model-apis/model-endpoints/queue#object-lifecycle
   */
  readonly storageSettings?: StorageSettings;

  /**
   * Server-side request timeout in seconds. Limits total time spent waiting
   * before processing starts (includes queue wait, retries, and routing).
   * Does not apply once the application begins processing.
   *
   * This will be sent as the `x-fal-request-timeout` header.
   */
  readonly startTimeout?: number;
}
```

The function input and other configuration when running
the function, such as the HTTP method to use.

### UrlOptions

```typescript theme={null}
type UrlOptions = {
  /**
   * If `true`, the function will use the queue to run the function
   * asynchronously and return the result in a separate call. This
   * influences how the URL is built.
   */
  readonly subdomain?: string;

  /**
   * The query parameters to include in the URL.
   */
  readonly query?: Record<string, string>;

  /**
   * The path to append to the function URL.
   */
  path?: string;
}
```

### RequestLog

```typescript theme={null}
type RequestLog = {
  message: string;
  level: "STDERR" | "STDOUT" | "ERROR" | "INFO" | "WARN" | "DEBUG";
  source: "USER";
  timestamp: string; // Using string to represent date-time format, but you could also use 'Date' type if you're going to construct Date objects.
}
```

### Metrics

```typescript theme={null}
type Metrics = {
  inference_time: number | null;
}
```

### QueueStatus

```typescript theme={null}
type QueueStatus = | InProgressQueueStatus
  | CompletedQueueStatus
  | InQueueQueueStatus
```

### ValidationErrorInfo

```typescript theme={null}
type ValidationErrorInfo = {
  msg: string;
  loc: Array<string | number>;
  type: string;
}
```

### WebHookResponse

```typescript theme={null}
type WebHookResponse = | {
      /** Indicates a successful response. */
      status: "OK";
      /** The payload of the response, structure determined by the Payload type. */
      payload: Payload;
      /** Error is never present in a successful response. */
      error: never;
      /** The unique identifier for the request. */
      request_id: string;
    }
  | {
      /** Indicates an unsuccessful response. */
      status: "ERROR";
      /** The payload of the response, structure determined by the Payload type. */
      payload: Payload;
      /** Description of the error that occurred. */
      error: string;
      /** The unique identifier for the request. */
      request_id: string;
    }
```

Represents the response from a WebHook request.
This is a union type that varies based on the `status` property.


# https://fal.ai/docs/api-reference/client-libraries/javascript/utils.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# utils

> API reference for @fal-ai/client utils

***

## Functions

### ensureEndpointIdFormat

```typescript theme={null}
function ensureEndpointIdFormat(id: string): string
```

| Parameter | Type     | Description |
| :-------- | :------- | :---------- |
| `id`      | `string` | -           |

**Returns:** `string`

### parseEndpointId

```typescript theme={null}
function parseEndpointId(id: string): EndpointId
```

| Parameter | Type     | Description |
| :-------- | :------- | :---------- |
| `id`      | `string` | -           |

**Returns:** `EndpointId`

### isValidUrl

```typescript theme={null}
function isValidUrl(url: string): any
```

| Parameter | Type     | Description |
| :-------- | :------- | :---------- |
| `url`     | `string` | -           |

**Returns:** `any`

### throttle

```typescript theme={null}
function throttle(func: T, limit: number, leading?: any): (...funcArgs: Parameters<T>) => ReturnType<T> | void
```

| Parameter | Type     | Description |
| :-------- | :------- | :---------- |
| `func`    | `T`      | -           |
| `limit`   | `number` | -           |
| `leading` | `any`    | -           |

**Returns:** `(...funcArgs: Parameters<T>) => ReturnType<T> | void`

### isReact

```typescript theme={null}
function isReact(): any
```

Not really the most optimal way to detect if we're running in React,
but the idea here is that we can support multiple rendering engines
(starting with React), with all their peculiarities, without having
to add a dependency or creating custom integrations (e.g. custom hooks).

Yes, a bit of magic to make things works out-of-the-box.

**Returns:** `any`

### isPlainObject

```typescript theme={null}
function isPlainObject(value: any): boolean
```

Check if a value is a plain object.

| Parameter | Type  | Description           |
| :-------- | :---- | :-------------------- |
| `value`   | `any` | - The value to check. |

**Returns:** `boolean`

### sleep

```typescript theme={null}
async function sleep(ms: number): Promise<void>
```

Utility function to sleep for a given number of milliseconds

| Parameter | Type     | Description |
| :-------- | :------- | :---------- |
| `ms`      | `number` | -           |

**Returns:** `Promise<void>`

***

## Types

### EndpointId

```typescript theme={null}
type EndpointId = {
  readonly owner: string;
  readonly alias: string;
  readonly path?: string;
  readonly namespace?: EndpointNamespace;
}
```


# https://fal.ai/docs/api-reference/client-libraries/kotlin/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kotlin / Java Client

> fal client library for Android and JVM applications

The `fal-client` packages provide Kotlin and Java interfaces for calling fal AI models on Android and JVM platforms.

## Installation

<CodeGroup>
  ```groovy Gradle (Kotlin) theme={null}
  implementation 'ai.fal.client:fal-client-kotlin:0.7.1'
  ```

  ```groovy Gradle (Java) theme={null}
  implementation 'ai.fal.client:fal-client:0.7.1'
  ```

  ```xml Maven (Kotlin) theme={null}
  <dependency>
    <groupId>ai.fal.client</groupId>
    <artifactId>fal-client-kotlin</artifactId>
    <version>0.7.1</version>
  </dependency>
  ```

  ```xml Maven (Java) theme={null}
  <dependency>
    <groupId>ai.fal.client</groupId>
    <artifactId>fal-client</artifactId>
    <version>0.7.1</version>
  </dependency>
  ```
</CodeGroup>

<Note>
  **Java Async Support**

  If your code relies on asynchronous operations via `CompletableFuture` or `Future`, use the `ai.fal.client:fal-client-async` artifact instead.
</Note>

## Quick Start

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import ai.fal.client.kt

  val fal = createFalClient()

  val input = mapOf<String, Any>(
      "prompt" to "a cat",
      "seed" to 6252023,
      "image_size" to "landscape_4_3",
      "num_images" to 4
  )
  val result = fal.subscribe("fal-ai/flux/dev", input, options = SubscribeOptions(
      logs = true
  )) { update ->
      if (update is QueueStatus.InProgress) {
          println(update.logs)
      }
  }
  ```

  ```java Java theme={null}
  import ai.fal.client.*;
  import ai.fal.client.queue.*;

  var fal = FalClient.withEnvCredentials();

  var input = Map.of(
      "prompt", "a cat",
      "seed", 6252023,
      "image_size", "landscape_4_3",
      "num_images", 4
  );
  var result = fal.subscribe("fal-ai/flux/dev",
      SubscribeOptions.<JsonObject>builder()
          .input(input)
          .logs(true)
          .resultType(JsonObject.class)
          .onQueueUpdate(update -> {
              if (update instanceof QueueStatus.InProgress) {
                  System.out.println(((QueueStatus.InProgress) update).getLogs());
              }
          })
          .build()
  );
  ```
</CodeGroup>

## Supported Platforms

* Android (API 21+)
* JVM (Java 11+)
* Kotlin Multiplatform (JVM target)

## API Reference

<CardGroup cols={2}>
  <Card title="Java API Reference" icon="book" href="https://fal-ai.github.io/fal-java/fal-client/index.html">
    JavaDoc documentation
  </Card>

  <Card title="Kotlin API Reference" icon="book" href="https://fal-ai.github.io/fal-java/fal-client-kotlin/fal-client-kotlin/ai.fal.client.kt/index.html">
    KDoc documentation
  </Card>
</CardGroup>

<Card title="GitHub Repository" icon="github" href="https://github.com/fal-ai/fal-java">
  Source code and examples
</Card>


# https://fal.ai/docs/api-reference/client-libraries/python/fal_client.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal_client

> API reference for fal_client

```python theme={null}
from fal_client import (
    SyncClient,
    AsyncClient,
    RealtimeConnection,
    AsyncRealtimeConnection,
    Status,
    Queued,
    InProgress,
    Completed,
    SyncRequestHandle,
    AsyncRequestHandle,
    run,
    subscribe_async,
    subscribe,
    submit,
    stream,
    run_async,
    submit_async,
    stream_async,
    realtime,
    realtime_async,
    cancel,
    cancel_async,
    status,
    status_async,
    result,
    result_async,
    encode,
    encode_file,
    encode_image,
)
```

## Classes

### SyncClient

```python theme={null}
class fal_client.SyncClient
```

<Accordion title="Constructor Parameters" defaultOpen>
  | Name              | Type          | Default | Description |
  | :---------------- | :------------ | :------ | :---------- |
  | `key`             | `str \| None` | `None`  | -           |
  | `default_timeout` | `float`       | `120.0` | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name              | Type          | Default | Description |
  | :---------------- | :------------ | :------ | :---------- |
  | `key`             | `str \| None` | `None`  | -           |
  | `default_timeout` | `float`       | `120.0` | -           |
</Accordion>

<Accordion title="Properties" defaultOpen>
  | Name        | Type                 | Description |
  | :---------- | :------------------- | :---------- |
  | `_executor` | `ThreadPoolExecutor` | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### cancel

  ```python theme={null}
  def cancel(self, application: 'str', request_id: 'str') -> 'None'
  ```

  | Parameter     | Type  | Default | Description |
  | :------------ | :---- | :------ | :---------- |
  | `application` | `str` | -       | -           |
  | `request_id`  | `str` | -       | -           |

  **Returns:** `NoneType`

  #### get\_handle

  ```python theme={null}
  def get_handle(self, application: 'str', request_id: 'str') -> 'SyncRequestHandle'
  ```

  | Parameter     | Type  | Default | Description |
  | :------------ | :---- | :------ | :---------- |
  | `application` | `str` | -       | -           |
  | `request_id`  | `str` | -       | -           |

  **Returns:** `SyncRequestHandle`

  #### realtime

  ```python theme={null}
  def realtime(self, application: 'str', *, use_jwt: 'bool' = True, path: 'str' = '/realtime', max_buffering: 'int | None' = None, token_expiration: 'int' = 120, encode_message: 'Callable[[Any], bytes] | None' = None, decode_message: 'Callable[[bytes], Any] | None' = None) -> 'Iterator[RealtimeConnection]'
  ```

  | Parameter          | Type                             | Default       | Description |
  | :----------------- | :------------------------------- | :------------ | :---------- |
  | `application`      | `str`                            | -             | -           |
  | `use_jwt`          | `bool`                           | `True`        | -           |
  | `path`             | `str`                            | `'/realtime'` | -           |
  | `max_buffering`    | `int \| None`                    | `None`        | -           |
  | `token_expiration` | `int`                            | `120`         | -           |
  | `encode_message`   | `Optional[Callable[Any, bytes]]` | `None`        | -           |
  | `decode_message`   | `Optional[Callable[bytes, Any]]` | `None`        | -           |

  **Returns:** `Iterator[RealtimeConnection]`

  #### result

  ```python theme={null}
  def result(self, application: 'str', request_id: 'str') -> 'AnyJSON'
  ```

  | Parameter     | Type  | Default | Description |
  | :------------ | :---- | :------ | :---------- |
  | `application` | `str` | -       | -           |
  | `request_id`  | `str` | -       | -           |

  **Returns:** `dict[str, Any]`

  #### run

  ```python theme={null}
  def run(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', timeout: 'Optional[Union[int, float]]' = None, start_timeout: 'Optional[Union[int, float]]' = None, hint: 'str | None' = None, headers: 'dict[str, str]' = {}) -> 'AnyJSON'
  ```

  Run an application with the given arguments (which will be JSON serialized).

  | Parameter       | Type                       | Default | Description                                                                                                                                              |
  | :-------------- | :------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `application`   | `str`                      | -       | -                                                                                                                                                        |
  | `arguments`     | `dict[str, Any]`           | -       | -                                                                                                                                                        |
  | `path`          | `str`                      | `''`    | -                                                                                                                                                        |
  | `timeout`       | `int \| float \| NoneType` | `None`  | Client-side HTTP timeout in seconds. Controls how long the HTTP client waits for a response. Defaults to the client's default\_timeout.                  |
  | `start_timeout` | `int \| float \| NoneType` | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts. Does not apply once the application begins processing. |
  | `hint`          | `str \| None`              | `None`  | -                                                                                                                                                        |
  | `headers`       | `dict[str, str]`           | `\{\}`  | -                                                                                                                                                        |

  **Returns:** `dict[str, Any]`

  #### status

  ```python theme={null}
  def status(self, application: 'str', request_id: 'str', *, with_logs: 'bool' = False) -> 'Status'
  ```

  | Parameter     | Type   | Default | Description |
  | :------------ | :----- | :------ | :---------- |
  | `application` | `str`  | -       | -           |
  | `request_id`  | `str`  | -       | -           |
  | `with_logs`   | `bool` | `False` | -           |

  **Returns:** `Status`

  #### stream

  ```python theme={null}
  def stream(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '/stream', timeout: 'float | None' = None) -> 'Iterator[dict[str, Any]]'
  ```

  Stream the output of an application with the given arguments (which will be JSON serialized). This is only supported at a few select applications at the moment, so be sure to first consult with the documentation of individual applications
  to see if this is supported.

  The function will iterate over each event that is streamed from the server.

  | Parameter     | Type             | Default     | Description |
  | :------------ | :--------------- | :---------- | :---------- |
  | `application` | `str`            | -           | -           |
  | `arguments`   | `dict[str, Any]` | -           | -           |
  | `path`        | `str`            | `'/stream'` | -           |
  | `timeout`     | `float \| None`  | `None`      | -           |

  **Returns:** `Iterator[dict[str, Any]]`

  #### submit

  ```python theme={null}
  def submit(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, webhook_url: 'str | None' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None) -> 'SyncRequestHandle'
  ```

  Submit an application with the given arguments (which will be JSON serialized).

  | Parameter       | Type                             | Default | Description                                                                                                                                                                                          |
  | :-------------- | :------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `application`   | `str`                            | -       | -                                                                                                                                                                                                    |
  | `arguments`     | `dict[str, Any]`                 | -       | -                                                                                                                                                                                                    |
  | `path`          | `str`                            | `''`    | -                                                                                                                                                                                                    |
  | `hint`          | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
  | `webhook_url`   | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
  | `priority`      | `Optional[Literal[normal, low]]` | `None`  | -                                                                                                                                                                                                    |
  | `headers`       | `dict[str, str]`                 | `\{\}`  | -                                                                                                                                                                                                    |
  | `start_timeout` | `int \| float \| NoneType`       | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |

  **Returns:** `SyncRequestHandle`

  #### subscribe

  ```python theme={null}
  def subscribe(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, with_logs: 'bool' = False, on_enqueue: 'Optional[Callable[[str], None]]' = None, on_queue_update: 'Optional[Callable[[Status], None]]' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None, client_timeout: 'Optional[Union[int, float]]' = None) -> 'AnyJSON'
  ```

  Subscribe to an application and wait for the result.

  | Parameter         | Type                                   | Default | Description                                                                                                                                                                                          |
  | :---------------- | :------------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `application`     | `str`                                  | -       | -                                                                                                                                                                                                    |
  | `arguments`       | `dict[str, Any]`                       | -       | -                                                                                                                                                                                                    |
  | `path`            | `str`                                  | `''`    | -                                                                                                                                                                                                    |
  | `hint`            | `str \| None`                          | `None`  | -                                                                                                                                                                                                    |
  | `with_logs`       | `bool`                                 | `False` | -                                                                                                                                                                                                    |
  | `on_enqueue`      | `Optional[Callable[str, NoneType]]`    | `None`  | -                                                                                                                                                                                                    |
  | `on_queue_update` | `Optional[Callable[Status, NoneType]]` | `None`  | -                                                                                                                                                                                                    |
  | `priority`        | `Optional[Literal[normal, low]]`       | `None`  | -                                                                                                                                                                                                    |
  | `headers`         | `dict[str, str]`                       | `\{\}`  | -                                                                                                                                                                                                    |
  | `start_timeout`   | `int \| float \| NoneType`             | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |
  | `client_timeout`  | `int \| float \| NoneType`             | `None`  | Client-side total timeout in seconds. Limits the total time spent waiting for the entire request to complete (including queue wait and processing). If not set, waits indefinitely.                  |

  **Returns:** `dict[str, Any]`

  #### upload

  ```python theme={null}
  def upload(self, data: 'str | bytes', content_type: 'str', file_name: 'str | None' = None, *, repository: 'UploadRepositoryId | None' = None, fallback_repository: 'UploadRepositoryId | list[UploadRepositoryId] | None' = None) -> 'str'
  ```

  Upload the given data blob to the CDN and return the access URL. The content type should be specified as the second argument. Use upload\_file or upload\_image for convenience.

  | Parameter             | Type                                                                       | Default | Description |
  | :-------------------- | :------------------------------------------------------------------------- | :------ | :---------- |
  | `data`                | `str \| bytes`                                                             | -       | -           |
  | `content_type`        | `str`                                                                      | -       | -           |
  | `file_name`           | `str \| None`                                                              | `None`  | -           |
  | `repository`          | `Optional[Literal[fal_v3, cdn, fal]]`                                      | `None`  | -           |
  | `fallback_repository` | `Literal[fal_v3, cdn, fal] \| list[Literal[fal_v3, cdn, fal]] \| NoneType` | `None`  | -           |

  **Returns:** `str`

  #### upload\_file

  ```python theme={null}
  def upload_file(self, path: 'os.PathLike', *, repository: 'UploadRepositoryId | None' = None, fallback_repository: 'UploadRepositoryId | list[UploadRepositoryId] | None' = None) -> 'str'
  ```

  Upload a file from the local filesystem to the CDN and return the access URL.

  | Parameter             | Type                                                                       | Default | Description |
  | :-------------------- | :------------------------------------------------------------------------- | :------ | :---------- |
  | `path`                | `PathLike`                                                                 | -       | -           |
  | `repository`          | `Optional[Literal[fal_v3, cdn, fal]]`                                      | `None`  | -           |
  | `fallback_repository` | `Literal[fal_v3, cdn, fal] \| list[Literal[fal_v3, cdn, fal]] \| NoneType` | `None`  | -           |

  **Returns:** `str`

  #### upload\_image

  ```python theme={null}
  def upload_image(self, image: 'Image.Image', format: 'str' = 'jpeg', *, repository: 'UploadRepositoryId | None' = None, fallback_repository: 'UploadRepositoryId | list[UploadRepositoryId] | None' = None) -> 'str'
  ```

  Upload a pillow image object to the CDN and return the access URL.

  | Parameter             | Type                                                     | Default  | Description |
  | :-------------------- | :------------------------------------------------------- | :------- | :---------- |
  | `image`               | `Image.Image`                                            | -        | -           |
  | `format`              | `str`                                                    | `'jpeg'` | -           |
  | `repository`          | `UploadRepositoryId \| None`                             | `None`   | -           |
  | `fallback_repository` | `UploadRepositoryId \| list[UploadRepositoryId] \| None` | `None`   | -           |

  #### ws\_connect

  ```python theme={null}
  def ws_connect(self, application: 'str', *, use_jwt: 'bool' = True, path: 'str' = '', max_buffering: 'int | None' = None, token_expiration: 'int' = 120) -> "Iterator['Connection']"
  ```

  | Parameter          | Type          | Default | Description |
  | :----------------- | :------------ | :------ | :---------- |
  | `application`      | `str`         | -       | -           |
  | `use_jwt`          | `bool`        | `True`  | -           |
  | `path`             | `str`         | `''`    | -           |
  | `max_buffering`    | `int \| None` | `None`  | -           |
  | `token_expiration` | `int`         | `120`   | -           |
</Accordion>

### AsyncClient

```python theme={null}
class fal_client.AsyncClient
```

<Accordion title="Constructor Parameters" defaultOpen>
  | Name              | Type          | Default | Description |
  | :---------------- | :------------ | :------ | :---------- |
  | `key`             | `str \| None` | `None`  | -           |
  | `default_timeout` | `float`       | `120.0` | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name              | Type          | Default | Description |
  | :---------------- | :------------ | :------ | :---------- |
  | `key`             | `str \| None` | `None`  | -           |
  | `default_timeout` | `float`       | `120.0` | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### cancel

  ```python theme={null}
  async def cancel(self, application: 'str', request_id: 'str') -> 'None'
  ```

  | Parameter     | Type  | Default | Description |
  | :------------ | :---- | :------ | :---------- |
  | `application` | `str` | -       | -           |
  | `request_id`  | `str` | -       | -           |

  **Returns:** `NoneType`

  #### get\_handle

  ```python theme={null}
  def get_handle(self, application: 'str', request_id: 'str') -> 'AsyncRequestHandle'
  ```

  | Parameter     | Type  | Default | Description |
  | :------------ | :---- | :------ | :---------- |
  | `application` | `str` | -       | -           |
  | `request_id`  | `str` | -       | -           |

  **Returns:** `AsyncRequestHandle`

  #### realtime

  ```python theme={null}
  def realtime(self, application: 'str', *, use_jwt: 'bool' = True, path: 'str' = '/realtime', max_buffering: 'int | None' = None, token_expiration: 'int' = 120, encode_message: 'Callable[[Any], bytes] | None' = None, decode_message: 'Callable[[bytes], Any] | None' = None) -> 'AsyncIterator[AsyncRealtimeConnection]'
  ```

  | Parameter          | Type                             | Default       | Description |
  | :----------------- | :------------------------------- | :------------ | :---------- |
  | `application`      | `str`                            | -             | -           |
  | `use_jwt`          | `bool`                           | `True`        | -           |
  | `path`             | `str`                            | `'/realtime'` | -           |
  | `max_buffering`    | `int \| None`                    | `None`        | -           |
  | `token_expiration` | `int`                            | `120`         | -           |
  | `encode_message`   | `Optional[Callable[Any, bytes]]` | `None`        | -           |
  | `decode_message`   | `Optional[Callable[bytes, Any]]` | `None`        | -           |

  **Returns:** `AsyncIterator[AsyncRealtimeConnection]`

  #### result

  ```python theme={null}
  async def result(self, application: 'str', request_id: 'str') -> 'AnyJSON'
  ```

  | Parameter     | Type  | Default | Description |
  | :------------ | :---- | :------ | :---------- |
  | `application` | `str` | -       | -           |
  | `request_id`  | `str` | -       | -           |

  **Returns:** `dict[str, Any]`

  #### run

  ```python theme={null}
  async def run(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', timeout: 'Optional[Union[int, float]]' = None, start_timeout: 'Optional[Union[int, float]]' = None, hint: 'str | None' = None, headers: 'dict[str, str]' = {}) -> 'AnyJSON'
  ```

  Run an application with the given arguments (which will be JSON serialized). The path parameter can be used to specify a subpath when applicable. This method will return the result of the inference call directly.

  | Parameter       | Type                       | Default | Description                                                                                                                                              |
  | :-------------- | :------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `application`   | `str`                      | -       | -                                                                                                                                                        |
  | `arguments`     | `dict[str, Any]`           | -       | -                                                                                                                                                        |
  | `path`          | `str`                      | `''`    | -                                                                                                                                                        |
  | `timeout`       | `int \| float \| NoneType` | `None`  | Client-side HTTP timeout in seconds. Controls how long the HTTP client waits for a response. Defaults to the client's default\_timeout.                  |
  | `start_timeout` | `int \| float \| NoneType` | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts. Does not apply once the application begins processing. |
  | `hint`          | `str \| None`              | `None`  | -                                                                                                                                                        |
  | `headers`       | `dict[str, str]`           | `\{\}`  | -                                                                                                                                                        |

  **Returns:** `dict[str, Any]`

  #### status

  ```python theme={null}
  async def status(self, application: 'str', request_id: 'str', *, with_logs: 'bool' = False) -> 'Status'
  ```

  | Parameter     | Type   | Default | Description |
  | :------------ | :----- | :------ | :---------- |
  | `application` | `str`  | -       | -           |
  | `request_id`  | `str`  | -       | -           |
  | `with_logs`   | `bool` | `False` | -           |

  **Returns:** `Status`

  #### stream

  ```python theme={null}
  def stream(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '/stream', timeout: 'float | None' = None) -> 'AsyncIterator[dict[str, Any]]'
  ```

  Stream the output of an application with the given arguments (which will be JSON serialized). This is only supported at a few select applications at the moment, so be sure to first consult with the documentation of individual applications
  to see if this is supported.

  The function will iterate over each event that is streamed from the server.

  | Parameter     | Type             | Default     | Description |
  | :------------ | :--------------- | :---------- | :---------- |
  | `application` | `str`            | -           | -           |
  | `arguments`   | `dict[str, Any]` | -           | -           |
  | `path`        | `str`            | `'/stream'` | -           |
  | `timeout`     | `float \| None`  | `None`      | -           |

  **Returns:** `AsyncIterator[dict[str, Any]]`

  #### submit

  ```python theme={null}
  async def submit(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, webhook_url: 'str | None' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None) -> 'AsyncRequestHandle'
  ```

  Submit an application with the given arguments (which will be JSON serialized). The path parameter can be used to specify a subpath when applicable. This method will return a handle to the request that can be used to check the status
  and retrieve the result of the inference call when it is done.

  | Parameter       | Type                             | Default | Description                                                                                                                                                                                          |
  | :-------------- | :------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `application`   | `str`                            | -       | -                                                                                                                                                                                                    |
  | `arguments`     | `dict[str, Any]`                 | -       | -                                                                                                                                                                                                    |
  | `path`          | `str`                            | `''`    | -                                                                                                                                                                                                    |
  | `hint`          | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
  | `webhook_url`   | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
  | `priority`      | `Optional[Literal[normal, low]]` | `None`  | -                                                                                                                                                                                                    |
  | `headers`       | `dict[str, str]`                 | `\{\}`  | -                                                                                                                                                                                                    |
  | `start_timeout` | `int \| float \| NoneType`       | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |

  **Returns:** `AsyncRequestHandle`

  #### subscribe

  ```python theme={null}
  async def subscribe(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, with_logs: 'bool' = False, on_enqueue: 'Optional[Callable[[str], None]]' = None, on_queue_update: 'Optional[Callable[[Status], None]]' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None, client_timeout: 'Optional[Union[int, float]]' = None) -> 'AnyJSON'
  ```

  Subscribe to an application and wait for the result.

  | Parameter         | Type                                   | Default | Description                                                                                                                                                                                          |
  | :---------------- | :------------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `application`     | `str`                                  | -       | -                                                                                                                                                                                                    |
  | `arguments`       | `dict[str, Any]`                       | -       | -                                                                                                                                                                                                    |
  | `path`            | `str`                                  | `''`    | -                                                                                                                                                                                                    |
  | `hint`            | `str \| None`                          | `None`  | -                                                                                                                                                                                                    |
  | `with_logs`       | `bool`                                 | `False` | -                                                                                                                                                                                                    |
  | `on_enqueue`      | `Optional[Callable[str, NoneType]]`    | `None`  | -                                                                                                                                                                                                    |
  | `on_queue_update` | `Optional[Callable[Status, NoneType]]` | `None`  | -                                                                                                                                                                                                    |
  | `priority`        | `Optional[Literal[normal, low]]`       | `None`  | -                                                                                                                                                                                                    |
  | `headers`         | `dict[str, str]`                       | `\{\}`  | -                                                                                                                                                                                                    |
  | `start_timeout`   | `int \| float \| NoneType`             | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |
  | `client_timeout`  | `int \| float \| NoneType`             | `None`  | Client-side total timeout in seconds. Limits the total time spent waiting for the entire request to complete (including queue wait and processing). If not set, waits indefinitely.                  |

  **Returns:** `dict[str, Any]`

  #### upload

  ```python theme={null}
  async def upload(self, data: 'str | bytes', content_type: 'str', file_name: 'str | None' = None, *, repository: 'UploadRepositoryId | None' = None, fallback_repository: 'UploadRepositoryId | list[UploadRepositoryId] | None' = None) -> 'str'
  ```

  Upload the given data blob to the CDN and return the access URL. The content type should be specified as the second argument. Use upload\_file or upload\_image for convenience.

  | Parameter             | Type                                                                       | Default | Description |
  | :-------------------- | :------------------------------------------------------------------------- | :------ | :---------- |
  | `data`                | `str \| bytes`                                                             | -       | -           |
  | `content_type`        | `str`                                                                      | -       | -           |
  | `file_name`           | `str \| None`                                                              | `None`  | -           |
  | `repository`          | `Optional[Literal[fal_v3, cdn, fal]]`                                      | `None`  | -           |
  | `fallback_repository` | `Literal[fal_v3, cdn, fal] \| list[Literal[fal_v3, cdn, fal]] \| NoneType` | `None`  | -           |

  **Returns:** `str`

  #### upload\_file

  ```python theme={null}
  async def upload_file(self, path: 'os.PathLike', *, repository: 'UploadRepositoryId | None' = None, fallback_repository: 'UploadRepositoryId | list[UploadRepositoryId] | None' = None) -> 'str'
  ```

  Upload a file from the local filesystem to the CDN and return the access URL.

  | Parameter             | Type                                                                       | Default | Description |
  | :-------------------- | :------------------------------------------------------------------------- | :------ | :---------- |
  | `path`                | `PathLike`                                                                 | -       | -           |
  | `repository`          | `Optional[Literal[fal_v3, cdn, fal]]`                                      | `None`  | -           |
  | `fallback_repository` | `Literal[fal_v3, cdn, fal] \| list[Literal[fal_v3, cdn, fal]] \| NoneType` | `None`  | -           |

  **Returns:** `str`

  #### upload\_image

  ```python theme={null}
  async def upload_image(self, image: 'Image.Image', format: 'str' = 'jpeg', *, repository: 'UploadRepositoryId | None' = None, fallback_repository: 'UploadRepositoryId | list[UploadRepositoryId] | None' = None) -> 'str'
  ```

  Upload a pillow image object to the CDN and return the access URL.

  | Parameter             | Type                                                     | Default  | Description |
  | :-------------------- | :------------------------------------------------------- | :------- | :---------- |
  | `image`               | `Image.Image`                                            | -        | -           |
  | `format`              | `str`                                                    | `'jpeg'` | -           |
  | `repository`          | `UploadRepositoryId \| None`                             | `None`   | -           |
  | `fallback_repository` | `UploadRepositoryId \| list[UploadRepositoryId] \| None` | `None`   | -           |

  #### ws\_connect

  ```python theme={null}
  def ws_connect(self, application: 'str', *, use_jwt: 'bool' = True, path: 'str' = '', max_buffering: 'int | None' = None, token_expiration: 'int' = 120) -> "AsyncIterator['WebSocketClientProtocol']"
  ```

  | Parameter          | Type          | Default | Description |
  | :----------------- | :------------ | :------ | :---------- |
  | `application`      | `str`         | -       | -           |
  | `use_jwt`          | `bool`        | `True`  | -           |
  | `path`             | `str`         | `''`    | -           |
  | `max_buffering`    | `int \| None` | `None`  | -           |
  | `token_expiration` | `int`         | `120`   | -           |
</Accordion>

### RealtimeConnection

```python theme={null}
class fal_client.RealtimeConnection
```

Synchronous realtime connection wrapper.

<Accordion title="Constructor Parameters" defaultOpen>
  | Name              | Type                             | Default | Description |
  | :---------------- | :------------------------------- | :------ | :---------- |
  | `_ws`             | `'Connection'`                   | -       | -           |
  | `_encode_message` | `Callable[[Any], bytes] \| None` | `None`  | -           |
  | `_decode_message` | `Callable[[bytes], Any] \| None` | `None`  | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### close

  ```python theme={null}
  def close(self) -> 'None'
  ```

  **Returns:** `NoneType`

  #### recv

  ```python theme={null}
  def recv(self) -> 'dict[str, Any] | None'
  ```

  **Returns:** `dict[str, Any] | None`

  #### send

  ```python theme={null}
  def send(self, arguments: 'dict[str, Any]') -> 'None'
  ```

  | Parameter   | Type             | Default | Description |
  | :---------- | :--------------- | :------ | :---------- |
  | `arguments` | `dict[str, Any]` | -       | -           |

  **Returns:** `NoneType`
</Accordion>

### AsyncRealtimeConnection

```python theme={null}
class fal_client.AsyncRealtimeConnection
```

Asynchronous realtime connection wrapper.

<Accordion title="Constructor Parameters" defaultOpen>
  | Name              | Type                             | Default | Description |
  | :---------------- | :------------------------------- | :------ | :---------- |
  | `_ws`             | `'WebSocketClientProtocol'`      | -       | -           |
  | `_encode_message` | `Callable[[Any], bytes] \| None` | `None`  | -           |
  | `_decode_message` | `Callable[[bytes], Any] \| None` | `None`  | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### close

  ```python theme={null}
  async def close(self) -> 'None'
  ```

  **Returns:** `NoneType`

  #### recv

  ```python theme={null}
  async def recv(self) -> 'dict[str, Any] | None'
  ```

  **Returns:** `dict[str, Any] | None`

  #### send

  ```python theme={null}
  async def send(self, arguments: 'dict[str, Any]') -> 'None'
  ```

  | Parameter   | Type             | Default | Description |
  | :---------- | :--------------- | :------ | :---------- |
  | `arguments` | `dict[str, Any]` | -       | -           |

  **Returns:** `NoneType`
</Accordion>

### Status

```python theme={null}
class fal_client.Status
```

### Queued

```python theme={null}
class fal_client.Queued
```

Indicates the request is enqueued and waiting to be processed. The position field indicates the relative position in the queue (0-indexed).

> **Inherits from:** `Status`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name       | Type  | Default | Description |
  | :--------- | :---- | :------ | :---------- |
  | `position` | `int` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name       | Type  | Default | Description |
  | :--------- | :---- | :------ | :---------- |
  | `position` | `int` | -       | -           |
</Accordion>

### InProgress

```python theme={null}
class fal_client.InProgress
```

Indicates the request is currently being processed. If the status operation called with the `with_logs` parameter set to True, the logs field will be a list of
log objects.

> **Inherits from:** `Status`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type                           | Default | Description |
  | :----- | :----------------------------- | :------ | :---------- |
  | `logs` | `list[dict[str, Any]] \| None` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name   | Type                           | Default | Description |
  | :----- | :----------------------------- | :------ | :---------- |
  | `logs` | `list[dict[str, Any]] \| None` | -       | -           |
</Accordion>

### Completed

```python theme={null}
class fal_client.Completed
```

Indicates the request has been completed and the result can be gathered. The logs field will contain the logs if the status operation was called with the `with_logs` parameter set to True. Metrics
might contain the inference time, and other internal metadata (number of tokens
processed, etc.).

> **Inherits from:** `Status`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name      | Type                           | Default | Description |
  | :-------- | :----------------------------- | :------ | :---------- |
  | `logs`    | `list[dict[str, Any]] \| None` | -       | -           |
  | `metrics` | `dict[str, Any]`               | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name      | Type                           | Default | Description |
  | :-------- | :----------------------------- | :------ | :---------- |
  | `logs`    | `list[dict[str, Any]] \| None` | -       | -           |
  | `metrics` | `dict[str, Any]`               | -       | -           |
</Accordion>

### SyncRequestHandle

```python theme={null}
class fal_client.SyncRequestHandle
```

> **Inherits from:** `_BaseRequestHandle`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name           | Type     | Default | Description |
  | :------------- | :------- | :------ | :---------- |
  | `request_id`   | `str`    | -       | -           |
  | `response_url` | `str`    | -       | -           |
  | `status_url`   | `str`    | -       | -           |
  | `cancel_url`   | `str`    | -       | -           |
  | `client`       | `Client` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name     | Type           | Default | Description |
  | :------- | :------------- | :------ | :---------- |
  | `client` | `httpx.Client` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### cancel

  ```python theme={null}
  def cancel(self) -> 'None'
  ```

  Cancel the request.

  **Returns:** `NoneType`

  #### from\_request\_id

  ```python theme={null}
  def from_request_id(cls, client: 'httpx.Client', application: 'str', request_id: 'str') -> 'SyncRequestHandle'
  ```

  | Parameter     | Type     | Default | Description |
  | :------------ | :------- | :------ | :---------- |
  | `client`      | `Client` | -       | -           |
  | `application` | `str`    | -       | -           |
  | `request_id`  | `str`    | -       | -           |

  **Returns:** `SyncRequestHandle`

  #### get

  ```python theme={null}
  def get(self) -> 'AnyJSON'
  ```

  Wait till the request is completed and return the result of the inference call.

  **Returns:** `dict[str, Any]`

  #### iter\_events

  ```python theme={null}
  def iter_events(self, *, with_logs: 'bool' = False, interval: 'float' = 0.1) -> 'Iterator[Status]'
  ```

  Continuously poll for the status of the request and yield it at each interval till the request is completed. If `with_logs` is True, logs will be included in the response.

  | Parameter   | Type    | Default | Description |
  | :---------- | :------ | :------ | :---------- |
  | `with_logs` | `bool`  | `False` | -           |
  | `interval`  | `float` | `0.1`   | -           |

  **Returns:** `Iterator[Status]`

  #### status

  ```python theme={null}
  def status(self, *, with_logs: 'bool' = False) -> 'Status'
  ```

  Returns the status of the request (which can be one of the following: Queued, InProgress, Completed). If `with_logs` is True, logs will be included
  for InProgress and Completed statuses.

  | Parameter   | Type   | Default | Description |
  | :---------- | :----- | :------ | :---------- |
  | `with_logs` | `bool` | `False` | -           |

  **Returns:** `Status`
</Accordion>

### AsyncRequestHandle

```python theme={null}
class fal_client.AsyncRequestHandle
```

> **Inherits from:** `_BaseRequestHandle`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name           | Type          | Default | Description |
  | :------------- | :------------ | :------ | :---------- |
  | `request_id`   | `str`         | -       | -           |
  | `response_url` | `str`         | -       | -           |
  | `status_url`   | `str`         | -       | -           |
  | `cancel_url`   | `str`         | -       | -           |
  | `client`       | `AsyncClient` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name     | Type                | Default | Description |
  | :------- | :------------------ | :------ | :---------- |
  | `client` | `httpx.AsyncClient` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### cancel

  ```python theme={null}
  async def cancel(self) -> 'None'
  ```

  Cancel the request.

  **Returns:** `NoneType`

  #### from\_request\_id

  ```python theme={null}
  def from_request_id(cls, client: 'httpx.AsyncClient', application: 'str', request_id: 'str') -> 'AsyncRequestHandle'
  ```

  | Parameter     | Type          | Default | Description |
  | :------------ | :------------ | :------ | :---------- |
  | `client`      | `AsyncClient` | -       | -           |
  | `application` | `str`         | -       | -           |
  | `request_id`  | `str`         | -       | -           |

  **Returns:** `AsyncRequestHandle`

  #### get

  ```python theme={null}
  async def get(self) -> 'AnyJSON'
  ```

  Wait till the request is completed and return the result.

  **Returns:** `dict[str, Any]`

  #### iter\_events

  ```python theme={null}
  def iter_events(self, *, with_logs: 'bool' = False, interval: 'float' = 0.1) -> 'AsyncIterator[Status]'
  ```

  Continuously poll for the status of the request and yield it at each interval till the request is completed. If `with_logs` is True, logs will be included in the response.

  | Parameter   | Type    | Default | Description |
  | :---------- | :------ | :------ | :---------- |
  | `with_logs` | `bool`  | `False` | -           |
  | `interval`  | `float` | `0.1`   | -           |

  **Returns:** `AsyncIterator[Status]`

  #### status

  ```python theme={null}
  async def status(self, *, with_logs: 'bool' = False) -> 'Status'
  ```

  Returns the status of the request (which can be one of the following: Queued, InProgress, Completed). If `with_logs` is True, logs will be included
  for InProgress and Completed statuses.

  | Parameter   | Type   | Default | Description |
  | :---------- | :----- | :------ | :---------- |
  | `with_logs` | `bool` | `False` | -           |

  **Returns:** `Status`
</Accordion>

***

## Functions

### run

```python theme={null}
def run(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', timeout: 'Optional[Union[int, float]]' = None, start_timeout: 'Optional[Union[int, float]]' = None, hint: 'str | None' = None, headers: 'dict[str, str]' = {}) -> 'AnyJSON'
```

Run an application with the given arguments (which will be JSON serialized).

| Parameter       | Type                       | Default | Description                                                                                                                                              |
| :-------------- | :------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application`   | `str`                      | -       | -                                                                                                                                                        |
| `arguments`     | `dict[str, Any]`           | -       | -                                                                                                                                                        |
| `path`          | `str`                      | `''`    | -                                                                                                                                                        |
| `timeout`       | `int \| float \| NoneType` | `None`  | Client-side HTTP timeout in seconds. Controls how long the HTTP client waits for a response. Defaults to the client's default\_timeout.                  |
| `start_timeout` | `int \| float \| NoneType` | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts. Does not apply once the application begins processing. |
| `hint`          | `str \| None`              | `None`  | -                                                                                                                                                        |
| `headers`       | `dict[str, str]`           | `\{\}`  | -                                                                                                                                                        |

**Returns:** `dict[str, Any]`

### subscribe\_async

```python theme={null}
async def subscribe_async(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, with_logs: 'bool' = False, on_enqueue: 'Optional[Callable[[str], None]]' = None, on_queue_update: 'Optional[Callable[[Status], None]]' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None, client_timeout: 'Optional[Union[int, float]]' = None) -> 'AnyJSON'
```

Subscribe to an application and wait for the result.

| Parameter         | Type                                   | Default | Description                                                                                                                                                                                          |
| :---------------- | :------------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application`     | `str`                                  | -       | -                                                                                                                                                                                                    |
| `arguments`       | `dict[str, Any]`                       | -       | -                                                                                                                                                                                                    |
| `path`            | `str`                                  | `''`    | -                                                                                                                                                                                                    |
| `hint`            | `str \| None`                          | `None`  | -                                                                                                                                                                                                    |
| `with_logs`       | `bool`                                 | `False` | -                                                                                                                                                                                                    |
| `on_enqueue`      | `Optional[Callable[str, NoneType]]`    | `None`  | -                                                                                                                                                                                                    |
| `on_queue_update` | `Optional[Callable[Status, NoneType]]` | `None`  | -                                                                                                                                                                                                    |
| `priority`        | `Optional[Literal[normal, low]]`       | `None`  | -                                                                                                                                                                                                    |
| `headers`         | `dict[str, str]`                       | `\{\}`  | -                                                                                                                                                                                                    |
| `start_timeout`   | `int \| float \| NoneType`             | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |
| `client_timeout`  | `int \| float \| NoneType`             | `None`  | Client-side total timeout in seconds. Limits the total time spent waiting for the entire request to complete (including queue wait and processing). If not set, waits indefinitely.                  |

**Returns:** `dict[str, Any]`

### subscribe

```python theme={null}
def subscribe(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, with_logs: 'bool' = False, on_enqueue: 'Optional[Callable[[str], None]]' = None, on_queue_update: 'Optional[Callable[[Status], None]]' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None, client_timeout: 'Optional[Union[int, float]]' = None) -> 'AnyJSON'
```

Subscribe to an application and wait for the result.

| Parameter         | Type                                   | Default | Description                                                                                                                                                                                          |
| :---------------- | :------------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application`     | `str`                                  | -       | -                                                                                                                                                                                                    |
| `arguments`       | `dict[str, Any]`                       | -       | -                                                                                                                                                                                                    |
| `path`            | `str`                                  | `''`    | -                                                                                                                                                                                                    |
| `hint`            | `str \| None`                          | `None`  | -                                                                                                                                                                                                    |
| `with_logs`       | `bool`                                 | `False` | -                                                                                                                                                                                                    |
| `on_enqueue`      | `Optional[Callable[str, NoneType]]`    | `None`  | -                                                                                                                                                                                                    |
| `on_queue_update` | `Optional[Callable[Status, NoneType]]` | `None`  | -                                                                                                                                                                                                    |
| `priority`        | `Optional[Literal[normal, low]]`       | `None`  | -                                                                                                                                                                                                    |
| `headers`         | `dict[str, str]`                       | `\{\}`  | -                                                                                                                                                                                                    |
| `start_timeout`   | `int \| float \| NoneType`             | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |
| `client_timeout`  | `int \| float \| NoneType`             | `None`  | Client-side total timeout in seconds. Limits the total time spent waiting for the entire request to complete (including queue wait and processing). If not set, waits indefinitely.                  |

**Returns:** `dict[str, Any]`

### submit

```python theme={null}
def submit(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, webhook_url: 'str | None' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None) -> 'SyncRequestHandle'
```

Submit an application with the given arguments (which will be JSON serialized).

| Parameter       | Type                             | Default | Description                                                                                                                                                                                          |
| :-------------- | :------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application`   | `str`                            | -       | -                                                                                                                                                                                                    |
| `arguments`     | `dict[str, Any]`                 | -       | -                                                                                                                                                                                                    |
| `path`          | `str`                            | `''`    | -                                                                                                                                                                                                    |
| `hint`          | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
| `webhook_url`   | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
| `priority`      | `Optional[Literal[normal, low]]` | `None`  | -                                                                                                                                                                                                    |
| `headers`       | `dict[str, str]`                 | `\{\}`  | -                                                                                                                                                                                                    |
| `start_timeout` | `int \| float \| NoneType`       | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |

**Returns:** `SyncRequestHandle`

### stream

```python theme={null}
def stream(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '/stream', timeout: 'float | None' = None) -> 'Iterator[dict[str, Any]]'
```

Stream the output of an application with the given arguments (which will be JSON serialized). This is only supported at a few select applications at the moment, so be sure to first consult with the documentation of individual applications
to see if this is supported.

The function will iterate over each event that is streamed from the server.

| Parameter     | Type             | Default     | Description |
| :------------ | :--------------- | :---------- | :---------- |
| `application` | `str`            | -           | -           |
| `arguments`   | `dict[str, Any]` | -           | -           |
| `path`        | `str`            | `'/stream'` | -           |
| `timeout`     | `float \| None`  | `None`      | -           |

**Returns:** `Iterator[dict[str, Any]]`

### run\_async

```python theme={null}
async def run_async(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', timeout: 'Optional[Union[int, float]]' = None, start_timeout: 'Optional[Union[int, float]]' = None, hint: 'str | None' = None, headers: 'dict[str, str]' = {}) -> 'AnyJSON'
```

Run an application with the given arguments (which will be JSON serialized). The path parameter can be used to specify a subpath when applicable. This method will return the result of the inference call directly.

| Parameter       | Type                       | Default | Description                                                                                                                                              |
| :-------------- | :------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application`   | `str`                      | -       | -                                                                                                                                                        |
| `arguments`     | `dict[str, Any]`           | -       | -                                                                                                                                                        |
| `path`          | `str`                      | `''`    | -                                                                                                                                                        |
| `timeout`       | `int \| float \| NoneType` | `None`  | Client-side HTTP timeout in seconds. Controls how long the HTTP client waits for a response. Defaults to the client's default\_timeout.                  |
| `start_timeout` | `int \| float \| NoneType` | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts. Does not apply once the application begins processing. |
| `hint`          | `str \| None`              | `None`  | -                                                                                                                                                        |
| `headers`       | `dict[str, str]`           | `\{\}`  | -                                                                                                                                                        |

**Returns:** `dict[str, Any]`

### submit\_async

```python theme={null}
async def submit_async(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '', hint: 'str | None' = None, webhook_url: 'str | None' = None, priority: 'Optional[Priority]' = None, headers: 'dict[str, str]' = {}, start_timeout: 'Optional[Union[int, float]]' = None) -> 'AsyncRequestHandle'
```

Submit an application with the given arguments (which will be JSON serialized). The path parameter can be used to specify a subpath when applicable. This method will return a handle to the request that can be used to check the status
and retrieve the result of the inference call when it is done.

| Parameter       | Type                             | Default | Description                                                                                                                                                                                          |
| :-------------- | :------------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `application`   | `str`                            | -       | -                                                                                                                                                                                                    |
| `arguments`     | `dict[str, Any]`                 | -       | -                                                                                                                                                                                                    |
| `path`          | `str`                            | `''`    | -                                                                                                                                                                                                    |
| `hint`          | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
| `webhook_url`   | `str \| None`                    | `None`  | -                                                                                                                                                                                                    |
| `priority`      | `Optional[Literal[normal, low]]` | `None`  | -                                                                                                                                                                                                    |
| `headers`       | `dict[str, str]`                 | `\{\}`  | -                                                                                                                                                                                                    |
| `start_timeout` | `int \| float \| NoneType`       | `None`  | Server-side request timeout in seconds. Limits total time spent waiting before processing starts (includes queue wait, retries, and routing). Does not apply once the application begins processing. |

**Returns:** `AsyncRequestHandle`

### stream\_async

```python theme={null}
def stream_async(self, application: 'str', arguments: 'AnyJSON', *, path: 'str' = '/stream', timeout: 'float | None' = None) -> 'AsyncIterator[dict[str, Any]]'
```

Stream the output of an application with the given arguments (which will be JSON serialized). This is only supported at a few select applications at the moment, so be sure to first consult with the documentation of individual applications
to see if this is supported.

The function will iterate over each event that is streamed from the server.

| Parameter     | Type             | Default     | Description |
| :------------ | :--------------- | :---------- | :---------- |
| `application` | `str`            | -           | -           |
| `arguments`   | `dict[str, Any]` | -           | -           |
| `path`        | `str`            | `'/stream'` | -           |
| `timeout`     | `float \| None`  | `None`      | -           |

**Returns:** `AsyncIterator[dict[str, Any]]`

### realtime

```python theme={null}
def realtime(self, application: 'str', *, use_jwt: 'bool' = True, path: 'str' = '/realtime', max_buffering: 'int | None' = None, token_expiration: 'int' = 120, encode_message: 'Callable[[Any], bytes] | None' = None, decode_message: 'Callable[[bytes], Any] | None' = None) -> 'Iterator[RealtimeConnection]'
```

| Parameter          | Type                             | Default       | Description |
| :----------------- | :------------------------------- | :------------ | :---------- |
| `application`      | `str`                            | -             | -           |
| `use_jwt`          | `bool`                           | `True`        | -           |
| `path`             | `str`                            | `'/realtime'` | -           |
| `max_buffering`    | `int \| None`                    | `None`        | -           |
| `token_expiration` | `int`                            | `120`         | -           |
| `encode_message`   | `Optional[Callable[Any, bytes]]` | `None`        | -           |
| `decode_message`   | `Optional[Callable[bytes, Any]]` | `None`        | -           |

**Returns:** `Iterator[RealtimeConnection]`

### realtime\_async

```python theme={null}
def realtime_async(self, application: 'str', *, use_jwt: 'bool' = True, path: 'str' = '/realtime', max_buffering: 'int | None' = None, token_expiration: 'int' = 120, encode_message: 'Callable[[Any], bytes] | None' = None, decode_message: 'Callable[[bytes], Any] | None' = None) -> 'AsyncIterator[AsyncRealtimeConnection]'
```

| Parameter          | Type                             | Default       | Description |
| :----------------- | :------------------------------- | :------------ | :---------- |
| `application`      | `str`                            | -             | -           |
| `use_jwt`          | `bool`                           | `True`        | -           |
| `path`             | `str`                            | `'/realtime'` | -           |
| `max_buffering`    | `int \| None`                    | `None`        | -           |
| `token_expiration` | `int`                            | `120`         | -           |
| `encode_message`   | `Optional[Callable[Any, bytes]]` | `None`        | -           |
| `decode_message`   | `Optional[Callable[bytes, Any]]` | `None`        | -           |

**Returns:** `AsyncIterator[AsyncRealtimeConnection]`

### cancel

```python theme={null}
def cancel(self, application: 'str', request_id: 'str') -> 'None'
```

| Parameter     | Type  | Default | Description |
| :------------ | :---- | :------ | :---------- |
| `application` | `str` | -       | -           |
| `request_id`  | `str` | -       | -           |

**Returns:** `NoneType`

### cancel\_async

```python theme={null}
async def cancel_async(self, application: 'str', request_id: 'str') -> 'None'
```

| Parameter     | Type  | Default | Description |
| :------------ | :---- | :------ | :---------- |
| `application` | `str` | -       | -           |
| `request_id`  | `str` | -       | -           |

**Returns:** `NoneType`

### status

```python theme={null}
def status(self, application: 'str', request_id: 'str', *, with_logs: 'bool' = False) -> 'Status'
```

| Parameter     | Type   | Default | Description |
| :------------ | :----- | :------ | :---------- |
| `application` | `str`  | -       | -           |
| `request_id`  | `str`  | -       | -           |
| `with_logs`   | `bool` | `False` | -           |

**Returns:** `Status`

### status\_async

```python theme={null}
async def status_async(self, application: 'str', request_id: 'str', *, with_logs: 'bool' = False) -> 'Status'
```

| Parameter     | Type   | Default | Description |
| :------------ | :----- | :------ | :---------- |
| `application` | `str`  | -       | -           |
| `request_id`  | `str`  | -       | -           |
| `with_logs`   | `bool` | `False` | -           |

**Returns:** `Status`

### result

```python theme={null}
def result(self, application: 'str', request_id: 'str') -> 'AnyJSON'
```

| Parameter     | Type  | Default | Description |
| :------------ | :---- | :------ | :---------- |
| `application` | `str` | -       | -           |
| `request_id`  | `str` | -       | -           |

**Returns:** `dict[str, Any]`

### result\_async

```python theme={null}
async def result_async(self, application: 'str', request_id: 'str') -> 'AnyJSON'
```

| Parameter     | Type  | Default | Description |
| :------------ | :---- | :------ | :---------- |
| `application` | `str` | -       | -           |
| `request_id`  | `str` | -       | -           |

**Returns:** `dict[str, Any]`

### encode

```python theme={null}
def encode(data: 'str | bytes', content_type: 'str') -> 'str'
```

Encode the given data blob to a data URL with the specified content type.

| Parameter      | Type           | Default | Description |
| :------------- | :------------- | :------ | :---------- |
| `data`         | `str \| bytes` | -       | -           |
| `content_type` | `str`          | -       | -           |

**Returns:** `str`

### encode\_file

```python theme={null}
def encode_file(path: 'os.PathLike') -> 'str'
```

Encode a file from the local filesystem to a data URL with the inferred content type.

| Parameter | Type       | Default | Description |
| :-------- | :--------- | :------ | :---------- |
| `path`    | `PathLike` | -       | -           |

**Returns:** `str`

### encode\_image

```python theme={null}
def encode_image(image: 'Image.Image', format: 'str' = 'jpeg') -> 'str'
```

Encode a pillow image object to a data URL with the specified format.

| Parameter | Type          | Default  | Description |
| :-------- | :------------ | :------- | :---------- |
| `image`   | `Image.Image` | -        | -           |
| `format`  | `str`         | `'jpeg'` | -           |


# https://fal.ai/docs/api-reference/client-libraries/python/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Python Client

> API reference for fal-client Python package

The `fal-client` package provides a Python interface for calling fal AI models.

## Installation

```bash theme={null}
pip install fal-client
```

## Quick Start

```python theme={null}
import fal_client

result = fal_client.subscribe(
    "fal-ai/flux/dev",
    arguments={
        "prompt": "a cat wearing a hat",
        "image_size": "landscape_4_3"
    },
    with_logs=True,
    on_queue_update=lambda status: print(f"Status: {status}")
)

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

## API Reference

The following pages contain the auto-generated API reference for all public classes and functions in the `fal-client` package.


# https://fal.ai/docs/api-reference/client-libraries/swift/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Swift Client

> fal client library for iOS, macOS, tvOS, and watchOS

The `fal-swift` package provides a native Swift interface for calling fal AI models on Apple platforms.

## Installation

Add the package via Swift Package Manager:

```swift theme={null}
.package(url: "https://github.com/fal-ai/fal-swift.git", from: "0.5.6")
```

## Quick Start

```swift theme={null}
import FalClient

let result = try await fal.subscribe(
    to: "fal-ai/flux/dev",
    input: [
        "prompt": "a cat",
        "seed": 6252023,
        "image_size": "landscape_4_3",
        "num_images": 4
    ],
    includeLogs: true
) { update in
    if case let .inProgress(logs) = update {
        print(logs)
    }
}
```

## Supported Platforms

* iOS 16+
* macOS 13+
* tvOS 16+
* watchOS 9+

## API Reference

<Card title="Swift API Reference" icon="book" href="https://swiftpackageindex.com/fal-ai/fal-swift/documentation/falclient">
  Full API documentation on Swift Package Index
</Card>

<Card title="GitHub Repository" icon="github" href="https://github.com/fal-ai/fal-swift">
  Source code and examples
</Card>


# https://fal.ai/docs/api-reference/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Reference

> Complete API and SDK reference documentation for fal

Complete reference documentation for all fal SDKs and tools.

<CardGroup cols={3}>
  <Card title="Client Libraries" icon="code" href="/api-reference/client-libraries">
    Libraries for calling fal AI models from your applications
  </Card>

  <Card title="CLI Reference" icon="terminal" href="/api-reference/cli">
    Command-line interface for deploying and managing fal applications
  </Card>

  <Card title="Python SDK" icon="python" href="/api-reference/python-sdk/fal-app-reference">
    Tools for building and deploying serverless AI applications
  </Card>
</CardGroup>

## Overview

| Section              | What it's for                                | When to use                                   |
| :------------------- | :------------------------------------------- | :-------------------------------------------- |
| **Client Libraries** | Call fal AI models and get results           | You want to use fal's AI models in your app   |
| **CLI Reference**    | Deploy, manage, and monitor fal applications | You're working with fal from the command line |
| **Python SDK**       | Build and deploy custom AI applications      | You're deploying your own models on fal       |


# https://fal.ai/docs/api-reference/platform-apis/authentication.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Platform APIs require API keys for secure access to your user or team's data.

## Generating API Keys

Navigate to the dashboard keys page and generate a key from the UI: [fal.ai/dashboard/keys](https://fal.ai/dashboard/keys)

## Scopes

Platform APIs may require different API key scopes.

[Learn more about key-based authentication and scopes](/documentation/model-apis/authentication/key-based).

<CardGroup cols={2}>
  <Card title="API Scope">
    Most Platform APIs accept **API scope** keys. This scope is suitable for most use cases including model discovery, pricing, and analytics.
  </Card>

  <Card title="Admin Scope">
    Some Platform APIs require **Admin scope** keys for access to sensitive data.
  </Card>
</CardGroup>

<Info>
  Check the specific Platform API documentation to see which scope is required. If you're unsure, start with an API scope key. You can always generate an Admin scope key later if needed.
</Info>

<Warning>
  API keys should be kept secure and never exposed in client-side code or public repositories.
</Warning>

## Authentication Format

Include your API key in the `Authorization` header with the `Key` prefix:

```bash theme={null}
Authorization: Key YOUR_API_KEY
```

For endpoints requiring Admin scope:

```bash theme={null}
Authorization: Key YOUR_ADMIN_API_KEY
```

## Usage Examples

### cURL

Using an API scope key for model listing:

```bash theme={null}
curl -X GET "https://api.fal.ai/v1/models?limit=10" \
  -H "Authorization: Key YOUR_API_KEY"
```

Using an Admin scope key for usage data:

```bash theme={null}
curl -X GET "https://api.fal.ai/v1/models/usage" \
  -H "Authorization: Key YOUR_ADMIN_API_KEY"
```

### Python

Using an API scope key:

```python theme={null}
import requests

headers = {
    "Authorization": "Key YOUR_API_KEY"
}

response = requests.get(
    "https://api.fal.ai/v1/models",
    headers=headers,
    params={"limit": 10}
)

print(response.json())
```

### JavaScript

Using an API scope key:

```javascript theme={null}
const response = await fetch('https://api.fal.ai/v1/models?limit=10', {
  headers: {
    'Authorization': 'Key YOUR_API_KEY'
  }
});

const data = await response.json();
console.log(data);
```

## Best Practices

* Store API keys in environment variables
* Use the minimum required scope for your use case
* Rotate keys regularly
* Keep Admin API keys secure and never expose them client-side

## Troubleshooting

### 401 Unauthorized

* Verify your API key is correct
* Ensure the `Authorization` header includes the `Key` prefix
* Check that your API key hasn't been revoked

### 403 Forbidden

Your API key may not have the required scope for the endpoint. Check the endpoint documentation to determine if it requires an Admin scope key, and generate one from the dashboard if needed.


# https://fal.ai/docs/api-reference/platform-apis/for-accounts.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform APIs for Accounts

> Programmatic access to account billing information, FOCUS-compliant cost reports, and model access controls

The **fal Platform APIs** provide programmatic access to account-level billing, cost reporting, and governance, including:

* **Billing information** - Retrieve account billing details and credit balances
* **FOCUS reports** - Download FinOps FOCUS-compliant billing reports for cost analysis and interoperability
* **Model access controls** - Export the resolved UI and API access state for each model in your organization

## Available Operations

The Platform APIs provide the following endpoints for account billing, reporting, and governance:

<CardGroup cols={2}>
  <Card title="Account Billing" icon="dollar-sign" href="/platform-apis/v1/account/billing">
    Retrieve billing information and credit balances for your account
  </Card>

  <Card title="FOCUS Report" icon="file-csv" href="/platform-apis/v1/account/focus">
    Download FOCUS-compliant billing reports from invoice or usage estimate data
  </Card>

  <Card title="Model Access Controls" icon="lock" href="/platform-apis/v1/account/model-access-controls">
    Export the resolved UI and API access state for each model in your organization
  </Card>
</CardGroup>

<Note>
  FOCUS reports and model access controls are available to enterprise customers with the corresponding features enabled. Contact your account team or [support@fal.ai](mailto:support@fal.ai) to request access.
</Note>


# https://fal.ai/docs/api-reference/platform-apis/for-compute.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform APIs for Compute

> Programmatic access to compute instance management, lifecycle control, and monitoring

The **fal Platform APIs** provide programmatic access to platform management features for Compute, including:

* **Instance management** - Create, list, and delete compute instances
* **Instance details** - Retrieve detailed information about specific instances

## Available Operations

The Platform APIs provide the following endpoints for managing Compute instances:

<CardGroup cols={2}>
  <Card title="List Instances" icon="list" href="/platform-apis/v1/compute/instances/list">
    List all compute instances with their current status and configuration
  </Card>

  <Card title="Get Instance Details" icon="info-circle" href="/platform-apis/v1/compute/instances/get">
    Retrieve detailed information about a specific compute instance
  </Card>

  <Card title="Create Instance" icon="plus" href="/platform-apis/v1/compute/instances/create">
    Create and provision a new compute instance
  </Card>

  <Card title="Delete Instance" icon="trash" href="/platform-apis/v1/compute/instances/delete">
    Terminate and remove a compute instance
  </Card>
</CardGroup>

<Note>
  These APIs are for **platform management** of Compute instances. For getting started with Compute, see the [Compute documentation](/compute).
</Note>


# https://fal.ai/docs/api-reference/platform-apis/for-keys.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform APIs for Keys

> Programmatic access to API key management, creation, and deletion

The **fal Platform APIs** provide programmatic access to API key management, including:

* **List keys** - Retrieve all API keys associated with your account
* **Create keys** - Generate new API keys with custom aliases
* **Delete keys** - Revoke and remove existing API keys

## Available Operations

The Platform APIs provide the following endpoints for managing API keys:

<CardGroup cols={3}>
  <Card title="List API Keys" icon="list" href="/platform-apis/v1/keys/list">
    Retrieve all API keys with pagination support
  </Card>

  <Card title="Create API Key" icon="plus" href="/platform-apis/v1/keys/create">
    Generate a new API key with a friendly alias
  </Card>

  <Card title="Delete API Key" icon="trash" href="/platform-apis/v1/keys/delete">
    Permanently revoke and delete an API key
  </Card>
</CardGroup>

<Note>
  These APIs require **admin API key** authentication. For more information on authentication, see the [Authentication](/reference/platform-apis/authentication) documentation.
</Note>


# https://fal.ai/docs/api-reference/platform-apis/for-models.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform APIs for Models

> Programmatic access to model metadata, pricing, usage tracking, and analytics

The **fal Platform APIs** provide programmatic access to platform management features for Model APIs, including:

* **Model metadata** - Search and discover available model endpoints with detailed information
* **Pricing information** - Retrieve real-time pricing and estimate costs
* **Usage tracking** - Access detailed usage line items with unit quantities and prices
* **Analytics** - Query time-bucketed metrics for request counts, success/error rates, and latency

## Available Operations

The Platform APIs provide the following endpoints for managing Model APIs:

<CardGroup cols={2}>
  <Card title="Model Search" icon="grid" href="/platform-apis/v1/models">
    Search and discover available model endpoints with metadata, categories, and capabilities
  </Card>

  <Card title="Model Pricing" icon="dollar-sign" href="/platform-apis/v1/models/pricing">
    Retrieve real-time pricing information for models
  </Card>

  <Card title="Estimate Cost" icon="calculator" href="/platform-apis/v1/models/pricing/estimate">
    Estimate costs for planned operations
  </Card>

  <Card title="Usage" icon="chart-bar" href="/platform-apis/v1/models/usage">
    Access detailed usage line items with unit quantities and prices
  </Card>

  <Card title="Analytics" icon="chart-line" href="/platform-apis/v1/models/analytics">
    Query time-bucketed metrics for requests, success rates, and latency
  </Card>

  <Card title="List Requests by Endpoint" icon="list" href="/platform-apis/v1/models/requests/by-endpoint">
    List recent requests for a specific model endpoint with filters and pagination
  </Card>

  <Card title="Delete Request Payloads" icon="trash" href="/platform-apis/v1/models/requests/payloads">
    Delete IO payloads and CDN output files for a specific request
  </Card>
</CardGroup>

<Note>
  These APIs are for **platform management** of Model APIs. For executing models and generating content, see the [Inference Methods](/documentation/model-apis/inference) documentation.
</Note>


# https://fal.ai/docs/api-reference/platform-apis/for-serverless.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform APIs for Serverless

> Programmatic access to serverless apps metadata and analytics

## Available Operations

The Platform APIs provide the following endpoints for Serverless Apps:

## Files

<CardGroup cols={5}>
  <Card title="List Root Directory Contents" icon="list" href="/platform-apis/v1/serverless/files/list">
    List the contents of the root directory of your Serverless storage.
  </Card>

  <Card title="List Directory Contents" icon="grid" href="/platform-apis/v1/serverless/files/list/directory">
    List the contents of any nested directory by providing its path.
  </Card>

  <Card title="Download File" icon="database" href="/platform-apis/v1/serverless/files/file/download">
    Download any file from Serverless storage.
  </Card>

  <Card title="Upload from URL" icon="plus" href="/platform-apis/v1/serverless/files/file/upload-from-url">
    Upload a file from a URL into Serverless storage.
  </Card>

  <Card title="Upload Local File" icon="server" href="/platform-apis/v1/serverless/files/file/upload-local">
    Upload a local file into Serverless storage.
  </Card>
</CardGroup>

## Requests

<CardGroup cols={1}>
  <Card title="List Requests by Endpoint" icon="list" href="/platform-apis/v1/serverless/requests/by-endpoint">
    List recent requests for your serverless endpoints with filtering, sorting, and pagination.
  </Card>
</CardGroup>

## Logs

<CardGroup cols={2}>
  <Card title="Logs History" icon="diagram-project" href="/platform-apis/v1/serverless/logs/history">
    Query paginated logs with powerful label filters, time ranges, and search keywords.
  </Card>

  <Card title="Logs Stream" icon="signal-stream" href="/platform-apis/v1/serverless/logs/stream">
    Stream live logs that match the provided filters using Server-Sent Events.
  </Card>
</CardGroup>

## Analytics

<CardGroup cols={1}>
  <Card title="Analytics" icon="chart-line" href="/platform-apis/v1/serverless/analytics">
    Query time-bucketed metrics across all inbound traffic to your apps, including request counts, success/error rates, and latency percentiles. Ideal for exporting to your own observability tools.
  </Card>
</CardGroup>

## Metrics

<CardGroup cols={2}>
  <Card title="Queue Size" icon="grid" href="/platform-apis/v1/serverless/apps/queue">
    Read the current queue backlog for your serverless applications.
  </Card>

  <Card title="Metrics" icon="grid" href="/platform-apis/v1/serverless/metrics">
    Export app metrics (runners, queue size, concurrent requests, throughput, and latency) in Prometheus format for custom dashboards and monitoring.
  </Card>
</CardGroup>


# https://fal.ai/docs/api-reference/platform-apis/for-workflows.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform APIs for Workflows

> Programmatic access to workflow metadata, listing, and details

The **fal Platform APIs** provide programmatic access to workflow management for the authenticated user, including:

* **List workflows** - Paginated list of your workflows with optional search and filtering
* **Get workflow details** - Retrieve a specific workflow by owner and name, including its full definition

## Available Operations

The Platform APIs provide the following endpoints for Workflows:

<CardGroup cols={2}>
  <Card title="List Workflows" icon="list" href="/platform-apis/v1/workflows">
    List workflows for the authenticated user with optional search and filtering
    by endpoint
  </Card>

  <Card title="Get Workflow Details" icon="info-circle" href="/platform-apis/v1/workflows/get">
    Get detailed information about a specific workflow, including its full
    definition
  </Card>
</CardGroup>

## Authentication

All Workflows endpoints require authentication. Include your API key in the `Authorization` header:

```
Authorization: Key YOUR_API_KEY
```

List workflows returns only workflows owned by the authenticated user. Get workflow details requires access to the workflow (e.g., it is yours or public).

<Note>
  These APIs are for **platform management** of Workflows (listing and reading).
  To run workflows, use the [Model APIs](/model-apis) or workflow execution
  endpoints.
</Note>


# https://fal.ai/docs/api-reference/platform-apis/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction to Platform APIs

> Platform APIs provide programmatic access to platform resources including model metadata, pricing information, usage tracking, and analytics.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=1029&end=1111&autoplay=1'><img src='/docs/images/video-thumbs/platform-apis.jpg' alt='Platform APIs - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

<Card title="Platform APIs for Models" icon="arrow-right" href="/api-reference/platform-apis/for-models">
  Access model metadata, pricing information, usage tracking, and analytics for Model APIs
</Card>

<Card title="Platform APIs for Serverless" icon="arrow-right" href="/api-reference/platform-apis/for-serverless">
  APIs to manage and monitor your serverless applications
</Card>

<Card title="Platform APIs for Compute" icon="arrow-right" href="/api-reference/platform-apis/for-compute">
  Manage compute instances with lifecycle control and monitoring capabilities
</Card>

<Card title="Platform APIs for Workflows" icon="arrow-right" href="/api-reference/platform-apis/for-workflows">
  List and retrieve workflow metadata and definitions
</Card>

<Card title="Platform APIs for Accounts" icon="arrow-right" href="/api-reference/platform-apis/for-accounts">
  Access account billing information and FOCUS-compliant cost reports
</Card>

<Note>
  For executing models and generating content, see [Model APIs](/documentation/model-apis/overview).
</Note>


# https://fal.ai/docs/api-reference/platform-apis/meta.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform Metadata

> 
Returns platform metadata including webhook IP ranges for allowlisting.

If your infrastructure requires allowlisting IP addresses for incoming webhook
requests, this endpoint provides the current list of IP ranges used by fal.ai
webhooks in CIDR notation.
    



## OpenAPI

````yaml GET /meta
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /meta:
    get:
      tags:
        - Meta
      summary: Get platform metadata
      description: >-

        Returns platform metadata including webhook IP ranges for allowlisting.


        If your infrastructure requires allowlisting IP addresses for incoming
        webhook

        requests, this endpoint provides the current list of IP ranges used by
        fal.ai

        webhooks in CIDR notation.
            
      operationId: getMeta
      responses:
        '200':
          description: Platform metadata
          content:
            application/json:
              schema:
                type: object
                properties:
                  webhook_ip_ranges:
                    type: array
                    items:
                      type: string
                    description: IP address ranges (CIDR notation) used by fal.ai webhooks
                required:
                  - webhook_ip_ranges
                description: Platform metadata including webhook IP ranges for allowlisting
                example:
                  webhook_ip_ranges:
                    - 34.123.59.101/32
                    - 34.135.41.243/32
                    - 35.239.83.87/32
                    - 104.198.204.37/32
                    - 34.56.20.205/32
                    - 34.170.94.127/32
                    - 35.224.184.236/32
                    - 136.114.56.197/32
                    - 34.29.37.237/32
                    - 35.225.160.28/32
                    - 34.56.205.145/32
                    - 34.59.170.72/32
                    - 34.10.147.45/32
                    - 104.198.64.245/32
                    - 34.9.1.255/32
              example:
                webhook_ip_ranges:
                  - 34.123.59.101/32
                  - 34.135.41.243/32
                  - 35.239.83.87/32
                  - 104.198.204.37/32
                  - 34.56.20.205/32
                  - 34.170.94.127/32
                  - 35.224.184.236/32
                  - 136.114.56.197/32
                  - 34.29.37.237/32
                  - 35.225.160.28/32
                  - 34.56.205.145/32
                  - 34.59.170.72/32
                  - 34.10.147.45/32
                  - 104.198.64.245/32
                  - 34.9.1.255/32
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred

````

# https://fal.ai/docs/api-reference/platform-apis/openapi-schema.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAPI Schema

> The fal Platform API is documented using the OpenAPI 3.1 specification format.

## Download

Download the complete OpenAPI schema to integrate with your tools and workflows:

<Card title="OpenAPI Specification" icon="file-code" href="https://api.fal.ai/v1/openapi.json">
  Download the OpenAPI 3.1 JSON schema
</Card>

## Use Cases

The OpenAPI schema enables you to:

* **Generate Client SDKs**: Use tools like OpenAPI Generator to create client libraries in your preferred language
* **API Testing**: Import into testing tools like Postman or Insomnia
* **Code Generation**: Generate type definitions and API interfaces
* **Documentation**: Use with documentation generators and API explorers
* **Validation**: Validate API requests and responses against the schema

## Schema URL

```
https://api.fal.ai/v1/openapi.json
```

## Integration Examples

### Postman

1. Open Postman
2. Click **Import**
3. Select **Link** and paste the schema URL
4. Postman will generate a collection from the OpenAPI spec

### OpenAPI Generator

Generate a client library using the OpenAPI Generator:

```bash theme={null}
openapi-generator-cli generate \
  -i https://api.fal.ai/v1/openapi.json \
  -g python \
  -o ./fal-api-client
```

### Swagger UI

View the API documentation in Swagger UI:

```bash theme={null}
docker run -p 8080:8080 \
  -e SWAGGER_JSON_URL=https://api.fal.ai/v1/openapi.json \
  swaggerapi/swagger-ui
```

## Specification Details

* **Version**: OpenAPI 3.1.0
* **Format**: JSON
* **Authentication**: API Key (Admin keys required)
* **Base URL**: `https://api.fal.ai/v1`


# https://fal.ai/docs/api-reference/python-sdk/api-reference.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal.api

> API reference for fal.api

```python theme={null}
from fal.api import (
    SyncServerlessClient,
    AppsNamespace,
    RunnersNamespace,
    KeysNamespace,
    SecretsNamespace,
)
```

## Classes

### SyncServerlessClient

```python theme={null}
class fal.api.SyncServerlessClient
```

Synchronous Python client for fal Serverless. Manage apps, runners, and deployments programmatically. The namespaces
and methods mirror the CLI so you can automate the same workflows from Python.

**Example:**

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient()

# List apps
apps = client.apps.list()

# Scale an app
client.apps.scale("my-app", max_concurrency=10)

# Deploy
client.deploy("path/to/myfile.py::MyApp")
```

**Namespaces:**

* client.apps.\*    - corresponds to `fal apps ...`
* client.runners.\* - corresponds to `fal runners ...`
* client.keys.\*    - corresponds to `fal keys ...`
* client.secrets.\* - corresponds to `fal secrets ...`
* client.deploy()  - corresponds to `fal deploy ...`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name      | Type            | Default | Description                                   |
  | :-------- | :-------------- | :------ | :-------------------------------------------- |
  | `host`    | `Optional[str]` | `None`  | Optional. Override API host.                  |
  | `api_key` | `Optional[str]` | `None`  | Optional. If omitted, read from env/profile.  |
  | `profile` | `Optional[str]` | `None`  | Optional. Named profile to use.               |
  | `team`    | `Optional[str]` | `None`  | Optional. Team context for runner operations. |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name      | Type            | Default | Description |
  | :-------- | :-------------- | :------ | :---------- |
  | `host`    | `Optional[str]` | `None`  | -           |
  | `api_key` | `Optional[str]` | `None`  | -           |
  | `profile` | `Optional[str]` | `None`  | -           |
  | `team`    | `Optional[str]` | `None`  | -           |
</Accordion>

<Accordion title="Properties" defaultOpen>
  | Name           | Type          | Description |
  | :------------- | :------------ | :---------- |
  | `_credentials` | `Credentials` | -           |
  | `_grpc_host`   | `str`         | -           |
  | `_rest_url`    | `str`         | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### deploy

  ```python theme={null}
  def deploy(self, *args, **kwargs)
  ```

  Deploy an application. Corresponds to `fal deploy`. If app\_ref is omitted, discovery behavior matches the CLI
  (e.g., uses pyproject.toml).

  **Example:**

  ```python theme={null}
  # Auto-discover from pyproject.toml
  client.deploy()

  # Deploy from a file path
  client.deploy("path/to/myfile.py")

  # Deploy a specific class
  client.deploy("path/to/myfile.py::MyApp")

  # With options
  client.deploy(
      app_ref="path/to/myfile.py::MyApp",
      app_name="myapp",
      auth="public",
      strategy="rolling",
  )
  ```

  | Parameter | Type | Default | Description |
  | :-------- | :--- | :------ | :---------- |
  | `args`    | -    | -       | -           |
  | `kwargs`  | -    | -       | -           |
</Accordion>

### AppsNamespace

```python theme={null}
class fal.api.AppsNamespace
```

Namespace for app management operations. Corresponds to `fal apps ...` CLI commands.

Accessed via `client.apps`.

**Example:**

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient()
apps = client.apps.list()
client.apps.scale("my-app", max_concurrency=10)
```

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type                   | Default | Description |
  | :------- | :--------------------- | :------ | :---------- |
  | `client` | `SyncServerlessClient` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### list

  ```python theme={null}
  def list(self, *, filter: 'str | None' = None, environment_name: 'str | None' = None) -> 'List[AliasInfo]'
  ```

  List all applications. Corresponds to `fal apps list`.

  **Example:**

  ```python theme={null}
  apps = client.apps.list()
  filtered = client.apps.list(filter="stable")
  ```

  | Parameter          | Type          | Default | Description                      |
  | :----------------- | :------------ | :------ | :------------------------------- |
  | `filter`           | `str \| None` | `None`  | Optional app name filter string. |
  | `environment_name` | `str \| None` | `None`  | Optional environment name.       |

  **Returns:** `list[AliasInfo]`

  #### rollout

  ```python theme={null}
  def rollout(self, app_name: 'str', *, force: 'bool' = False, environment_name: 'str | None' = None) -> 'None'
  ```

  | Parameter          | Type          | Default | Description |
  | :----------------- | :------------ | :------ | :---------- |
  | `app_name`         | `str`         | -       | -           |
  | `force`            | `bool`        | `False` | -           |
  | `environment_name` | `str \| None` | `None`  | -           |

  **Returns:** `NoneType`

  #### runners

  ```python theme={null}
  def runners(self, app_name: 'str', *, since=None, state: 'List[str] | None' = None, environment_name: 'str | None' = None) -> 'List[RunnerInfo]'
  ```

  List runners for a specific app. Corresponds to `fal apps runners \<app\>`.

  **Example:**

  ```python theme={null}
  from datetime import datetime, timedelta

  runners = client.apps.runners("my-app")
  recent = client.apps.runners(
      "my-app", since=datetime.now() - timedelta(hours=1)
  )
  running = client.apps.runners("my-app", state=["running"])
  ```

  | Parameter          | Type                  | Default | Description                                      |
  | :----------------- | :-------------------- | :------ | :----------------------------------------------- |
  | `app_name`         | `str`                 | -       | Name of the application.                         |
  | `since`            | -                     | `None`  | Only return runners started after this datetime. |
  | `state`            | `Optional[list[str]]` | `None`  | Filter by runner state (e.g., \["running"]).     |
  | `environment_name` | `str \| None`         | `None`  | Optional environment name.                       |

  **Returns:** `list[RunnerInfo]`

  #### scale

  ```python theme={null}
  def scale(self, app_name: 'str', *, keep_alive: 'int | None' = None, max_multiplexing: 'int | None' = None, max_concurrency: 'int | None' = None, min_concurrency: 'int | None' = None, concurrency_buffer: 'int | None' = None, concurrency_buffer_perc: 'int | None' = None, scaling_delay: 'int | None' = None, request_timeout: 'int | None' = None, startup_timeout: 'int | None' = None, machine_types: 'List[str] | None' = None, regions: 'List[str] | None' = None, environment_name: 'str | None' = None) -> 'apps_api.AliasInfo'
  ```

  Adjust scaling settings for an application. Corresponds to `fal apps scale`. Any omitted option keeps the current value.

  **Example:**

  ```python theme={null}
  client.apps.scale(
      "my-app",
      keep_alive=300,
      max_concurrency=10,
      min_concurrency=1,
      machine_types=["GPU-H100", "GPU-H200"],
  )
  ```

  | Parameter                 | Type                  | Default | Description                                          |
  | :------------------------ | :-------------------- | :------ | :--------------------------------------------------- |
  | `app_name`                | `str`                 | -       | Name of the application.                             |
  | `keep_alive`              | `int \| None`         | `None`  | Keep-alive time in seconds.                          |
  | `max_multiplexing`        | `int \| None`         | `None`  | Maximum request multiplexing.                        |
  | `max_concurrency`         | `int \| None`         | `None`  | Maximum concurrent runners.                          |
  | `min_concurrency`         | `int \| None`         | `None`  | Minimum concurrent runners.                          |
  | `concurrency_buffer`      | `int \| None`         | `None`  | -                                                    |
  | `concurrency_buffer_perc` | `int \| None`         | `None`  | -                                                    |
  | `scaling_delay`           | `int \| None`         | `None`  | -                                                    |
  | `request_timeout`         | `int \| None`         | `None`  | Request timeout in seconds.                          |
  | `startup_timeout`         | `int \| None`         | `None`  | Startup timeout in seconds.                          |
  | `machine_types`           | `Optional[list[str]]` | `None`  | List of allowed machine types (e.g., \["GPU-H100"]). |
  | `regions`                 | `Optional[list[str]]` | `None`  | List of allowed regions (e.g., \["us-east-1"]).      |
  | `environment_name`        | `str \| None`         | `None`  | -                                                    |

  **Returns:** `AliasInfo`
</Accordion>

### RunnersNamespace

```python theme={null}
class fal.api.RunnersNamespace
```

Namespace for runner management operations. Corresponds to `fal runners ...` CLI commands.

Accessed via `client.runners`.

**Example:**

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient()
runners = client.runners.list()
client.runners.stop("runner-id")
```

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type                   | Default | Description |
  | :------- | :--------------------- | :------ | :---------- |
  | `client` | `SyncServerlessClient` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### kill

  ```python theme={null}
  def kill(self, runner_id: 'str') -> 'None'
  ```

  Forcefully kill a runner.

  | Parameter   | Type  | Default | Description                   |
  | :---------- | :---- | :------ | :---------------------------- |
  | `runner_id` | `str` | -       | The ID of the runner to kill. |

  **Returns:** `NoneType`

  #### list

  ```python theme={null}
  def list(self, *, since=None) -> 'List[RunnerInfo]'
  ```

  List all runners. Corresponds to `fal runners list`.

  **Example:**

  ```python theme={null}
  from datetime import datetime, timedelta

  all_runners = client.runners.list()
  recent = client.runners.list(since=datetime.now() - timedelta(minutes=10))
  ```

  | Parameter | Type | Default | Description                                      |
  | :-------- | :--- | :------ | :----------------------------------------------- |
  | `since`   | -    | `None`  | Only return runners started after this datetime. |

  **Returns:** `list[RunnerInfo]`

  #### stop

  ```python theme={null}
  def stop(self, runner_id: 'str') -> 'None'
  ```

  Gracefully stop a runner.

  | Parameter   | Type  | Default | Description                   |
  | :---------- | :---- | :------ | :---------------------------- |
  | `runner_id` | `str` | -       | The ID of the runner to stop. |

  **Returns:** `NoneType`
</Accordion>

### KeysNamespace

```python theme={null}
class fal.api.KeysNamespace
```

Namespace for API key management. Corresponds to `fal keys ...` CLI commands. Accessed via `client.keys`.

**Example:**

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient()
keys = client.keys.list()
key_id, key_secret = client.keys.create(scope="admin")
```

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type                   | Default | Description |
  | :------- | :--------------------- | :------ | :---------- |
  | `client` | `SyncServerlessClient` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### create

  ```python theme={null}
  def create(self, *, scope: 'KeyScope', description: 'str | None' = None) -> 'tuple[str, str]'
  ```

  Create a new API key.

  | Parameter     | Type          | Default | Description                       |
  | :------------ | :------------ | :------ | :-------------------------------- |
  | `scope`       | `KeyScope`    | -       | Key scope (e.g., "admin").        |
  | `description` | `str \| None` | `None`  | Optional description for the key. |

  **Returns:** `tuple[str, str]`

  #### list

  ```python theme={null}
  def list(self) -> 'List[UserKeyInfo]'
  ```

  List all API keys.

  **Returns:** `list[UserKeyInfo]`

  #### revoke

  ```python theme={null}
  def revoke(self, key_id: 'str') -> 'None'
  ```

  Revoke an API key.

  | Parameter | Type  | Default | Description                  |
  | :-------- | :---- | :------ | :--------------------------- |
  | `key_id`  | `str` | -       | The ID of the key to revoke. |

  **Returns:** `NoneType`
</Accordion>

### SecretsNamespace

```python theme={null}
class fal.api.SecretsNamespace
```

Namespace for secrets management. Corresponds to `fal secrets ...` CLI commands. Accessed via `client.secrets`.

**Example:**

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient()
client.secrets.set("API_KEY", "my-secret-value")
secrets = client.secrets.list()
```

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type                   | Default | Description |
  | :------- | :--------------------- | :------ | :---------- |
  | `client` | `SyncServerlessClient` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### list

  ```python theme={null}
  def list(self, environment_name: 'str | None' = None) -> 'List[ServerlessSecret]'
  ```

  List all secrets (names only, not values).

  | Parameter          | Type          | Default | Description |
  | :----------------- | :------------ | :------ | :---------- |
  | `environment_name` | `str \| None` | `None`  | -           |

  **Returns:** `list[ServerlessSecret]`

  #### set

  ```python theme={null}
  def set(self, name: 'str', value: 'str', environment_name: 'str | None' = None) -> 'None'
  ```

  Set a secret value.

  | Parameter          | Type          | Default | Description         |
  | :----------------- | :------------ | :------ | :------------------ |
  | `name`             | `str`         | -       | Name of the secret. |
  | `value`            | `str`         | -       | Value to store.     |
  | `environment_name` | `str \| None` | `None`  | -                   |

  **Returns:** `NoneType`

  #### unset

  ```python theme={null}
  def unset(self, name: 'str', environment_name: 'str | None' = None) -> 'None'
  ```

  Delete a secret.

  | Parameter          | Type          | Default | Description                   |
  | :----------------- | :------------ | :------ | :---------------------------- |
  | `name`             | `str`         | -       | Name of the secret to delete. |
  | `environment_name` | `str \| None` | `None`  | Optional environment name.    |

  **Returns:** `NoneType`
</Accordion>


# https://fal.ai/docs/api-reference/python-sdk/client.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SyncServerlessClient

> Synchronous Python client for fal Serverless. Manage apps, runners, and deployments programmatically.

The `SyncServerlessClient` is the synchronous Python client for interacting with fal Serverless.
Its namespaces and methods mirror the CLI so you can automate the same workflows from Python.

## Import and Initialize

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient(
    host=None,     # Optional. Override API host
    api_key=None,  # Optional. If omitted, read from env/profile
    profile=None,  # Optional. Named profile to use
    team=None,     # Optional. Team context for runner ops
)
```

## Overview of Namespaces

* `client.apps.*` — corresponds to `fal apps ...`
* `client.runners.*` — corresponds to `fal runners ...`
* `client.secrets.*` — corresponds to `fal secrets ...`
* `client.keys.*` — corresponds to `fal keys ...`
* `client.environments.*` — corresponds to `fal environments ...`
* `client.deploy(...)` — corresponds to `fal deploy ...`

## Apps Namespace

Manage your applications: list them, view runners for a specific app, and adjust scaling.

### List Applications (fal apps list)

```python theme={null}
apps = client.apps.list()

# Optional app name filter
filtered = client.apps.list(filter="stable")

# List apps in a specific environment
staging_apps = client.apps.list(environment_name="staging")
```

### List App Runners (fal apps runners my-app)

```python theme={null}
app_runners = client.apps.runners("my-app")

# Optional filters
recent = client.apps.runners("my-app", since=datetime.now() - timedelta(hours=1)) # last hour
running_only = client.apps.runners("my-app", state=["running"])                   # by state

# List runners for an app in a specific environment
staging_runners = client.apps.runners("my-app", environment_name="staging")
```

### Scale Application (fal apps scale)

Maps to CLI flags in `fal apps scale`. Any omitted option keeps the current value.

```python theme={null}
client.apps.scale(
    "my-app",
    keep_alive=300,            # seconds
    max_multiplexing=1,
    max_concurrency=10,
    min_concurrency=1,
    request_timeout=600,       # seconds
    startup_timeout=900,       # seconds
    machine_types=["GPU-H100", "GPU-H200"],
    regions=["us-east-1", "us-west-2"],
    concurrency_buffer=1,
    concurrency_buffer_perc=10,
    environment_name="staging",  # target environment
)
```

### Rollout Application (fal apps rollout)

```python theme={null}
client.apps.rollout("my-app")

# Force rollout
client.apps.rollout("my-app", force=True)

# Rollout in a specific environment
client.apps.rollout("my-app", environment_name="staging")
```

## Runners Namespace

List and manage runners.

### List Runners (fal runners list)

```python theme={null}
all_runners = client.runners.list()

# Recent runners only
last_10_min = client.runners.list(since=datetime.now() - timedelta(minutes=10))
```

## Keys Namespace

Create and manage API keys that the service uses to authenticate requests. The Python surface mirrors `fal keys ...`.

### Create Key (fal keys create)

```python theme={null}
from fal.sdk import KeyScope

# ADMIN keys can manage resources; API keys are limited to app invocation.
key_id, key_secret = client.keys.create(
    scope=KeyScope.ADMIN,          # or KeyScope.API
    description="CI deploy key",
)
print(f"Store securely: {key_id}:{key_secret}")  # secret shown only once
```

### List Keys (fal keys list)

```python theme={null}
keys = client.keys.list()

for key in keys:
    print(key.key_id, key.scope.value, key.alias)  # alias holds the description
```

### Revoke Key (fal keys revoke)

```python theme={null}
client.keys.revoke("key-id-to-revoke")
```

## Secrets Namespace

Store configuration values for builds and runtime without hardcoding them. Values are never returned when you list secrets.

### Set Secret (fal secrets set)

```python theme={null}
client.secrets.set("MY_API_TOKEN", "s3cr3t-value")

# Set secret in a specific environment
client.secrets.set("MY_API_TOKEN", "staging-value", environment_name="staging")
```

### List Secrets (fal secrets list)

```python theme={null}
secrets = client.secrets.list()
for secret in secrets:
    print(secret.name, secret.created_at, secret.environment_name)

# List secrets for a specific environment
staging_secrets = client.secrets.list(environment_name="staging")
```

### Unset Secret (fal secrets unset)

```python theme={null}
client.secrets.unset("MY_API_TOKEN")

# Unset secret in a specific environment
client.secrets.unset("MY_API_TOKEN", environment_name="staging")
```

## Environments Namespace

Create and manage environments to organize your applications and secrets across different stages (development, staging, production).

### Create Environment (fal environments create)

```python theme={null}
env = client.environments.create("staging", description="Staging environment")
print(f"Created: {env.name}")
```

### List Environments (fal environments list)

```python theme={null}
environments = client.environments.list()
for env in environments:
    print(env.name, env.description, env.is_default)
```

### Delete Environment (fal environments delete)

```python theme={null}
client.environments.delete("staging")
```

<Warning>
  Deleting an environment removes all apps and secrets in that environment.
</Warning>

## Deploy (fal deploy)

Programmatic equivalent of `fal deploy`. If `app_ref` is omitted, discovery behavior matches the CLI (e.g., `pyproject.toml`).

```python theme={null}
# Auto-discover
client.deploy()

# Deploy from a file path
client.deploy("path/to/myfile.py")

# Deploy a specific class in a file
client.deploy("path/to/myfile.py::MyApp")

# Deploy by existing app name
client.deploy("my-app")

# With options mirroring CLI flags
client.deploy(
    app_ref="path/to/myfile.py::MyApp",
    app_name="myapp",
    auth="public",                # "private" | "public"
    strategy="rolling",           # "recreate" | "rolling"
    reset_scale=True,             # use previous scaling if False
    environment_name="staging",   # target environment
)
```

## Reference

<CardGroup cols={2}>
  <Card title="CLI Overview" icon="terminal" href="/serverless/python/cli">
    CLI commands that mirror these methods
  </Card>

  <Card title="API Reference" icon="book" href="/reference/serverless-sdk/fal.api">
    Full method signatures and types
  </Card>
</CardGroup>


# https://fal.ai/docs/api-reference/python-sdk/fal.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal

> API reference for fal

```python theme={null}
from fal import (
    App,
    HealthCheck,
    FalServerlessKeyCredentials,
    ContainerImage,
    function,
    cached,
    endpoint,
    realtime,
    sync_dir,
)
```

## Classes

### App

```python theme={null}
class fal.App
```

Create a fal serverless application. Subclass this to define your application with custom setup, endpoints,
and configuration. The App class handles model loading, request routing,
and lifecycle management.

**Example:**

```python theme={null}
>>> class TextToImage(fal.App, machine_type="GPU"):
...     requirements = ["diffusers", "torch"]
...
...     def setup(self):
...         self.pipe = StableDiffusionPipeline.from_pretrained(
...             "runwayml/stable-diffusion-v1-5"
...         )
...
...     @fal.endpoint("/")
...     def generate(self, prompt: str) -> dict:
...         image = self.pipe(prompt).images[0]
...         return {"url": fal.toolkit.upload_image(image)}
```

> **Inherits from:** `BaseServable`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name          | Type   | Default | Description |
  | :------------ | :----- | :------ | :---------- |
  | `_allow_init` | `bool` | `False` | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name                      | Type                                              | Default                                                                                                                | Description                                                                                                                                                                                                                                                                                                                       |
  | :------------------------ | :------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `requirements`            | `ClassVar[list[str] \| list[list[str]]]`          | `[]`                                                                                                                   | Pip packages to install in the environment. Supports standard pip syntax including version specifiers. Use a list of strings for a single install step, or a list of lists to install in multiple steps. Example: `["numpy==1.24.0", "torch\>=2.0.0"]` or `[["setuptools", "wheel"], ["numpy==1.24.0"]]`                          |
  | `local_python_modules`    | `ClassVar[list[str]]`                             | `[]`                                                                                                                   | List of local Python module names to include in the deployment. Use for custom code not available on PyPI. Example: `["my_utils", "models"]`                                                                                                                                                                                      |
  | `machine_type`            | `ClassVar[str \| list[str]]`                      | `'S'`                                                                                                                  | Compute instance type for your application. CPU options: 'XS', 'S' (default), 'M', 'L'. GPU options: 'GPU-A6000', 'GPU-A100', 'GPU-H100', 'GPU-H200', 'GPU-B200'. Use a string for a single type, or a list to define fallback types (tried in order until one is available). Example: `"GPU-A100"` or `["GPU-H100", "GPU-A100"]` |
  | `num_gpus`                | `ClassVar[int \| None]`                           | `None`                                                                                                                 | Number of GPUs to allocate. Only applies to GPU machine types.                                                                                                                                                                                                                                                                    |
  | `regions`                 | `ClassVar[Optional[list[str]]]`                   | `None`                                                                                                                 | Allowed regions for deployment. None means any region. Example: `["us-east", "eu-west"]`                                                                                                                                                                                                                                          |
  | `host_kwargs`             | `ClassVar[dict[str, Any]]`                        | `\{'_scheduler': 'nomad', '_scheduler_options': \{'storage_region': 'us-east'\}, 'resolver': 'uv', 'keep_alive': 60\}` | Advanced configuration dictionary passed to the host. For internal use. Prefer using class attributes instead.                                                                                                                                                                                                                    |
  | `app_name`                | `ClassVar[Optional[str]]`                         | `None`                                                                                                                 | Custom name for the application. Defaults to class name.                                                                                                                                                                                                                                                                          |
  | `app_auth`                | `ClassVar[Optional[AuthModeLiteral]]`             | `None`                                                                                                                 | Authentication mode. Options: 'private' (API key required), 'public' (no auth), 'shared' (shareable link).                                                                                                                                                                                                                        |
  | `app_files`               | `ClassVar[list[str]]`                             | `[]`                                                                                                                   | List of files/directories to include in deployment. Example: `["./models", "./config.yaml"]`                                                                                                                                                                                                                                      |
  | `app_files_ignore`        | `ClassVar[list[str]]`                             | `['\\.pyc$', '__pycache__/', '\\.git/', '\\.DS_Store$']`                                                               | Regex patterns to exclude from deployment. Default excludes `.pyc`, `__pycache__`, `.git`, `.DS_Store`.                                                                                                                                                                                                                           |
  | `app_files_context_dir`   | `ClassVar[Optional[str]]`                         | `None`                                                                                                                 | Base directory for resolving app\_files paths. Defaults to the directory containing the app file.                                                                                                                                                                                                                                 |
  | `request_timeout`         | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Maximum seconds for a single request. None for default.                                                                                                                                                                                                                                                                           |
  | `startup_timeout`         | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Maximum seconds for app startup/setup. None for default.                                                                                                                                                                                                                                                                          |
  | `min_concurrency`         | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Minimum warm instances to keep running. Set to 1+ to avoid cold starts. Default is 0 (scale to zero).                                                                                                                                                                                                                             |
  | `max_concurrency`         | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Maximum instances to scale up to.                                                                                                                                                                                                                                                                                                 |
  | `concurrency_buffer`      | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Additional instances to keep warm above current load.                                                                                                                                                                                                                                                                             |
  | `concurrency_buffer_perc` | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Percentage buffer of instances above current load.                                                                                                                                                                                                                                                                                |
  | `scaling_delay`           | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Seconds to wait for a request to be picked up by a runner before triggering a scale up. Useful for apps with slow startup times.                                                                                                                                                                                                  |
  | `max_multiplexing`        | `ClassVar[Optional[int]]`                         | `None`                                                                                                                 | Maximum concurrent requests per instance.                                                                                                                                                                                                                                                                                         |
  | `kind`                    | `ClassVar[Optional[str]]`                         | `None`                                                                                                                 | Deployment kind. For internal use.                                                                                                                                                                                                                                                                                                |
  | `image`                   | `ClassVar[Optional[ContainerImage]]`              | `None`                                                                                                                 | Custom container image for the application. Use ContainerImage to specify a Dockerfile.                                                                                                                                                                                                                                           |
  | `local_file_path`         | `ClassVar[Optional[str]]`                         | `None`                                                                                                                 | -                                                                                                                                                                                                                                                                                                                                 |
  | `skip_retry_conditions`   | `ClassVar[Optional[list[RetryConditionLiteral]]]` | `None`                                                                                                                 | -                                                                                                                                                                                                                                                                                                                                 |
  | `isolate_channel`         | `async_grpc.Channel \| None`                      | `None`                                                                                                                 | -                                                                                                                                                                                                                                                                                                                                 |
</Accordion>

<Accordion title="Properties" defaultOpen>
  | Name              | Type                     | Description |   |
  | :---------------- | :----------------------- | :---------- | - |
  | `current_request` | \`fal.app.RequestContext | None\`      | - |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### collect\_routes

  ```python theme={null}
  def collect_routes(self) -> 'dict[RouteSignature, Callable[..., Any]]'
  ```

  **Returns:** `dict[RouteSignature, Callable[Ellipsis, Any]]`

  #### get\_endpoints

  ```python theme={null}
  def get_endpoints(cls) -> 'list[str]'
  ```

  **Returns:** `list[str]`

  #### get\_health\_check\_config

  ```python theme={null}
  def get_health_check_config(cls) -> 'Optional[ApplicationHealthCheckConfig]'
  ```

  **Returns:** `Optional[ApplicationHealthCheckConfig]`

  #### handle\_exit

  ```python theme={null}
  def handle_exit(self)
  ```

  Handle exit signal.

  #### health

  ```python theme={null}
  def health(self)
  ```

  #### lifespan

  ```python theme={null}
  def lifespan(self, app: 'fastapi.FastAPI')
  ```

  | Parameter | Type      | Default | Description |
  | :-------- | :-------- | :------ | :---------- |
  | `app`     | `FastAPI` | -       | -           |

  #### provide\_hints

  ```python theme={null}
  def provide_hints(self) -> 'list[str]'
  ```

  Provide hints for routing the application.

  **Returns:** `list[str]`

  #### run\_local

  ```python theme={null}
  def run_local(cls, *args, **kwargs)
  ```

  | Parameter | Type | Default | Description |
  | :-------- | :--- | :------ | :---------- |
  | `args`    | -    | -       | -           |
  | `kwargs`  | -    | -       | -           |

  #### setup

  ```python theme={null}
  def setup(self)
  ```

  Setup the application before serving.

  #### spawn

  ```python theme={null}
  def spawn(cls) -> 'AppSpawnInfo'
  ```

  **Returns:** `AppSpawnInfo`

  #### teardown

  ```python theme={null}
  def teardown(self)
  ```

  Teardown the application after serving.
</Accordion>

### HealthCheck

```python theme={null}
class fal.HealthCheck
```

<Accordion title="Constructor Parameters" defaultOpen>
  | Name                   | Type             | Default | Description                                                                                                                                                                                                                                                      |
  | :--------------------- | :--------------- | :------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `start_period_seconds` | `Optional[int]`  | `None`  | Minimum time the runner has been running before considering the runner unhealthy when health check fails. To prevent the health check from failing too early, this will be replaced by startup\_timeout of the application if it's less than it. Defaults to 30. |
  | `timeout_seconds`      | `Optional[int]`  | `None`  | Timeout in seconds for the health check request. Defaults to 5 seconds.                                                                                                                                                                                          |
  | `failure_threshold`    | `Optional[int]`  | `None`  | Number of consecutive failures before considering the runner as unhealthy. Defaults to 3.                                                                                                                                                                        |
  | `call_regularly`       | `Optional[bool]` | `None`  | Perform health check every 15s. If false, only do it when the x-fal-runner-health-check header is present. Defaults to True.                                                                                                                                     |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name                   | Type             | Default | Description |
  | :--------------------- | :--------------- | :------ | :---------- |
  | `start_period_seconds` | `Optional[int]`  | `None`  | -           |
  | `timeout_seconds`      | `Optional[int]`  | `None`  | -           |
  | `failure_threshold`    | `Optional[int]`  | `None`  | -           |
  | `call_regularly`       | `Optional[bool]` | `None`  | -           |
</Accordion>

### FalServerlessKeyCredentials

```python theme={null}
class fal.FalServerlessKeyCredentials
```

> **Inherits from:** `Credentials`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name         | Type  | Default | Description |
  | :----------- | :---- | :------ | :---------- |
  | `key_id`     | `str` | -       | -           |
  | `key_secret` | `str` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name         | Type  | Default | Description |
  | :----------- | :---- | :------ | :---------- |
  | `key_id`     | `str` | -       | -           |
  | `key_secret` | `str` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### to\_grpc

  ```python theme={null}
  def to_grpc(self) -> 'grpc.ChannelCredentials'
  ```

  **Returns:** `ChannelCredentials`

  #### to\_headers

  ```python theme={null}
  def to_headers(self) -> 'dict[str, str]'
  ```

  **Returns:** `dict[str, str]`
</Accordion>

### ContainerImage

```python theme={null}
class fal.ContainerImage
```

ContainerImage represents a Docker image that can be built from a Dockerfile.

<Accordion title="Constructor Parameters" defaultOpen>
  | Name                | Type                                        | Default                               | Description |
  | :------------------ | :------------------------------------------ | :------------------------------------ | :---------- |
  | `dockerfile_str`    | `str`                                       | -                                     | -           |
  | `build_args`        | `dict[str, str]`                            | `\<factory\>`                         | -           |
  | `registries`        | `dict[str, dict[str, str]]`                 | `\<factory\>`                         | -           |
  | `builder`           | `Optional[Literal[depot, service, worker]]` | `None`                                | -           |
  | `compression`       | `str`                                       | `'gzip'`                              | -           |
  | `force_compression` | `bool`                                      | `False`                               | -           |
  | `secrets`           | `dict[str, str]`                            | `\<factory\>`                         | -           |
  | `context_dir`       | `PathLike`                                  | `/home/runner/work/fal-docs/fal-docs` | -           |
  | `dockerignore`      | `Optional[list[str]]`                       | `None`                                | -           |
  | `dockerignore_path` | `Optional[PathLike]`                        | `None`                                | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name                | Type                                        | Default                               | Description |
  | :------------------ | :------------------------------------------ | :------------------------------------ | :---------- |
  | `dockerfile_str`    | `str`                                       | -                                     | -           |
  | `build_args`        | `dict[str, str]`                            | -                                     | -           |
  | `registries`        | `dict[str, dict[str, str]]`                 | -                                     | -           |
  | `builder`           | `Optional[Literal[depot, service, worker]]` | `None`                                | -           |
  | `compression`       | `str`                                       | `'gzip'`                              | -           |
  | `force_compression` | `bool`                                      | `False`                               | -           |
  | `secrets`           | `dict[str, str]`                            | -                                     | -           |
  | `context_dir`       | `PathLike`                                  | `/home/runner/work/fal-docs/fal-docs` | -           |
  | `dockerignore`      | `Optional[list[str]]`                       | `None`                                | -           |
  | `dockerignore_path` | `Optional[PathLike]`                        | `None`                                | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### add\_dockerignore

  ```python theme={null}
  def add_dockerignore(self, patterns: Optional[List[str]] = None, path: Optional[os.PathLike] = None) -> None
  ```

  Add or update dockerignore patterns. Sets the internal dockerignore patterns using gitignore-style matching.
  You can provide either a list of patterns or a path to a .dockerignore file.

  | Parameter  | Type                  | Default | Description                      |
  | :--------- | :-------------------- | :------ | :------------------------------- |
  | `patterns` | `Optional[list[str]]` | `None`  | List of gitignore-style patterns |
  | `path`     | `Optional[PathLike]`  | `None`  | Path to a .dockerignore file     |

  **Returns:** `NoneType`

  **Raises:**

  * `ValueError`: If both patterns and path are provided, or neither

  #### from\_dockerfile

  ```python theme={null}
  def from_dockerfile(cls, path: str, **kwargs) -> 'ContainerImage'
  ```

  | Parameter | Type  | Default | Description |
  | :-------- | :---- | :------ | :---------- |
  | `path`    | `str` | -       | -           |
  | `kwargs`  | -     | -       | -           |

  **Returns:** `ContainerImage`

  #### from\_dockerfile\_str

  ```python theme={null}
  def from_dockerfile_str(cls, text: str, **kwargs) -> 'ContainerImage'
  ```

  | Parameter | Type  | Default | Description |
  | :-------- | :---- | :------ | :---------- |
  | `text`    | `str` | -       | -           |
  | `kwargs`  | -     | -       | -           |

  **Returns:** `ContainerImage`

  #### get\_copy\_add\_sources

  ```python theme={null}
  def get_copy_add_sources(self) -> List[str]
  ```

  Get list of src paths/patterns from COPY/ADD commands. This method only parses the Dockerfile - it doesn't access the filesystem.

  **Returns:** `list[str]`

  #### to\_dict

  ```python theme={null}
  def to_dict(self) -> dict
  ```

  **Returns:** `dict`
</Accordion>

***

## Functions

### function

```python theme={null}
def function(kind: 'str' = 'virtualenv', *, host: 'Host | None' = None, local_python_modules: 'list[str] | None' = None, **config: 'Any')
```

| Parameter              | Type                       | Default        | Description |
| :--------------------- | :------------------------- | :------------- | :---------- |
| `kind`                 | `str`                      | `'virtualenv'` | -           |
| `host`                 | `fal.api.api.Host \| None` | `None`         | -           |
| `local_python_modules` | `list[str] \| None`        | `None`         | -           |
| `config`               | `Any`                      | -              | -           |

### cached

```python theme={null}
def cached(func: 'Callable[ArgsT, ReturnT]') -> 'Callable[ArgsT, ReturnT]'
```

Cache the result of the given function in-memory.

| Parameter | Type                       | Default | Description |
| :-------- | :------------------------- | :------ | :---------- |
| `func`    | `Callable[ArgsT, ReturnT]` | -       | -           |

**Returns:** `Callable[ArgsT, ReturnT]`

### endpoint

```python theme={null}
def endpoint(path: 'str', *, is_websocket: 'bool' = False, health_check: 'HealthCheck | None' = None) -> 'Callable[[EndpointT], EndpointT]'
```

Designate the decorated function as an application endpoint.

| Parameter      | Type                          | Default | Description |
| :------------- | :---------------------------- | :------ | :---------- |
| `path`         | `str`                         | -       | -           |
| `is_websocket` | `bool`                        | `False` | -           |
| `health_check` | `fal.sdk.HealthCheck \| None` | `None`  | -           |

**Returns:** `Callable[EndpointT, EndpointT]`

### realtime

```python theme={null}
def realtime(path: 'str', *, buffering: 'int | None' = None, session_timeout: 'float | None' = None, input_modal: 'Any | None' = <object object at 0x7f9efed85f00>, output_modal: 'Any | None' = <object object at 0x7f9efed85f00>, max_batch_size: 'int' = 1, content_type: 'str' = 'application/msgpack', encode_message: 'Callable[[Any], bytes] | None' = None, decode_message: 'Callable[[bytes], Any] | None' = None) -> 'Callable[[EndpointT], EndpointT]'
```

Designate the decorated function as a realtime application endpoint.

| Parameter         | Type                             | Default                               | Description |
| :---------------- | :------------------------------- | :------------------------------------ | :---------- |
| `path`            | `str`                            | -                                     | -           |
| `buffering`       | `int \| None`                    | `None`                                | -           |
| `session_timeout` | `float \| None`                  | `None`                                | -           |
| `input_modal`     | `Any \| None`                    | `\<object object at 0x7f9efed85f00\>` | -           |
| `output_modal`    | `Any \| None`                    | `\<object object at 0x7f9efed85f00\>` | -           |
| `max_batch_size`  | `int`                            | `1`                                   | -           |
| `content_type`    | `str`                            | `'application/msgpack'`               | -           |
| `encode_message`  | `Optional[Callable[Any, bytes]]` | `None`                                | -           |
| `decode_message`  | `Optional[Callable[bytes, Any]]` | `None`                                | -           |

**Returns:** `Callable[EndpointT, EndpointT]`

### sync\_dir

```python theme={null}
def sync_dir(local_dir: 'str | Path', remote_dir: 'str', force_upload=False) -> 'str'
```

| Parameter      | Type                  | Default | Description |
| :------------- | :-------------------- | :------ | :---------- |
| `local_dir`    | `str \| pathlib.Path` | -       | -           |
| `remote_dir`   | `str`                 | -       | -           |
| `force_upload` | -                     | `False` | -           |

**Returns:** `str`


# https://fal.ai/docs/api-reference/python-sdk/fal-app-reference.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> API reference for the fal Python package

The `fal` package provides decorators and utilities for building serverless AI applications.

## Installation

```bash theme={null}
pip install fal
```

## Quick Start

```python theme={null}
import fal

class MyApp(fal.App):
    @fal.endpoint("/")
    def run(self) -> dict:
        return {"message": "Hello, World!"}
```

Deploy with:

```bash theme={null}
fal deploy my_app.py
```

See the [Quick Start guide](/serverless/getting-started/quick-start) for a complete walkthrough.

## API Reference

<CardGroup cols={2}>
  <Card title="fal" icon="cube" href="/reference/serverless-sdk/fal">
    `App` class, decorators (`endpoint`, `realtime`, `function`, `cached`), `HealthCheck`, `ContainerImage`
  </Card>

  <Card title="fal.api" icon="server" href="/reference/serverless-sdk/fal.api">
    `SyncServerlessClient`: manage apps, runners, keys, secrets, and deploy programmatically
  </Card>

  <Card title="fal.toolkit" icon="toolbox" href="/reference/serverless-sdk/fal.toolkit">
    File types (`Image`, `Video`, `Audio`), `KVStore`, model downloads, GPU utilities
  </Card>

  <Card title="fal.exceptions" icon="triangle-exclamation" href="/reference/serverless-sdk/fal.exceptions">
    Exception classes for error handling
  </Card>

  <Card title="CLI" icon="terminal" href="/reference/cli/installation">
    `fal deploy`, `fal apps`, `fal runners`, `fal keys`, `fal secrets`, and more
  </Card>
</CardGroup>

## Key Decorators

| Decorator             | Description                                  |
| :-------------------- | :------------------------------------------- |
| `@fal.endpoint(path)` | Define an HTTP endpoint on an App            |
| `@fal.realtime(path)` | WebSocket endpoint for realtime applications |
| `@fal.function(...)`  | Create a standalone serverless function      |
| `@fal.cached`         | Cache function results in-memory             |

See the [fal module reference](/reference/serverless-sdk/fal) for full details.

## App Configuration

Configure your app using class variables. See the [full App reference](/reference/serverless-sdk/fal#app) for all options.

| Property          | Description                                                                                                               |
| :---------------- | :------------------------------------------------------------------------------------------------------------------------ |
| `machine_type`    | GPU type: `"GPU-A100"`, `"GPU-H100"`, or list for fallback (see [Machine Types](/documentation/deployment/machine-types)) |
| `requirements`    | Pip packages to install (e.g., `["torch>=2.0"]`)                                                                          |
| `num_gpus`        | Number of GPUs to allocate                                                                                                |
| `min_concurrency` | Minimum warm instances (1+ to avoid cold starts)                                                                          |
| `max_concurrency` | Maximum instances to scale to                                                                                             |
| `request_timeout` | Maximum seconds per request                                                                                               |
| `startup_timeout` | Maximum seconds for setup                                                                                                 |
| `app_auth`        | Auth mode: `"private"`, `"public"`, or `"shared"`                                                                         |
| `app_files`       | Files/directories to include in deployment                                                                                |
| `image`           | Custom `ContainerImage` for the application                                                                               |

## Toolkit Highlights

The [fal.toolkit](/reference/serverless-sdk/fal.toolkit) module provides utilities for common tasks:

| Utility                    | Description                              |
| :------------------------- | :--------------------------------------- |
| `Image`, `Video`, `Audio`  | File types with automatic CDN upload     |
| `KVStore`                  | Persistent key-value storage             |
| `download_model_weights()` | Download and cache model weights         |
| `clone_repository()`       | Clone git repositories                   |
| `sync_dir()`               | Sync local directories to remote storage |
| `get_gpu_type()`           | Detect current GPU type                  |

## SyncServerlessClient

The [SyncServerlessClient](/reference/serverless-sdk/fal.api#syncserverlessclient) provides programmatic access to fal operations (mirrors the CLI):

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient()

# Manage apps
apps = client.apps.list()
client.apps.scale("my-app", max_concurrency=10)

# Manage runners
runners = client.runners.list()
client.runners.stop("runner-id")

# Manage keys and secrets
client.keys.create(scope="admin")
client.secrets.set("API_KEY", "value")

# Deploy
client.deploy("path/to/app.py::MyApp")
```

For detailed guides on building applications, see the [Serverless documentation](/serverless).


# https://fal.ai/docs/api-reference/python-sdk/fal-distributed.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal.distributed

> API reference for fal.distributed

```python theme={null}
from fal.distributed import DistributedRunner, DistributedWorker
```

## Classes

### DistributedRunner

```python theme={null}
class fal.distributed.DistributedRunner
```

A class to launch and manage distributed workers.

<Accordion title="Constructor Parameters" defaultOpen>
  | Name                 | Type                       | Default                                                | Description |
  | :------------------- | :------------------------- | :----------------------------------------------------- | :---------- |
  | `worker_cls`         | `type[DistributedWorker]`  | `\<class 'fal.distributed.worker.DistributedWorker'\>` | -           |
  | `world_size`         | `int`                      | `1`                                                    | -           |
  | `master_addr`        | `str`                      | `'127.0.0.1'`                                          | -           |
  | `master_port`        | `int`                      | `29500`                                                | -           |
  | `worker_addr`        | `str`                      | `'127.0.0.1'`                                          | -           |
  | `worker_port`        | `int`                      | `54923`                                                | -           |
  | `timeout`            | `int`                      | `86400`                                                | -           |
  | `keepalive_payload`  | `dict[str, Any]`           | `\{\}`                                                 | -           |
  | `keepalive_interval` | `int \| float \| NoneType` | `None`                                                 | -           |
  | `cwd`                | `str \| Path \| NoneType`  | `None`                                                 | -           |
  | `set_device`         | `Optional[bool]`           | `None`                                                 | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name              | Type                          | Default | Description |
  | :---------------- | :---------------------------- | :------ | :---------- |
  | `zmq_socket`      | `Optional[Socket[Any]]`       | -       | -           |
  | `context`         | `Optional[mp.ProcessContext]` | -       | -           |
  | `keepalive_timer` | `Optional[KeepAliveTimer]`    | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### close\_zmq\_socket

  ```python theme={null}
  def close_zmq_socket(self) -> 'None'
  ```

  Closes the ZeroMQ socket.

  **Returns:** `NoneType`

  #### ensure\_alive

  ```python theme={null}
  def ensure_alive(self) -> 'None'
  ```

  Ensures that the distributed worker processes are alive. If the processes are not alive, it raises an error.

  **Returns:** `NoneType`

  #### gather\_errors

  ```python theme={null}
  def gather_errors(self) -> 'list[Exception]'
  ```

  Gathers errors from the distributed worker processes. This method should be called to collect any errors that occurred
  during execution.

  **Returns:** `list[Exception]`

  #### get\_zmq\_socket

  ```python theme={null}
  def get_zmq_socket(self) -> 'Socket[Any]'
  ```

  Returns a ZeroMQ socket of the specified type.

  **Returns:** `A ZeroMQ socket.`

  #### invoke

  ```python theme={null}
  async def invoke(self, payload: 'dict[str, Any]' = {}, timeout: 'Optional[int]' = None) -> 'Any'
  ```

  Invokes the distributed worker with the given payload.

  | Parameter | Type             | Default | Description                            |
  | :-------- | :--------------- | :------ | :------------------------------------- |
  | `payload` | `dict[str, Any]` | `\{\}`  | The payload to send to the worker.     |
  | `timeout` | `Optional[int]`  | `None`  | The timeout for the overall operation. |

  **Returns:** `Any`

  #### is\_alive

  ```python theme={null}
  def is_alive(self) -> 'bool'
  ```

  Check if the distributed worker processes are alive.

  **Returns:** `bool`

  #### keepalive

  ```python theme={null}
  def keepalive(self, timeout: 'Optional[Union[int, float]]' = 60.0) -> 'None'
  ```

  Sends the keepalive payload to the worker.

  | Parameter | Type                       | Default | Description |
  | :-------- | :------------------------- | :------ | :---------- |
  | `timeout` | `int \| float \| NoneType` | `60.0`  | -           |

  **Returns:** `NoneType`

  #### maybe\_cancel\_keepalive

  ```python theme={null}
  def maybe_cancel_keepalive(self) -> 'None'
  ```

  Cancels the keepalive timer if it is set.

  **Returns:** `NoneType`

  #### maybe\_reset\_keepalive

  ```python theme={null}
  def maybe_reset_keepalive(self) -> 'None'
  ```

  Resets the keepalive timer if it is set.

  **Returns:** `NoneType`

  #### maybe\_start\_keepalive

  ```python theme={null}
  def maybe_start_keepalive(self) -> 'None'
  ```

  Starts the keepalive timer if it is set.

  **Returns:** `NoneType`

  #### run

  ```python theme={null}
  def run(self, **kwargs: 'Any') -> 'None'
  ```

  The main function to run the distributed worker. This function is called by each worker process spawned by
  `torch.multiprocessing.spawn`. This method must be synchronous.

  | Parameter | Type  | Default | Description                          |
  | :-------- | :---- | :------ | :----------------------------------- |
  | `kwargs`  | `Any` | -       | The arguments to pass to the worker. |

  **Returns:** `NoneType`

  #### start

  ```python theme={null}
  async def start(self, timeout: 'int' = 1800, **kwargs: 'Any') -> 'None'
  ```

  Starts the distributed worker processes.

  | Parameter | Type  | Default | Description                                |
  | :-------- | :---- | :------ | :----------------------------------------- |
  | `timeout` | `int` | `1800`  | The timeout for the distributed processes. |
  | `kwargs`  | `Any` | -       | -                                          |

  **Returns:** `NoneType`

  #### stop

  ```python theme={null}
  async def stop(self, timeout: 'int' = 10) -> 'None'
  ```

  Stops the distributed worker processes.

  | Parameter | Type  | Default | Description                                        |
  | :-------- | :---- | :------ | :------------------------------------------------- |
  | `timeout` | `int` | `10`    | The timeout for the distributed processes to stop. |

  **Returns:** `NoneType`

  #### stream

  ```python theme={null}
  def stream(self, payload: 'dict[str, Any]' = {}, timeout: 'Optional[int]' = None, streaming_timeout: 'Optional[int]' = None, as_text_events: 'bool' = False) -> 'AsyncIterator[Any]'
  ```

  Streams the result from the distributed worker.

  | Parameter           | Type             | Default | Description                              |
  | :------------------ | :--------------- | :------ | :--------------------------------------- |
  | `payload`           | `dict[str, Any]` | `\{\}`  | The payload to send to the worker.       |
  | `timeout`           | `Optional[int]`  | `None`  | The timeout for the overall operation.   |
  | `streaming_timeout` | `Optional[int]`  | `None`  | The timeout in-between streamed results. |
  | `as_text_events`    | `bool`           | `False` | Whether to yield results as text events. |

  **Returns:** `AsyncIterator[Any]`

  #### terminate

  ```python theme={null}
  def terminate(self, timeout: 'Union[int, float]' = 10) -> 'None'
  ```

  Terminates the distributed worker processes. This method should be called to clean up the worker processes.

  | Parameter | Type           | Default | Description |
  | :-------- | :------------- | :------ | :---------- |
  | `timeout` | `int \| float` | `10`    | -           |

  **Returns:** `NoneType`
</Accordion>

### DistributedWorker

```python theme={null}
class fal.distributed.DistributedWorker
```

A base class for distributed workers.

<Accordion title="Constructor Parameters" defaultOpen>
  | Name         | Type  | Default | Description |
  | :----------- | :---- | :------ | :---------- |
  | `rank`       | `int` | `0`     | -           |
  | `world_size` | `int` | `1`     | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name     | Type                        | Default | Description |
  | :------- | :-------------------------- | :------ | :---------- |
  | `queue`  | `queue.Queue[bytes]`        | -       | -           |
  | `loop`   | `asyncio.AbstractEventLoop` | -       | -           |
  | `thread` | `threading.Thread`          | -       | -           |
</Accordion>

<Accordion title="Properties" defaultOpen>
  | Name      | Type   | Description                       |
  | :-------- | :----- | :-------------------------------- |
  | `device`  | -      | The device for the current worker |
  | `running` | `bool` | Whether the event loop is running |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### add\_streaming\_error

  ```python theme={null}
  def add_streaming_error(self, error: 'Exception') -> 'None'
  ```

  Add an error to the queue.

  | Parameter | Type        | Default | Description                    |
  | :-------- | :---------- | :------ | :----------------------------- |
  | `error`   | `Exception` | -       | The error to add to the queue. |

  **Returns:** `NoneType`

  #### add\_streaming\_result

  ```python theme={null}
  def add_streaming_result(self, result: 'Any', image_format: 'str' = 'jpeg', as_text_event: 'bool' = False) -> 'None'
  ```

  Add a streaming result to the queue.

  | Parameter       | Type   | Default  | Description                     |
  | :-------------- | :----- | :------- | :------------------------------ |
  | `result`        | `Any`  | -        | The result to add to the queue. |
  | `image_format`  | `str`  | `'jpeg'` | -                               |
  | `as_text_event` | `bool` | `False`  | -                               |

  **Returns:** `NoneType`

  #### initialize

  ```python theme={null}
  def initialize(self, **kwargs: 'Any') -> 'None'
  ```

  Initialize the worker.

  | Parameter | Type  | Default | Description |
  | :-------- | :---- | :------ | :---------- |
  | `kwargs`  | `Any` | -       | -           |

  **Returns:** `NoneType`

  #### rank\_print

  ```python theme={null}
  def rank_print(self, message: 'str', debug: 'bool' = False) -> 'None'
  ```

  Print a message with the rank of the current worker.

  | Parameter | Type   | Default | Description                                      |
  | :-------- | :----- | :------ | :----------------------------------------------- |
  | `message` | `str`  | -       | The message to print.                            |
  | `debug`   | `bool` | `False` | Whether to print the message as a debug message. |

  **Returns:** `NoneType`

  #### run\_in\_worker

  ```python theme={null}
  def run_in_worker(self, func: 'Callable[..., Any]', *args: 'Any', **kwargs: 'Any') -> 'Future[Any]'
  ```

  Run a function in the worker.

  | Parameter | Type                      | Default | Description |
  | :-------- | :------------------------ | :------ | :---------- |
  | `func`    | `Callable[Ellipsis, Any]` | -       | -           |
  | `args`    | `Any`                     | -       | -           |
  | `kwargs`  | `Any`                     | -       | -           |

  **Returns:** `Future[Any]`

  #### setup

  ```python theme={null}
  def setup(self, **kwargs: 'Any') -> 'None'
  ```

  Override this method to set up the worker. This method is called once per worker.

  | Parameter | Type  | Default | Description |
  | :-------- | :---- | :------ | :---------- |
  | `kwargs`  | `Any` | -       | -           |

  **Returns:** `NoneType`

  #### shutdown

  ```python theme={null}
  def shutdown(self, timeout: 'Optional[Union[int, float]]' = None) -> 'None'
  ```

  Shutdown the event loop.

  | Parameter | Type                       | Default | Description                   |
  | :-------- | :------------------------- | :------ | :---------------------------- |
  | `timeout` | `int \| float \| NoneType` | `None`  | The timeout for the shutdown. |

  **Returns:** `NoneType`

  #### submit

  ```python theme={null}
  def submit(self, coro: 'Coroutine[Any, Any, Any]') -> 'Future[Any]'
  ```

  Submit a coroutine to the event loop.

  | Parameter | Type                       | Default | Description                                |
  | :-------- | :------------------------- | :------ | :----------------------------------------- |
  | `coro`    | `Coroutine[Any, Any, Any]` | -       | The coroutine to submit to the event loop. |

  **Returns:** `Future[Any]`

  #### teardown

  ```python theme={null}
  def teardown(self) -> 'None'
  ```

  Override this method to tear down the worker. This method is called once per worker.

  **Returns:** `NoneType`
</Accordion>


# https://fal.ai/docs/api-reference/python-sdk/fal-exceptions.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal.exceptions

> API reference for fal.exceptions

```python theme={null}
from fal.exceptions import (
    FalServerlessException,
    AppException,
    FieldException,
    RequestCancelledException,
    FileTooLargeError,
    AppFileUploadException,
    CUDAOutOfMemoryException,
    UnauthenticatedException,
)
```

## Classes

### FalServerlessException

```python theme={null}
class fal.exceptions.FalServerlessException
```

Base exception type for fal Serverless related flows and APIs.

> **Inherits from:** `Exception`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type | Default | Description |
  | :------- | :--- | :------ | :---------- |
  | `args`   | -    | -       | -           |
  | `kwargs` | -    | -       | -           |
</Accordion>

### AppException

```python theme={null}
class fal.exceptions.AppException
```

Base exception class for application-specific errors.

> **Inherits from:** `FalServerlessException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name          | Type  | Default | Description                                     |
  | :------------ | :---- | :------ | :---------------------------------------------- |
  | `message`     | `str` | -       | A descriptive message explaining the error.     |
  | `status_code` | `int` | -       | The HTTP status code associated with the error. |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name          | Type  | Default | Description                                     |
  | :------------ | :---- | :------ | :---------------------------------------------- |
  | `message`     | `str` | -       | A descriptive message explaining the error.     |
  | `status_code` | `int` | -       | The HTTP status code associated with the error. |
</Accordion>

### FieldException

```python theme={null}
class fal.exceptions.FieldException
```

Exception raised for errors related to specific fields.

> **Inherits from:** `FalServerlessException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name             | Type                          | Default         | Description                                                     |
  | :--------------- | :---------------------------- | :-------------- | :-------------------------------------------------------------- |
  | `field`          | `str`                         | -               | The field that caused the error.                                |
  | `message`        | `str`                         | -               | A descriptive message explaining the error.                     |
  | `status_code`    | `int`                         | `422`           | The HTTP status code associated with the error. Defaults to 422 |
  | `type`           | `str`                         | `'value_error'` | The type of error. Defaults to "value\_error"                   |
  | `billable_units` | `int \| float \| str \| None` | `0`             | -                                                               |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name             | Type                          | Default         | Description                                                     |
  | :--------------- | :---------------------------- | :-------------- | :-------------------------------------------------------------- |
  | `field`          | `str`                         | -               | The field that caused the error.                                |
  | `message`        | `str`                         | -               | A descriptive message explaining the error.                     |
  | `status_code`    | `int`                         | `422`           | The HTTP status code associated with the error. Defaults to 422 |
  | `type`           | `str`                         | `'value_error'` | The type of error. Defaults to "value\_error"                   |
  | `billable_units` | `int \| float \| str \| None` | `0`             | -                                                               |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### to\_pydantic\_format

  ```python theme={null}
  def to_pydantic_format(self) -> 'dict[str, list[dict]]'
  ```

  **Returns:** `dict[str, list[dict]]`
</Accordion>

### RequestCancelledException

```python theme={null}
class fal.exceptions.RequestCancelledException
```

Exception raised when the request is cancelled by the client.

> **Inherits from:** `FalServerlessException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name      | Type  | Default                              | Description |
  | :-------- | :---- | :----------------------------------- | :---------- |
  | `message` | `str` | `'Request cancelled by the client.'` | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name      | Type  | Default                              | Description |
  | :-------- | :---- | :----------------------------------- | :---------- |
  | `message` | `str` | `'Request cancelled by the client.'` | -           |
</Accordion>

### FileTooLargeError

```python theme={null}
class fal.exceptions.FileTooLargeError
```

Exception raised when the file is too large.

> **Inherits from:** `FalServerlessException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name      | Type  | Default                | Description |
  | :-------- | :---- | :--------------------- | :---------- |
  | `message` | `str` | `'File is too large.'` | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name      | Type  | Default                | Description |
  | :-------- | :---- | :--------------------- | :---------- |
  | `message` | `str` | `'File is too large.'` | -           |
</Accordion>

### AppFileUploadException

```python theme={null}
class fal.exceptions.AppFileUploadException
```

Raised when file upload fails

> **Inherits from:** `FalServerlessException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name            | Type  | Default | Description |
  | :-------------- | :---- | :------ | :---------- |
  | `message`       | `str` | -       | -           |
  | `relative_path` | `str` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name            | Type  | Default | Description |
  | :-------------- | :---- | :------ | :---------- |
  | `message`       | `str` | -       | -           |
  | `relative_path` | `str` | -       | -           |
</Accordion>

### CUDAOutOfMemoryException

```python theme={null}
class fal.exceptions.CUDAOutOfMemoryException
```

Exception raised when a CUDA operation runs out of memory.

> **Inherits from:** `AppException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name          | Type  | Default                       | Description |
  | :------------ | :---- | :---------------------------- | :---------- |
  | `message`     | `str` | `'CUDA error: out of memory'` | -           |
  | `status_code` | `int` | `503`                         | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name          | Type  | Default                       | Description |
  | :------------ | :---- | :---------------------------- | :---------- |
  | `message`     | `str` | `'CUDA error: out of memory'` | -           |
  | `status_code` | `int` | `503`                         | -           |
</Accordion>

### UnauthenticatedException

```python theme={null}
class fal.exceptions.UnauthenticatedException
```

Base exception type for fal Serverless related flows and APIs.

> **Inherits from:** `FalServerlessException`


# https://fal.ai/docs/api-reference/python-sdk/fal-toolkit.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal.toolkit

> API reference for fal.toolkit

```python theme={null}
from fal.toolkit import (
    Audio,
    CompressedFile,
    FalBaseModel,
    File,
    Image,
    KVStore,
    Video,
    FalTookitException,
    FileUploadException,
    KVStoreException,
    DownloadError,
    Hidden,
    get_image_size,
    optimize,
    clone_repository,
    download_file,
    download_model_weights,
    get_gpu_type,
    load_inductor_cache,
    sync_inductor_cache,
    synchronized_inductor_cache,
)
```

## Classes

### Audio

```python theme={null}
class fal.toolkit.Audio
```

!!! abstract "Usage Documentation" [Models](../concepts/models.md)

A base class for creating Pydantic models.

> **Inherits from:** `File`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

### CompressedFile

```python theme={null}
class fal.toolkit.CompressedFile
```

!!! abstract "Usage Documentation" [Models](../concepts/models.md)

A base class for creating Pydantic models.

> **Inherits from:** `File`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name          | Type            | Default | Description |
  | :------------ | :-------------- | :------ | :---------- |
  | `extract_dir` | `Optional[str]` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### glob

  ```python theme={null}
  def glob(self, pattern: 'str')
  ```

  | Parameter | Type  | Default | Description |
  | :-------- | :---- | :------ | :---------- |
  | `pattern` | `str` | -       | -           |
</Accordion>

### FalBaseModel

```python theme={null}
class fal.toolkit.FalBaseModel
```

Base model for fal applications with field ordering, visibility control, and context binding for error reporting.

Features:

* FIELD\_ORDERS: Control field order in JSON schema, useful for nested
  models.
* Hidden(Field(...)): Mark fields as hidden from OpenAPI schema, useful
  for hidden params.

**Example:**

```python theme={null}
from fal.toolkit.pydantic import FalBaseModel, Field, Hidden

class Input(FalBaseModel):
    FIELD_ORDERS = ["prompt", "image_url"]

    prompt: str = Field(description="Text prompt")
    image_url: str = Field(description="Image URL")
    debug_mode: bool = Hidden(Field(default=False))
```

> **Inherits from:** `BaseModel`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name             | Type                  | Default | Description |
  | :--------------- | :-------------------- | :------ | :---------- |
  | `SCHEMA_IGNORES` | `ClassVar[Set[str]]`  | `set()` | -           |
  | `FIELD_ORDERS`   | `ClassVar[List[str]]` | `[]`    | -           |
</Accordion>

### File

```python theme={null}
class fal.toolkit.File
```

!!! abstract "Usage Documentation" [Models](../concepts/models.md)

A base class for creating Pydantic models.

> **Inherits from:** `BaseModel`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name           | Type              | Default | Description |
  | :------------- | :---------------- | :------ | :---------- |
  | `url`          | `str`             | -       | -           |
  | `content_type` | `Optional[str]`   | -       | -           |
  | `file_name`    | `Optional[str]`   | -       | -           |
  | `file_size`    | `Optional[int]`   | -       | -           |
  | `file_data`    | `Optional[bytes]` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### as\_bytes

  ```python theme={null}
  def as_bytes(self) -> 'bytes'
  ```

  **Returns:** `bytes`

  #### from\_bytes

  ```python theme={null}
  def from_bytes(cls, data: 'bytes', content_type: 'Optional[str]' = None, file_name: 'Optional[str]' = None, repository: 'FileRepository | RepositoryId' = 'fal_v3', fallback_repository: 'Optional[FileRepository | RepositoryId | list[FileRepository | RepositoryId]]' = ['cdn', 'fal'], request: 'Optional[Request]' = None, save_kwargs: 'Optional[dict]' = None, fallback_save_kwargs: 'Optional[dict]' = None) -> 'File'
  ```

  | Parameter              | Type                                                                                                                                                                                   | Default          | Description |
  | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------- | :---------- |
  | `data`                 | `bytes`                                                                                                                                                                                | -                | -           |
  | `content_type`         | `Optional[str]`                                                                                                                                                                        | `None`           | -           |
  | `file_name`            | `Optional[str]`                                                                                                                                                                        | `None`           | -           |
  | `repository`           | `FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn]`                                                                                                      | `'fal_v3'`       | -           |
  | `fallback_repository`  | `FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn] \| list[FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn]] \| NoneType` | `['cdn', 'fal']` | -           |
  | `request`              | `Optional[Request]`                                                                                                                                                                    | `None`           | -           |
  | `save_kwargs`          | `Optional[dict]`                                                                                                                                                                       | `None`           | -           |
  | `fallback_save_kwargs` | `Optional[dict]`                                                                                                                                                                       | `None`           | -           |

  **Returns:** `File`

  #### from\_path

  ```python theme={null}
  def from_path(cls, path: 'str | Path', content_type: 'Optional[str]' = None, repository: 'FileRepository | RepositoryId' = 'fal_v3', multipart: 'bool | None' = None, fallback_repository: 'Optional[FileRepository | RepositoryId | list[FileRepository | RepositoryId]]' = ['cdn', 'fal'], request: 'Optional[Request]' = None, save_kwargs: 'Optional[dict]' = None, fallback_save_kwargs: 'Optional[dict]' = None) -> 'File'
  ```

  | Parameter              | Type                                                                                                                                                                                   | Default          | Description |
  | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------- | :---------- |
  | `path`                 | `str \| pathlib.Path`                                                                                                                                                                  | -                | -           |
  | `content_type`         | `Optional[str]`                                                                                                                                                                        | `None`           | -           |
  | `repository`           | `FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn]`                                                                                                      | `'fal_v3'`       | -           |
  | `multipart`            | `bool \| None`                                                                                                                                                                         | `None`           | -           |
  | `fallback_repository`  | `FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn] \| list[FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn]] \| NoneType` | `['cdn', 'fal']` | -           |
  | `request`              | `Optional[Request]`                                                                                                                                                                    | `None`           | -           |
  | `save_kwargs`          | `Optional[dict]`                                                                                                                                                                       | `None`           | -           |
  | `fallback_save_kwargs` | `Optional[dict]`                                                                                                                                                                       | `None`           | -           |

  **Returns:** `File`

  #### save

  ```python theme={null}
  def save(self, path: 'str | Path', overwrite: 'bool' = False) -> 'Path'
  ```

  | Parameter   | Type                  | Default | Description |
  | :---------- | :-------------------- | :------ | :---------- |
  | `path`      | `str \| pathlib.Path` | -       | -           |
  | `overwrite` | `bool`                | `False` | -           |

  **Returns:** `Path`
</Accordion>

### Image

```python theme={null}
class fal.toolkit.Image
```

Represents an image file.

> **Inherits from:** `File`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name     | Type            | Default | Description |
  | :------- | :-------------- | :------ | :---------- |
  | `width`  | `Optional[int]` | -       | -           |
  | `height` | `Optional[int]` | -       | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### from\_bytes

  ```python theme={null}
  def from_bytes(cls, data: 'bytes', format: 'ImageFormat', size: 'ImageSize | None' = None, file_name: 'str | None' = None, repository: 'FileRepository | RepositoryId' = 'fal_v3', fallback_repository: 'Optional[FileRepository | RepositoryId | list[FileRepository | RepositoryId]]' = ['cdn', 'fal'], request: 'Optional[Request]' = None) -> 'Image'
  ```

  | Parameter             | Type                                                                                                                                                                                   | Default          | Description |
  | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------- | :---------- |
  | `data`                | `bytes`                                                                                                                                                                                | -                | -           |
  | `format`              | `Literal[png, jpeg, jpg, webp, gif]`                                                                                                                                                   | -                | -           |
  | `size`                | `fal.toolkit.image.image.ImageSize \| None`                                                                                                                                            | `None`           | -           |
  | `file_name`           | `str \| None`                                                                                                                                                                          | `None`           | -           |
  | `repository`          | `FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn]`                                                                                                      | `'fal_v3'`       | -           |
  | `fallback_repository` | `FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn] \| list[FileRepository \| Literal[fal, fal_v2, fal_v3, in_memory, gcp_storage, r2, cdn]] \| NoneType` | `['cdn', 'fal']` | -           |
  | `request`             | `Optional[Request]`                                                                                                                                                                    | `None`           | -           |

  **Returns:** `Image`

  #### from\_pil

  ```python theme={null}
  def from_pil(cls, pil_image: 'PILImage.Image', format: 'ImageFormat | None' = None, file_name: 'str | None' = None, repository: 'FileRepository | RepositoryId' = 'fal_v3', fallback_repository: 'Optional[FileRepository | RepositoryId | list[FileRepository | RepositoryId]]' = ['cdn', 'fal'], request: 'Optional[Request]' = None) -> 'Image'
  ```

  | Parameter             | Type                                                                               | Default          | Description |
  | :-------------------- | :--------------------------------------------------------------------------------- | :--------------- | :---------- |
  | `pil_image`           | `PILImage.Image`                                                                   | -                | -           |
  | `format`              | `ImageFormat \| None`                                                              | `None`           | -           |
  | `file_name`           | `str \| None`                                                                      | `None`           | -           |
  | `repository`          | `FileRepository \| RepositoryId`                                                   | `'fal_v3'`       | -           |
  | `fallback_repository` | `Optional[FileRepository \| RepositoryId \| list[FileRepository \| RepositoryId]]` | `['cdn', 'fal']` | -           |
  | `request`             | `Optional[Request]`                                                                | `None`           | -           |

  #### to\_pil

  ```python theme={null}
  def to_pil(self, mode: 'str' = 'RGB') -> 'PILImage.Image'
  ```

  | Parameter | Type  | Default | Description |
  | :-------- | :---- | :------ | :---------- |
  | `mode`    | `str` | `'RGB'` | -           |
</Accordion>

### KVStore

```python theme={null}
class fal.toolkit.KVStore
```

A key-value store client for interacting with the FAL KV service.

<Accordion title="Constructor Parameters" defaultOpen>
  | Name      | Type  | Default | Description                                                  |
  | :-------- | :---- | :------ | :----------------------------------------------------------- |
  | `db_name` | `str` | -       | The name of the database/namespace to use for this KV store. |
</Accordion>

<Accordion title="Properties" defaultOpen>
  | Name           | Type             | Description |
  | :------------- | :--------------- | :---------- |
  | `auth_headers` | `dict[str, str]` | -           |
</Accordion>

<Accordion title="Methods" defaultOpen>
  #### get

  ```python theme={null}
  def get(self, key: str) -> Optional[str]
  ```

  Retrieve a value from the key-value store.

  | Parameter | Type  | Default | Description                        |
  | :-------- | :---- | :------ | :--------------------------------- |
  | `key`     | `str` | -       | The key to retrieve the value for. |

  **Returns:** `Optional[str]`

  #### set

  ```python theme={null}
  def set(self, key: str, value: str) -> None
  ```

  Store a value in the key-value store.

  | Parameter | Type  | Default | Description                       |
  | :-------- | :---- | :------ | :-------------------------------- |
  | `key`     | `str` | -       | The key to store the value under. |
  | `value`   | `str` | -       | The value to store.               |

  **Returns:** `NoneType`
</Accordion>

### Video

```python theme={null}
class fal.toolkit.Video
```

!!! abstract "Usage Documentation" [Models](../concepts/models.md)

A base class for creating Pydantic models.

> **Inherits from:** `File`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

### FalTookitException

```python theme={null}
class fal.toolkit.FalTookitException
```

Base exception for all toolkit exceptions

> **Inherits from:** `Exception`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type | Default | Description |
  | :------- | :--- | :------ | :---------- |
  | `args`   | -    | -       | -           |
  | `kwargs` | -    | -       | -           |
</Accordion>

### FileUploadException

```python theme={null}
class fal.toolkit.FileUploadException
```

Raised when file upload fails

> **Inherits from:** `FalTookitException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type | Default | Description |
  | :------- | :--- | :------ | :---------- |
  | `args`   | -    | -       | -           |
  | `kwargs` | -    | -       | -           |
</Accordion>

### KVStoreException

```python theme={null}
class fal.toolkit.KVStoreException
```

Raised when KV store operation fails

> **Inherits from:** `FalTookitException`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type | Default | Description |
  | :------- | :--- | :------ | :---------- |
  | `args`   | -    | -       | -           |
  | `kwargs` | -    | -       | -           |
</Accordion>

### DownloadError

```python theme={null}
class fal.toolkit.DownloadError
```

Common base class for all non-exit exceptions.

> **Inherits from:** `Exception`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name     | Type | Default | Description |
  | :------- | :--- | :------ | :---------- |
  | `args`   | -    | -       | -           |
  | `kwargs` | -    | -       | -           |
</Accordion>

***

## Functions

### Hidden

```python theme={null}
def Hidden(field: '_T') -> '_T'
```

Wrapper that marks a Field as hidden in the UI. The field MUST have a default or default\_factory set since hidden
fields cannot be required inputs in the UI.

Usage:
class Input(FalBaseModel):
prompt: str = Field(...)
hidden\_flag: bool = Hidden(Field(default=False))

| Parameter | Type | Default | Description                                          |
| :-------- | :--- | :------ | :--------------------------------------------------- |
| `field`   | `_T` | -       | A pydantic FieldInfo instance (result of Field(...)) |

**Returns:** `_T`

**Raises:**

* `ValueError`: If field has no default or default\_factory

### get\_image\_size

```python theme={null}
def get_image_size(source: 'ImageSizeInput') -> 'ImageSize'
```

| Parameter | Type                                                                                                  | Default | Description |
| :-------- | :---------------------------------------------------------------------------------------------------- | :------ | :---------- |
| `source`  | `ImageSize \| Literal[square_hd, square, portrait_4_3, portrait_16_9, landscape_4_3, landscape_16_9]` | -       | -           |

**Returns:** `ImageSize`

### optimize

```python theme={null}
def optimize(module: 'torch.nn.Module', *, optimization_config: 'dict[str, Any] | None' = None) -> 'torch.nn.Module'
```

Optimize the given torch module with dynamic compilation and quantization techniques. Only applicable under fal's cloud environment.

Warning: This function is experimental and may not work as expected.

| Parameter             | Type                     | Default | Description |
| :-------------------- | :----------------------- | :------ | :---------- |
| `module`              | `torch.nn.Module`        | -       | -           |
| `optimization_config` | `dict[str, Any] \| None` | `None`  | -           |

### clone\_repository

```python theme={null}
def clone_repository(https_url: 'str', *, commit_hash: 'str | None' = None, target_dir: 'str | Path | None' = None, repo_name: 'str | None' = None, force: 'bool' = False, include_to_path: 'bool' = False) -> 'Path'
```

Clones a Git repository from the specified HTTPS URL into a local directory.

This function clones a Git repository from the specified HTTPS URL into a local
directory. It can also checkout a specific commit if the `commit_hash` is provided.

If a custom `target_dir` or `repo_name` is not specified, a predefined directory is
used for the target directory, and the repository name is determined from the URL.

| Parameter         | Type                          | Default | Description                                                                                                                                      |
| :---------------- | :---------------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| `https_url`       | `str`                         | -       | The HTTPS URL of the Git repository to be cloned.                                                                                                |
| `commit_hash`     | `str \| None`                 | `None`  | The commit hash to checkout after cloning.                                                                                                       |
| `target_dir`      | `str \| pathlib.Path \| None` | `None`  | The directory where the repository will be saved. If not provided, a predefined directory is used.                                               |
| `repo_name`       | `str \| None`                 | `None`  | The name to be used for the cloned repository directory. If not provided, the repository's name from the URL is used.                            |
| `force`           | `bool`                        | `False` | If `True`, the repository is cloned even if it already exists locally and its commit hash matches the provided commit hash. Defaults to `False`. |
| `include_to_path` | `bool`                        | `False` | If `True`, the cloned repository is added to the `sys.path`. Defaults to `False`.                                                                |

**Returns:** `Path`

### download\_file

```python theme={null}
def download_file(url: 'str', target_dir: 'str | Path', *, force: 'bool' = False, request_headers: 'dict[str, str] | None' = None, filesize_limit: 'int | None' = None) -> 'Path'
```

Downloads a file from the specified URL to the target directory. The function downloads the file from the given URL and saves it in the specified
target directory, provided it is below the given filesize limit.

It also checks whether the local file already exists and whether its content length
matches the expected content length from the remote file. If the local file already
exists and its content length matches the expected content length from the remote
file, the existing file is returned without re-downloading it.

If the file needs to be downloaded or if an existing file's content length does not
match the expected length, the function proceeds to download and save the file. It
ensures that the target directory exists and handles any errors that may occur
during the download process, raising a `DownloadError` if necessary.

| Parameter         | Type                     | Default | Description                                                                                                                                                               |
| :---------------- | :----------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `url`             | `str`                    | -       | The URL of the file to be downloaded.                                                                                                                                     |
| `target_dir`      | `str \| pathlib.Path`    | -       | The directory where the downloaded file will be saved. If it's not an absolute path, it's treated as a relative directory to "/data".                                     |
| `force`           | `bool`                   | `False` | If `True`, the file is downloaded even if it already exists locally and its content length matches the expected content length from the remote file. Defaults to `False`. |
| `request_headers` | `dict[str, str] \| None` | `None`  | A dictionary containing additional headers to be included in the HTTP request. Defaults to `None`.                                                                        |
| `filesize_limit`  | `int \| None`            | `None`  | An integer specifying the maximum downloadable size, in megabytes. Defaults to `None`.                                                                                    |

**Returns:** `Path`

**Raises:**

* `ValueError`: If the provided `file_name` contains a forward slash ('/').
* `DownloadError`: If an error occurs during the download process.

### download\_model\_weights

```python theme={null}
def download_model_weights(url: 'str', force: 'bool' = False, request_headers: 'dict[str, str] | None' = None) -> 'Path'
```

Downloads model weights from the specified URL and saves them to a predefined directory.

This function is specifically designed for downloading model weights and stores
them in a predefined directory.

It calls the `download_file` function with the provided
URL and the target directory set to a pre-defined location for model weights.
The downloaded model weights are saved in this directory, and the function returns
the full path to the downloaded weights file.

| Parameter         | Type                     | Default | Description                                                                                                                                                                            |
| :---------------- | :----------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`             | `str`                    | -       | The URL from which the model weights will be downloaded.                                                                                                                               |
| `force`           | `bool`                   | `False` | If `True`, the model weights are downloaded even if they already exist locally and their content length matches the expected content length from the remote file. Defaults to `False`. |
| `request_headers` | `dict[str, str] \| None` | `None`  | A dictionary containing additional headers to be included in the HTTP request. Defaults to `None`.                                                                                     |

**Returns:** `Path`

### get\_gpu\_type

```python theme={null}
def get_gpu_type() -> 'str'
```

Detect the GPU type using nvidia-smi.

**Example:**

```python theme={null}
>>> gpu_type = get_gpu_type()
>>> print(f"Running on: {gpu_type}")
Running on: H100
```

**Returns:** `str`

### load\_inductor\_cache

```python theme={null}
def load_inductor_cache(cache_key: 'str') -> 'str'
```

Load PyTorch Inductor compilation cache from global storage. This function:

1. Sets TORCHINDUCTOR\_CACHE\_DIR environment variable
2. Looks for cached compiled kernels in GPU-specific global storage
3. Unpacks the cache to local temporary directory
4. Returns a hash of the unpacked directory for change detection

**Example:**

```python theme={null}
>>> dir_hash = load_inductor_cache("flux/2")
Found compilation cache at /data/inductor-caches/H100/flux/2.zip, unpacking...
Cache unpacked successfully.
```

| Parameter   | Type  | Default | Description                                                     |
| :---------- | :---- | :------ | :-------------------------------------------------------------- |
| `cache_key` | `str` | -       | Unique identifier for this cache (e.g., "flux/2", "mymodel/v1") |

**Returns:** `str`

### sync\_inductor\_cache

```python theme={null}
def sync_inductor_cache(cache_key: 'str', unpacked_dir_hash: 'str') -> 'None'
```

Sync updated PyTorch Inductor cache back to global storage. This function:

1. Checks if the local cache has changed (by comparing hashes)
2. If changed, creates a zip archive of the new cache
3. Saves it to GPU-specific global storage

**Example:**

```python theme={null}
>>> sync_inductor_cache("flux/2", dir_hash)
No changes in the cache dir, skipping sync.
# or
Changes detected in the cache dir, syncing...
```

| Parameter           | Type  | Default | Description                                                              |
| :------------------ | :---- | :------ | :----------------------------------------------------------------------- |
| `cache_key`         | `str` | -       | Unique identifier for this cache (same as used in load\_inductor\_cache) |
| `unpacked_dir_hash` | `str` | -       | Hash returned from load\_inductor\_cache (for change detection)          |

**Returns:** `NoneType`

### synchronized\_inductor\_cache

```python theme={null}
def synchronized_inductor_cache(cache_key: 'str') -> 'Iterator[None]'
```

Context manager to automatically load and sync PyTorch Inductor cache. This wraps load\_inductor\_cache and sync\_inductor\_cache for convenience.
The cache is loaded on entry and synced on exit (even if an exception occurs).

**Example:**

```python theme={null}
>>> with synchronized_inductor_cache("mymodel/v1"):
...     self.model = torch.compile(self.model)
...     self.warmup()  # Compilation happens here
# Cache is automatically synced after the with block
```

| Parameter   | Type  | Default | Description                                                     |
| :---------- | :---- | :------ | :-------------------------------------------------------------- |
| `cache_key` | `str` | -       | Unique identifier for this cache (e.g., "flux/2", "mymodel/v1") |

**Returns:** `Iterator[]`


# https://fal.ai/docs/api-reference/python-sdk/fal-toolkit-image-nsfw-filter.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal.toolkit.image.nsfw_filter

> API reference for fal.toolkit.image.nsfw_filter

```python theme={null}
from fal.toolkit.image.nsfw_filter import NSFWImageDetectionInput, NSFWImageDetectionOutput, run_nsfw_estimation
```

## Classes

### NSFWImageDetectionInput

```python theme={null}
class fal.toolkit.image.nsfw_filter.NSFWImageDetectionInput
```

!!! abstract "Usage Documentation" [Models](../concepts/models.md)

A base class for creating Pydantic models.

> **Inherits from:** `BaseModel`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name        | Type  | Default | Description |
  | :---------- | :---- | :------ | :---------- |
  | `image_url` | `str` | -       | -           |
</Accordion>

### NSFWImageDetectionOutput

```python theme={null}
class fal.toolkit.image.nsfw_filter.NSFWImageDetectionOutput
```

!!! abstract "Usage Documentation" [Models](../concepts/models.md)

A base class for creating Pydantic models.

> **Inherits from:** `BaseModel`

<Accordion title="Constructor Parameters" defaultOpen>
  | Name   | Type  | Default | Description |
  | :----- | :---- | :------ | :---------- |
  | `data` | `Any` | -       | -           |
</Accordion>

<Accordion title="Class Variables" defaultOpen>
  | Name               | Type    | Default | Description |
  | :----------------- | :------ | :------ | :---------- |
  | `nsfw_probability` | `float` | -       | -           |
</Accordion>

***

## Functions

### run\_nsfw\_estimation

```python theme={null}
def run_nsfw_estimation(input: fal.toolkit.image.nsfw_filter.inference.NSFWImageDetectionInput) -> fal.toolkit.image.nsfw_filter.inference.NSFWImageDetectionOutput
```

| Parameter | Type                      | Default | Description |
| :-------- | :------------------------ | :------ | :---------- |
| `input`   | `NSFWImageDetectionInput` | -       | -           |

**Returns:** `NSFWImageDetectionOutput`


# https://fal.ai/docs/changelog.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Product Changelog

> Latest features and updates to the fal platform

<div className="max-w-2xl mx-auto bg-gradient-to-br from-blue-600/10 to-blue-500/5 border border-blue-500/20 rounded-xl p-5 mb-8 shadow-sm">
  <div className="flex items-center gap-2.5 mb-4">
    <div className="w-8 h-8 rounded-lg bg-blue-500/15 flex items-center justify-center">
      <svg width="14" height="14" viewBox="0 0 24 24" fill="#3386FE" xmlns="http://www.w3.org/2000/svg">
        <path d="M8 5.14v14.72a1 1 0 001.5.86l11-7.36a1 1 0 000-1.72l-11-7.36a1 1 0 00-1.5.86z" />
      </svg>
    </div>

    <div>
      <span className="font-semibold text-blue-700 dark:text-blue-400">
        What's New in Serverless
      </span>

      <span className="text-sm text-gray-500 dark:text-gray-400 ml-2">
        Scaling, observability, cold starts, multi-GPU & more
      </span>
    </div>
  </div>

  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?autoplay=1'><img src='https://img.youtube.com/vi/gDJJ9bppyV8/maxresdefault.jpg' alt='What's New in fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</div>

<Update label="April 29, 2026" tags={["Dashboard", "Analytics", "Serverless"]}>
  ## Aggregate Analytics Components

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/NH1xMgqfuYMzBqdq/images/changelog/apps.png?fit=max&auto=format&n=NH1xMgqfuYMzBqdq&q=85&s=39b65eb1b8d4b4f4d0376c0a11b57a05" alt="Serverless apps page showing shared health metrics components for runners, requests, latency, errors, and queue" className="w-full rounded-lg" width="5504" height="3128" data-path="images/changelog/apps.png" />
  </Frame>

  We introduced new aggregate analytics components on serverless app surfaces to keep health signals consistent between the app listing and each app header.

  * Shared metrics components now power **Runners, Reqs/min, Latency, and Errors** in both app cards and app detail headers
  * Reqs/min, latency, and error trends are shown with directional indicators using recent activity windows, so regressions stand out at a glance
  * App headers now pair those analytics signals with a queue metric, giving a compact operational snapshot before drilling into detailed analytics tabs
</Update>

<Update label="April 28, 2026" tags={["CDN", "Storage"]}>
  ## Legacy CDN Cleanup — June 1st, 2026

  On **June 1st, 2026**, any legacy CDN object not accessed in the past 6 months will be deleted.

  **How to identify legacy objects:** Legacy URLs look like `/files/[animal]/[filename]` (e.g. `/files/otter/AFsfdoliuhhvf.mp4`). Anything served from `/files/b/...` is on our current CDN and is unaffected.

  **If you've accessed it recently, it's already safe:** Any legacy object accessed in the last 6 months has already been automatically migrated to our current CDN — no action needed on your end. The URL is unchanged and the object will be preserved.

  **To keep a legacy object you haven't touched in a while:** Access it once before **June 1st, 2026**. That single access triggers the automatic migration and preserves the object. The URL stays the same.

  **What stays the same:**

  * Legacy URLs continue to work — no code changes needed
  * Anything new you create already uses the modern CDN (`/files/b/...`)
</Update>

<Update label="April 27, 2026" tags={["Serverless", "ComfyUI"]}>
  ## Deploy ComfyUI on fal — Visual Control

  Run ComfyUI workflows on fal serverless GPUs without writing a single line of code. Two pre-built zip packages, one double-click — your team is generating on H100s in minutes.

  * **User package** — a tiny launcher UI on `localhost:9998`. Paste your fal API key and the endpoint slug your team lead gave you, click **Start**, and the full ComfyUI canvas opens on `localhost:8188` running against the cloud GPU.
  * **Admin package** — a complete management UI on `localhost:9999`. Add models, custom nodes, and Python deps from a table, set HuggingFace / Civitai tokens for gated weights (auto-pushed to fal secrets at deploy), and ship with one click. Live runner observability, an outputs gallery, and an undeploy switch are built in.

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/Un5AMpXNKs4_TsjB/images/changelog/comfyui-visual-admin.png?fit=max&auto=format&n=Un5AMpXNKs4_TsjB&q=85&s=f0f6c87a56d04a741a6a535ea505cc84" alt="Admin web UI showing the Models tab — folders, filenames, download URLs in a table" className="w-full rounded-lg" width="2576" height="1470" data-path="images/changelog/comfyui-visual-admin.png" />
  </Frame>

  The launcher auto-installs `uv` and Python 3.11 on first run — no Python knowledge required from end users. Works on macOS and Windows.

  [Read the guide →](/examples/image-generation/run-comfyui-visual)
</Update>

<Update label="April 23, 2026" tags={["Dashboard", "Serverless"]}>
  ## Runner Termination Reason

  Diagnose why a runner was terminated directly from the dashboard. The reason now appears across every runner surface.

  * **Runner detail page** — termination reason is shown inline next to the state.

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/GdCSIoK3y-dVum8C/images/changelog/runner-terminate-reason-detail.png?fit=max&auto=format&n=GdCSIoK3y-dVum8C&q=85&s=b855acfc34426bf63bdcc0877d1a2bb1" alt="Runner detail page state section showing termination reason badge" className="w-full rounded-lg" width="2832" height="758" data-path="images/changelog/runner-terminate-reason-detail.png" />
  </Frame>

  * **Runner list** — surfaces the same reason via a tooltip on the state badge, so you can scan failures without opening each runner

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/GdCSIoK3y-dVum8C/images/changelog/runner-terminate-reason-list.png?fit=max&auto=format&n=GdCSIoK3y-dVum8C&q=85&s=86dcc994543b9f7ad36e7ccd4d9a3d9a" alt="Runner list with termination reason tooltip on the state badge" className="w-full rounded-lg" width="2816" height="320" data-path="images/changelog/runner-terminate-reason-list.png" />
  </Frame>

  * **Runner events timeline** — event rows display the termination reason as a highlighted badge alongside the status text

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/GdCSIoK3y-dVum8C/images/changelog/runner-terminate-reason-events.png?fit=max&auto=format&n=GdCSIoK3y-dVum8C&q=85&s=d27c350bee87a53a7357c64e52a3dcd9" alt="Runner event row showing termination reason as a highlighted badge alongside the status text" className="w-full rounded-lg" width="2830" height="500" data-path="images/changelog/runner-terminate-reason-events.png" />
  </Frame>

  Please note that in some cases the termination reason may be unknown. When that happens, no reason badge or tooltip is shown.
</Update>

<Update label="April 23, 2026" tags={["Workflows", "Product"]}>
  ## fal Workflow

  * Improved the model search experience
  * Improved API documentation
  * Smoother workflow when adding models
  * Node IDs are visible in the UI
  * Nodes can be locked
  * Media-type icons on node handles
  * Performance improvements and bug fixes
</Update>

<Update label="April 14, 2026" tags={["Documentation", "API Reference"]}>
  ## Model API Reference

  We've launched a comprehensive **[Model API Reference](/model-api-reference)** — auto-generated documentation for every top model on fal.ai, covering video generation, image generation, audio, vision, and 3D.

  Each model page includes:

  * **Full input/output schemas** with parameter descriptions, types, and defaults
  * **Quick Start code examples** in Python, JavaScript, and cURL
  * **Real prompt-and-output examples** pulled directly from the fal.ai playground
  * **Rich model descriptions** with feature breakdowns, comparisons, and technical specs
  * **Direct playground links** to try models interactively

  The reference is organized by model family (FLUX, Kling Video, Seedance, Nano Banana, Veo, and more) with a navigation structure that mirrors the endpoint hierarchy. Browse by category or jump straight to any endpoint.

  [Explore the Model API Reference →](/model-api-reference)
</Update>

<Update label="April 10, 2026" tags={["Platform API", "Analytics", "Serverless"]}>
  ## Serverless Analytics API

  * New **[`GET /v1/serverless/analytics`](/platform-apis/v1/serverless/analytics)** endpoint lets serverless app owners query time-bucketed analytics across all inbound traffic to their endpoints
  * Retrieve request counts, success/error rates, and latency percentiles (p50/p75/p90) for any date range and timeframe
  * Ideal for exporting analytics to your own tools like BigQuery, Grafana, or Datadog
  * Requires endpoint ownership — only the app owner can access these metrics
  * The existing [`GET /v1/models/analytics`](/platform-apis/v1/models/analytics) continues to show your own request activity as a caller
</Update>

<Update label="April 1, 2026" tags={["Dashboard", "Analytics", "Serverless"]}>
  ## Latency Percentile Chart

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/latency-percentile-chart.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=b652d30a1d10d515e5c2adada4b7c364" alt="Latency percentile chart showing p50, p90, p95, and p99 over time" className="w-full rounded-lg" width="2908" height="660" data-path="images/changelog/latency-percentile-chart.png" />
  </Frame>

  * The [analytics page](/documentation/serverless/observability/app-analytics) now includes a **latency percentile chart** showing p50, p90, p95, and p99 request latency over time
  * Quickly spot latency regressions or tail-latency spikes at a glance
</Update>

<Update label="March 31, 2026" tags={["Dashboard", "Analytics", "Serverless"]}>
  ## Multi-Endpoint Aggregation in Analytics

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/multi-endpoint-aggregation.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=612727e3c34f436fb147b05517d4bdd4" alt="Analytics endpoint selector with All option for aggregated metrics" className="w-full rounded-lg" width="2908" height="1916" data-path="images/changelog/multi-endpoint-aggregation.png" />
  </Frame>

  * Select **"All" endpoints** in [App Analytics](/documentation/serverless/observability/app-analytics) to see metrics aggregated across every endpoint at once
  * Aggregation works across request counts, error rates, percentile charts, and gateway stats, so you can get a full picture of your app's performance without switching between endpoints
</Update>

<Update label="March 31, 2026" tags={["Dashboard", "Serverless"]}>
  ## GPU and Runner Metrics on Apps Page

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/gpu-runner-metrics-apps.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=4d30827b73e8c4dab8707307896f688d" alt="Apps page with aggregate metrics bar showing runners, queue depth, and GPU distribution" className="w-full rounded-lg" width="2908" height="572" data-path="images/changelog/gpu-runner-metrics-apps.png" />
  </Frame>

  * The [apps page](/documentation/deployment/manage-deployments) now shows an **aggregate metrics bar** with total runners, queue depth, and GPU distribution, giving you a quick overview of your resource usage without clicking into each app
  * **Per-app GPU and queue columns** in both card view and list view make it easy to compare usage across apps at a glance
</Update>

<Update label="March 31, 2026" tags={["Dashboard", "Serverless"]}>
  ## Logs Endpoint Filtering and Source Column

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/logs-endpoint-source.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=0637fb4efb04c9488924b69b2a91cff1" alt="Logs view with endpoint filter and source column" className="w-full rounded-lg" width="4530" height="572" data-path="images/changelog/logs-endpoint-source.png" />
  </Frame>

  * **Filter [logs](/serverless/development/logging) by endpoint** to focus on a specific route
  * A new **Source column** shows which endpoint or system action produced each log line
</Update>

<Update label="March 30, 2026" tags={["Dashboard", "Serverless"]}>
  ## Notifications Overhaul

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/notifications-overhaul.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=ead345f1f0c40abef26501511f790595" alt="Redesigned notifications dropdown with pagination and mark all read" className="w-full rounded-lg" width="3316" height="2142" data-path="images/changelog/notifications-overhaul.png" />
  </Frame>

  * **Redesigned notification dropdown** so you can stay on top of issues without leaving the page you're on
  * **Category filtering** lets you cut through noise and focus on the notification types that matter to you
  * **Pagination** so you can browse your full notification history without losing your place
  * **Mark all as read** to quickly clear your inbox when you've caught up
  * **OOM alerts** notify you when a runner runs out of memory, so you can resize before it impacts users
  * **Notification badge on app tabs** shows unread counts per app so you know exactly which apps need attention

  See [notification settings](/documentation/serverless/observability/slack-notifications) to configure alerts.
</Update>

<Update label="March 28, 2026" tags={["Dashboard", "Analytics", "Serverless"]}>
  ## Cold Start and Queue Percentiles

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/cold-start-queue-percentiles.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=17f96717c19e1fa0ac28027d8a1d49d5" alt="Analytics page showing cold start ratio, cold start percentiles, and queue wait percentiles" className="w-full rounded-lg" width="3316" height="1906" data-path="images/changelog/cold-start-queue-percentiles.png" />
  </Frame>

  * **Cold start ratio** shows what percentage of requests hit a cold start, so you can measure the impact of your scaling configuration
  * **Cold start duration percentiles** (p50, p75, p90, p95) help you understand whether cold starts are a minor delay or a real bottleneck for your users
  * **Queue wait percentiles** (p50, p75, p90, p95) reveal how long requests wait before a runner picks them up, helping you decide if you need more concurrency
  * A new **startup breakdown card** shows exactly where startup time goes (image pull, setup, etc.) so you know what to optimize
  * The [analytics](/documentation/serverless/observability/app-analytics) layout has been redesigned with expandable sections so you can focus on the metrics that matter most
</Update>

<Update label="March 28, 2026" tags={["Dashboard", "Analytics", "Serverless"]}>
  ## Request Throughput Charts

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/request-throughput-charts.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=63a293ed8a4ebec930f7f3a42eff8be3" alt="Charts showing processed requests per second, received requests per second, and concurrent requests" className="w-full rounded-lg" width="3316" height="544" data-path="images/changelog/request-throughput-charts.png" />
  </Frame>

  New charts are available on the [App Analytics](/documentation/serverless/observability/app-analytics) Requests tab:

  * **Processed requests per second** chart shows your inference throughput over time
  * **Received requests per second** chart shows the inbound request rate
  * **Concurrent requests** chart shows how many requests are in-flight simultaneously
</Update>

<Update label="March 28, 2026" tags={["Dashboard"]}>
  ## API Key Tags and Editing

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/api-key-tags-editing.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=433861fbc2313a08b37a7b53c64a55d7" alt="Keys page with tags column and editable key descriptions" className="w-full rounded-lg" width="3540" height="1202" data-path="images/changelog/api-key-tags-editing.png" />
  </Frame>

  * **Tags on [API keys](/documentation/setting-up/authentication/index)** let you organize keys with the same tagging system used for apps
  * **Editable key descriptions** can now be updated directly from the dashboard without recreating the key
</Update>

<Update label="March 27, 2026" tags={["Dashboard", "Serverless"]}>
  ## Request Timing Breakdown

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/request-timing-breakdown.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=905043093a77cbf45aa840451a649378" alt="Request list showing duration broken into startup time and execution time" className="w-full rounded-lg" width="4838" height="1368" data-path="images/changelog/request-timing-breakdown.png" />
  </Frame>

  * Request duration in the [requests list](/serverless/deployment-operations/monitor-performance) now shows a **breakdown into startup time and execution time**
  * Hover over the duration to see the full timing detail
</Update>

<Update label="March 27, 2026" tags={["Dashboard", "Serverless"]}>
  ## Environment Manager

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/_K0ozUKUZUyNXY0L/images/changelog/environment-manager.png?fit=max&auto=format&n=_K0ozUKUZUyNXY0L&q=85&s=f2ddcafc9f772e06c0aff90ec68643aa" alt="Environment manager dialog for creating and deleting environments" className="w-full rounded-lg" width="2950" height="946" data-path="images/changelog/environment-manager.png" />
  </Frame>

  * A new **[environment manager](/serverless/deployment-operations/manage-environments) dialog** lets you create and delete environments in one place
  * The environment selector is now **searchable**, replacing the old dropdown
</Update>

<Update label="March 25, 2026" tags={["Dashboard", "Serverless"]}>
  ## Requests Page Overhaul

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/o8eW4dsVeOWMw5el/images/changelog/requests-page-overhaul.png?fit=max&auto=format&n=o8eW4dsVeOWMw5el&q=85&s=6f0dec1c687f0a72c19529ae9502d6bc" alt="Requests page with status code charts, p90 latency, and sortable request list" className="w-full rounded-lg" width="5120" height="2510" data-path="images/changelog/requests-page-overhaul.png" />
  </Frame>

  * **Status code and latency charts** — the requests page now shows interactive charts for request status code distribution and p90 latency over time, giving you an instant picture of your app's health
  * **Click and drag to filter** — select a time range on any chart to filter the request list below to just that window, making it easy to isolate a spike or incident
  * **Sort by cold start, execution time, and latency** — sort the request list by longest cold start duration, execution time, total latency, and more to quickly surface the slowest or most problematic requests
  * **Jump to Analytics** — a direct link takes you from the requests page to App Analytics with your current filters pre-applied
</Update>

<Update label="March 23, 2026" tags={["Dashboard", "Runners", "Serverless"]}>
  ## Runner Summary on App Overview

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/o8eW4dsVeOWMw5el/images/changelog/runner-summary-card.png?fit=max&auto=format&n=o8eW4dsVeOWMw5el&q=85&s=659748d93f5c17e43f616c0c86d99973" alt="Runner summary card showing active runner counts, state breakdowns, and concurrency trend" className="w-full rounded-lg" width="1022" height="920" data-path="images/changelog/runner-summary-card.png" />
  </Frame>

  * The app overview page now includes a **runner summary card** showing active runner counts, state breakdowns, and a concurrency trend chart at a glance
  * Quickly see how many runners are in each state (running, idle, pending, setup) without navigating to the Runners page
</Update>

<Update label="March 20, 2026" tags={["Dashboard", "Runners", "Serverless"]}>
  ## Search Runners by ID

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/o8eW4dsVeOWMw5el/images/changelog/runner-id-search.png?fit=max&auto=format&n=o8eW4dsVeOWMw5el&q=85&s=f1b14ce93d0862ff6364bcd8e5806cb7" alt="Runner ID search on the Runners page" className="w-full rounded-lg" width="2876" height="1068" data-path="images/changelog/runner-id-search.png" />
  </Frame>

  * Search for a specific runner by its ID on the Runners page — useful when you have a runner ID from logs, alerts, or incident reports
  * Results display instantly with full runner details, and the Refresh button re-fetches the searched runner
</Update>

<Update label="March 20, 2026" tags={["Dashboard", "Serverless"]}>
  ## Error Types in App Requests and Errors pages

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/o8eW4dsVeOWMw5el/images/changelog/error-types-ui.png?fit=max&auto=format&n=o8eW4dsVeOWMw5el&q=85&s=28a9aeb6cfea6071d12d5858af5c9ae7" alt="Error type badges on request logs showing specific failure reasons" className="w-full rounded-lg" width="4896" height="1082" data-path="images/changelog/error-types-ui.png" />
  </Frame>

  * Failed requests in the dashboard now show the **specific reason** for the failure — not just a status code, but whether it was a `request_timeout`, `runner_disconnected`, `startup_timeout`, `runner_scheduling_failure`, and more
  * Instantly understand if a 500 was caused by your code crashing, the runner running out of memory, or a scheduling issue — without digging through logs
  * Error types are shown as badges on request rows and in the request detail view, matching the `error_type` field in [API responses](/model-apis/errors#request-error-types)
</Update>

<Update label="March 20, 2026" tags={["Dashboard", "Serverless"]}>
  ## Granularity Picker on App Overview Chart

  <Frame>
    <img src="https://mintcdn.com/fal-d8505a2e/o8eW4dsVeOWMw5el/images/changelog/granularity-picker.png?fit=max&auto=format&n=o8eW4dsVeOWMw5el&q=85&s=4caf1dec51215ceb44a02a7d5bfd48cb" alt="Granularity picker on the app overview chart" className="w-full rounded-lg" width="1910" height="874" data-path="images/changelog/granularity-picker.png" />
  </Frame>

  * The app overview chart now includes a **granularity picker** to control the time bucket size — defaults to 10-minute intervals
  * Choose finer or coarser intervals to zoom into specific traffic patterns or view broader trends
</Update>

<Update label="March 16, 2026" tags={["Dashboard", "Serverless"]}>
  ## Enhanced App Cards

  * App cards on the listing page now show **separate client and server error rates** for clearer error attribution
  * Updated **machine type icons** for better visual identification of GPU types
  * Improved card layout with more readable stat values
</Update>

<Update label="March 20, 2026" tags={["Serverless"]}>
  ## REST API `/metrics` Improvements

  Runner-level resource metrics are now available through the REST API:

  * **Runner resource metrics** — CPU, memory, GPU, and VRAM usage are now included in `/metrics`, summed across all runners per app
  * **Per-runner metrics endpoint** — `GET /metrics/runners/{runner_id}` returns resource metrics for an individual runner
</Update>

<Update label="March 18, 2026" tags={["Platform"]}>
  ## fal MCP Server

  The fal MCP server is now available at `mcp.fal.ai`. Connect any AI assistant that supports the [Model Context Protocol](https://modelcontextprotocol.io) — Claude Code, Claude Desktop, Cursor, Windsurf, and more — to the full fal platform.

  **9 tools** let your assistant search 1,000+ models, check schemas and pricing, run inference, upload files, and browse documentation — all from a single conversation.

  ```bash theme={null}
  claude mcp add --transport http fal-ai \
    https://mcp.fal.ai/mcp \
    --header "Authorization: Bearer $FAL_KEY"
  ```

  The server is fully stateless and free to use. You only pay for the model runs you trigger.

  * [Setup guide](/documentation/setting-up/mcp)
</Update>

<Update label="March 17, 2026" tags={["Serverless"]}>
  ## `x-fal-stop-runner` Response Header

  You can now control whether a runner is terminated after a response using the `x-fal-stop-runner` response header, independent of the HTTP status code.

  * Set `x-fal-stop-runner: true` to force runner termination with any status code (same effect as a 503 on the runner, without requiring a 503 response)
  * Set `x-fal-stop-runner: false` to keep the runner alive even when returning a 503 (useful when you want the retry behavior of a 503 without killing the runner)
  * The header is stripped from the response before it reaches the caller
  * Combine with `X-Fal-Needs-Retry` to fully decouple retry behavior from runner lifecycle — for example, retry on a fresh runner (`X-Fal-Needs-Retry: 1` + `x-fal-stop-runner: true`) or retry while keeping the current runner alive (`X-Fal-Needs-Retry: 1` + `x-fal-stop-runner: false`)

  See [Retries and Error Handling](/documentation/serverless/reliability/retries#per-response-x-fal-stop-runner) for full details.
</Update>

<Update label="March 12, 2026" tags={["Dashboard", "Serverless"]}>
  ## Delete App Versions

  * You can now **delete individual app versions** directly from the dashboard
  * Useful for cleaning up old or failed deployments without needing the CLI
  * A confirmation dialog prevents accidental deletions
</Update>

<Update label="March 12, 2026" tags={["Dashboard", "Runners"]}>
  ## Shareable Runner Details

  * Runner slideout panels are now **shareable via URL** — click on a runner and copy the link to share the exact runner view with a teammate
  * Helpful for debugging runner issues collaboratively or linking from incident reports
</Update>

<Update label="March 12, 2026" tags={["Dashboard", "Serverless"]}>
  ## Endpoint Filter in Request Logs

  * Filter your request logs by **specific endpoint** to focus on traffic to a particular route (e.g. `/predict` vs `/health`)
  * Works alongside existing filters for status codes, date ranges, and apps
</Update>

<Update label="March 11, 2026" tags={["Dashboard", "Analytics", "Serverless"]}>
  ## Interval Selection and Chart Zoom in Analytics

  * The analytics pages now include an **Interval** picker that lets you control how metrics are bucketed — choose from **30 seconds**, **1 minute**, **5 minutes**, **10 minutes**, **1 hour**, **1 day**, **1 week**, or **1 month** depending on your selected date range
  * Use finer intervals (30 sec, 1 min) to pinpoint exact moments when latency spiked or error rates changed, and wider intervals (1 day, 1 week) for high-level trends over longer periods
  * **Click and drag on any chart** in [App Analytics](/documentation/serverless/observability/app-analytics) to select a time range and instantly zoom into that window — the date range updates automatically so you can isolate an incident, compare before-and-after a deployment, or drill into a traffic spike without manually adjusting date pickers
  * The Interval picker is available on both the **Requests** and **Runners** tabs in App Analytics, as well as in [Error Analytics](/serverless/observability/error-analytics)
</Update>

<Update label="March 11, 2026" tags={["Dashboard", "Serverless"]}>
  ## App List View

  * Toggle between **card view** and a new compact **list view** on the app listing page using the view switcher in the toolbar
  * List view displays your apps as rows with columns for **type**, **runners**, **requests/min**, **latency**, **errors**, **machine type**, and **last updated** — making it easy to scan and compare performance across many apps at once
  * Your view preference is saved automatically, so you'll see the same layout next time you visit
  * Especially useful for teams managing dozens of serverless apps who need to quickly spot which apps need attention
</Update>

<Update label="March 11, 2026" tags={["Serverless", "Model APIs"]}>
  ## Error Types in API Responses

  * Error responses now include a machine-readable **`error_type`** field identifying the specific failure category — such as `request_timeout`, `runner_disconnected`, `runner_scheduling_failure`, or `runner_server_error`
  * Use `error_type` to build smarter retry logic: runner and timeout errors (e.g. `runner_connection_timeout`, `startup_timeout`) are typically transient and worth retrying, while client errors like `bad_request` should not be
  * Track `error_type` values in your monitoring to spot trends — for example, frequent `runner_scheduling_failure` errors may indicate you need to increase `max_concurrency`

  See [Error Reference — Request Error Types](/model-apis/errors#request-error-types) for the full list of error types, status codes, and handling guidance.
</Update>

<Update label="March 11, 2026" tags={["Serverless", "Runners"]}>
  ## Termination Grace Period

  * New `termination_grace_period_seconds` parameter lets you control how long a runner has to finish in-flight requests and run `teardown()` before being forcefully killed
  * Defaults to **5 seconds**, configurable up to a maximum of **30 seconds**

  ```python theme={null}
  class MyApp(fal.App):
      termination_grace_period_seconds = 20
  ```

  See [Scale Your Application — Termination Grace Period](/serverless/deployment-operations/scale-your-application#termination-grace-period) for the full shutdown lifecycle and best practices.
</Update>

<Update label="February 25, 2026" tags={["Dashboard", "Serverless"]}>
  ## App Tagging

  * You can now create and assign **custom tags** to your serverless apps directly from the dashboard
  * Organize your app listing by tagging apps by team, project, model type, or any label that makes sense for your workflow
  * **Filter by tag** in the app list to quickly find the apps you need
  * Create, assign, and remove tags right from the app listing page — no CLI or API needed

  Tags are visual labels for organizing your dashboard — they don't affect app behavior, routing, or secrets. For isolated deployment stages (dev, staging, production), use [Environments](/serverless/deployment-operations/manage-environments) instead.
</Update>

<Update label="February 23, 2026" tags={["CLI", "Serverless"]}>
  ## Machine Type in Runner Output

  * `fal runners list` and `fal app runners <app>` now display the **machine type** for each runner (e.g. `GPU-A100`, `GPU-H100`)
  * JSON output (`--output json`) also includes the `machine_type` field for each runner
</Update>

<Update label="February 17, 2026" tags={["Serverless"]}>
  ## Runner `FAILURE_DELAY` Status

  * Runners that fail during `setup()` now show a `FAILURE_DELAY` status, making it easier to identify runners that are in a cooldown period before retrying initialization
  * You can filter runners by this state using `fal runners list --state failure_delay`
  * See [Understanding Runners](/serverless/deployment-operations/understand-runners#runner-states) for details
</Update>

<Update label="February 16, 2026" tags={["Dashboard", "Logs", "Serverless"]}>
  ## Interactive Log Histogram

  * The logs page now features an interactive histogram that visualizes log volume over time, broken down by severity level
  * **Click and drag** to select a time range on the histogram to zoom into that window and filter your logs instantly
  * **Zoom in and out** to explore log patterns at different time granularities
  * Color-coded bars show the distribution of stderr, error, warning, info, and trace logs at a glance

  ## Jump to Context

  * When viewing a specific log entry, use the new **Jump to Context** button to instantly scroll to surrounding log lines
  * Quickly see what happened before and after any log entry without manually searching through timestamps
  * Especially useful when navigating to a log from a shared link or alert

  ## Switch Log Timezones Between UTC and Local

  * You can now toggle between **UTC** and your **local timezone** directly from the datepicker in the logs page
  * All log timestamps, filters, and the histogram update instantly when switching timezones
</Update>

<Update label="February 12, 2026" tags={["Dashboard", "Platform", "Serverless"]}>
  ## Serverless App Cards with Error Rates and Graphs

  * The app listing page now displays rich cards for each serverless app with at-a-glance performance metrics
  * **Error rate indicators** show the health of each app directly on the card
  * **Inline sparkline graphs** visualize request volume and error trends over time
  * Quickly identify apps that need attention without clicking into each one individually
</Update>

<Update label="February 11, 2026" tags={["Dashboard", "Platform", "Serverless", "Logs"]}>
  ## Share Logs with Your Team

  * You can now click on any log entry and share the link directly with the rest of your team
  * Shared log links preserve the full context of the log, making it easy to collaborate on debugging and troubleshooting

  ## Runner Side Sheet

  * Click into any runner on the Runners page to open a detailed side sheet with telemetry, logs, and the ability to connect to the runner
  * Makes it much easier to debug and observe your runners without leaving the page
</Update>

<Update label="February 11, 2026" tags={["Serverless", "CLI"]}>
  ## `--auth` flag for `fal run`

  You can now specify the authentication mode when running your app with `fal run` using the `--auth` flag. Supported values are `public` and `private`, giving you control over who can access your app during development and testing.

  ```bash theme={null}
  fal run path/to/myapp.py::MyApp --auth private
  ```

  * `public` — no authentication required, app owner pays
  * `private` — only you or your team can access
</Update>

<Update label="February 4, 2026" tags={["Dashboard", "Logs"]}>
  ## Full-Screen Logs

  * The logs page now opens in a **full-screen view**, giving you significantly more vertical and horizontal space to work with
  * See more log lines at once and reduce scrolling when debugging complex issues
</Update>

<Update label="February 3, 2026" tags={["Serverless"]}>
  ## FalBaseModel for better input/output definitions

  Define your API inputs and outputs with `FalBaseModel` a Pydantic base class with built-in support for hidden fields, field ordering, and media type hints.

  * **Hidden fields** - Use `Hidden(Field(...))` to mark parameters as API-only, hiding them from the playground UI while keeping them accessible via API
  * **Field ordering** - Control the order of fields in your API schema with `FIELD_ORDERS`
  * **Media field helpers** - Use `ImageField`, `AudioField`, `VideoField`, and `FileField` for better playground rendering

  Example:

  ```python theme={null}
  from fal.toolkit import FalBaseModel, Field, Hidden, ImageField

  class TextToImageInput(FalBaseModel):
      FIELD_ORDERS = ["prompt", "negative_prompt", "image_size"]

      prompt: str = Field(description="Text description of the image")
      negative_prompt: str = Field(default="", description="What to avoid")
      image_size: str = Field(default="1024x1024")

      # Hidden from playground but accessible via API
      debug_mode: bool = Hidden(Field(default=False))
      internal_seed: int = Hidden(Field(default=-1))

  class ImageToImageInput(FalBaseModel):
      image_url: str = ImageField(description="Input image")
      strength: float = Field(default=0.8)
  ```

  See [Handle Inputs and Outputs](/serverless/development/handle-inputs-and-outputs#falbasemodel) for details.
</Update>

<Update label="February 2, 2026" tags={["Dashboard", "Serverless"]}>
  ## Switch environments from app pages

  You can now quickly switch between environments directly from any app page using the new environment dropdown in the dashboard.

  * **Environment dropdown** - Click the environment badge on any app page to see all environments where the app is deployed
  * **One-click switching** - Select an environment to navigate to the same app in that environment
  * **Quick access** - View environment secrets or create new environments directly from the dropdown
</Update>

<Update label="January 30, 2026" tags={["Serverless", "Runners", "Breaking Change"]}>
  ## Track when runners are idle and waiting for work

  <Warning>
    **Potential Breaking Change** - The runner state model has been updated. If
    you're monitoring or tracking runner states programmatically, you may need to
    update your integration to handle the new IDLE state.
  </Warning>

  Understand runner utilization with the new IDLE state that shows when runners are ready but not actively processing requests.

  * **IDLE state visibility** - see when runners finish processing and are waiting for new work
  * **Better resource monitoring** - distinguish between actively processing requests and waiting states
  * **Improved observability** - track idle time to optimize scaling and resource allocation

  See the new [Understanding Runners](/serverless/deployment-operations/understand-runners) guide and [Optimizing Cold Starts](/serverless/deployment-operations/optimize-cold-starts) guide for complete details on runner lifecycle, states, and performance optimization.
</Update>

<Update label="January 25, 2026" tags={["Model APIs"]}>
  ## Control queue wait time with `start_timeout`

  You can now set a `start_timeout` on requests which ensures that when queue time is too long, the request is aborted without starting.

  See [Client Libraries → Start Timeout](/model-apis/client#2-queue-management) for details.
</Update>

<Update label="January 21, 2026" tags={["Serverless"]}>
  ## Environments for isolated deployments

  Organize your applications, secrets, and configurations across different stages of your workflow with the new environments feature.

  * **Create isolated environments** for development, staging, and production
  * **Environment-scoped secrets** - use different API keys and credentials per environment
  * **Deploy to specific environments** using the `--env` flag

  ```bash theme={null}
  # Create a staging environment
  fal environments create staging

  # Deploy to staging
  fal deploy my_app.py --env staging

  # Set environment-specific secrets
  fal secrets set API_KEY=staging-key --env staging
  ```

  See [environments documentation](/serverless/deployment-operations/manage-environments) for details.
</Update>

<Update label="January 19, 2026" tags={["Serverless"]}>
  ## Handle graceful shutdown with `handle_exit()` and `teardown()`

  You can now define `handle_exit()` and `teardown()` methods in your app to handle graceful shutdown.

  * **`handle_exit()`** - Called when the runner is requested to terminate to signal handlers to stop early.
  * **`teardown()`** - Called when the runner is shutting down to clean up resources.

  See [lifespan docs](https://docs.fal.ai/serverless/getting-started/core-concepts#lifespan) for details.
</Update>

<Update label="January 13, 2026" tags={["Serverless"]}>
  ## Include local files in container builds with COPY and ADD

  <Warning>
    **Experimental Feature** - This feature is currently experimental.
  </Warning>

  You can now use standard Docker `COPY` and `ADD` commands to include local files in your container builds.

  * **Automatic file parsing** - fal parses your Dockerfile to find COPY/ADD commands and collects referenced files
  * **Hash-based deduplication** - Files are uploaded to fal's storage with content-addressable deduplication (files from `app_files` are reused automatically)
  * **.dockerignore support** - Create a `.dockerignore` file or use `add_dockerignore()` to exclude files
  * **Multi-stage build support** - `COPY --from=...` commands are correctly handled (only local files are collected)
  * **Smart rebuilds** - Changes to your `fal.App` file don't trigger rebuilds (it's pickled separately); only changes to COPY/ADD referenced files trigger rebuilds

  Example:

  ```python theme={null}
  dockerfile_str = """
  FROM python:3.11
  WORKDIR /app
  COPY requirements.txt .
  RUN pip install -r requirements.txt
  COPY src/ ./src/
  """

  class MyApp(fal.App):
      image = ContainerImage.from_dockerfile_str(dockerfile_str)
  ```

  See [custom container image docs](https://docs.fal.ai/serverless/development/use-custom-container-image#using-copy-and-add-commands).
</Update>

<Update label="January 9, 2026" tags={["Serverless"]}>
  ## Skip retries for specific conditions

  You can now skip retries for specific conditions using the `skip_retry_conditions` option.

  ```python theme={null}
  class MyApp(fal.App):
      skip_retry_conditions=["timeout"]  # This app won't retry on timeout
      ...
  ```

  Available conditions: `"server_error"`, `"timeout"`.

  See [retry policy docs](https://docs.fal.ai/serverless/getting-started/core-concepts#retry-policy) for details.
</Update>

<Update label="January 7, 2026" tags={["Serverless"]}>
  ## Graceful shutdown of fal apps

  Starting with `fal>=1.61.0`, runners now receive a `SIGTERM` signal when terminated and are given a **5-second grace period** to complete ongoing requests before being forcefully terminated with `SIGKILL`.

  This applies to all termination scenarios: expiration, manual stop/kill, and scaling down. Use the `teardown()` method to handle cleanup during this grace period.

  See [lifespan docs](https://docs.fal.ai/serverless/getting-started/core-concepts#lifespan) for details.
</Update>

<Update label="December 22, 2025" tags={["Serverless"]}>
  ## Add a health check endpoint to your application

  Add a health check endpoint to your application to automatically replace unhealthy runners.

  * **Health check endpoint** - Pass the `health_check` parameter to the `@fal.endpoint()` decorator to configure an endpoint as your health check
  * **Periodic checks and recovery** - fal periodically (every 15 seconds) calls this endpoint and replace unhealthy runners if it fails for a few consecutive calls

  Example:

  ```python theme={null}
  class MyApp(fal.App):
      @fal.endpoint("/health", health_check=fal.HealthCheck(failure_threshold=3))
      def health(self) -> HealthResponse:
          if not self.connection.is_alive():
              raise RuntimeError("Lost connection to the external service")
          return HealthResponse(status="ok")
  ```

  See [health check endpoint docs](https://docs.fal.ai/serverless/development/add-health-check-endpoint).
</Update>

<Update label="December 22, 2025" tags={["Serverless"]}>
  ## Disable environment build cache

  You can now disable the environment build cache
  by passing the `--no-cache` flag to the `fal deploy` or `fal run` command.

  See [custom container image docs](https://docs.fal.ai/serverless/development/use-custom-container-image#disable-build-cache).
</Update>

<Update label="November 25, 2025" tags={["Serverless"]}>
  ## Scale your application with the new scaling delay feature

  Scale your application with the new scaling delay feature.

  * **Scaling delay** - the amount of seconds the system will wait for a request to be picked up by a runner before triggering a scale up of a runner

  Example:

  ```python theme={null}
  class MyApp(fal.App):
      scaling_delay = 30
      # ...
  ```

  See [scaling docs](https://docs.fal.ai/serverless/deployment-operations/scale-your-application#scaling-delay).
</Update>

<Update label="November 17, 2025" tags={["Serverless"]}>
  ## Reduce cold start times with shared compiled PyTorch caches

  Dramatically reduce cold start times for torch.compile() models with the new inductor cache utilities.

  * **Load pre-compiled CUDA kernels** in \~2 seconds instead of recompiling for 20-30 seconds on each worker
  * **GPU-specific caching** automatically organized by GPU type (H100, H200, A100)
  * **Two usage patterns**: Manual control with `load_inductor_cache()` / `sync_inductor_cache()` or automatic with `synchronized_inductor_cache()` context manager
  * **Persistent shared storage** at `/data/inductor-caches/<GPU_TYPE>/<cache_key>.zip`
  * First worker compiles and shares, subsequent workers load instantly

  Example:

  ```python theme={null}
  from fal.toolkit import synchronized_inductor_cache

  with synchronized_inductor_cache("mymodel/v1"):
      self.model = torch.compile(self.model)
      self.warmup()  # Compilation happens once, synced automatically
  ```

  See [compilation cache docs](https://docs.fal.ai/serverless/optimizations/optimize-startup-with-compiled-caches).
</Update>

<Update label="November 14, 2025" tags={["Serverless", "Dashboard"]}>
  ## Get Slack notifications for serverless app failures

  Never miss critical issues with instant Slack alerts for your serverless applications.

  * **Connect your workspace** with one-click OAuth installation
  * **Choose notification channel** from a dropdown of your Slack channels
  * **Instant alerts for**:
    * App startup failures and timeouts
    * Critical platform issues
    * Real-time error notifications
  * **Team visibility** - everyone in the channel sees important updates
  * Configure at `https://fal.ai/dashboard/notifications/settings`
</Update>

<Update label="November 4, 2025" tags={["Serverless", "Dashboard", "Runners", "Logs"]}>
  ## Stop and kill runners directly from the dashboard

  No more switching to the CLI to manage your runners. You now have full lifecycle control right from the dashboard.

  * **Graceful shutdown** or **force kill** runners with a single click
  * Access at `https://fal.ai/dashboard/apps/{username}/{appname}/runners`

  ## Stream platform logs to your own endpoint with drains

  Integrate fal's logging with your existing observability stack using the new Serverless Drains feature.

  * **Automatic log forwarding** from apps, runners, and file operations in NDJSON format
  * Works with Datadog, Splunk, Elasticsearch, or any HTTP endpoint
  * Configure at `https://fal.ai/dashboard/drains`
</Update>

<Update label="November 2, 2025" tags={["CLI", "Files", "Serverless"]}>
  ## Upload larger files with improved timeout handling

  We've significantly improved the reliability of file uploads from URLs, especially for large datasets and model files.

  * **Extended timeout to 10 minutes** for `fal files upload` and `fal files upload-url`
  * Upload multi-GB files without timeout errors
  * See [`fal files` docs](https://docs.fal.ai/serverless/cli/files)
</Update>

<Update label="November 1, 2025" tags={["CLI", "Runners", "Serverless"]}>
  ## Restart all runners without redeploying

  Apply environment changes or recover from bad states instantly with the new `fal apps rollout` command.

  * **Restart all runners** for an app without creating a new deployment
  * **Graceful by default** (runners finish current requests) or use `--force` for immediate restart
  * Pick up new secrets, environment variables, or clear memory issues
  * See [`fal apps rollout` docs](https://docs.fal.ai/serverless/cli/apps/rollout)

  ## Stop specific runners without affecting others

  Target individual runners for maintenance with graceful shutdown via `fal runners stop`.

  * Stop specific runners without affecting others, useful for targeted maintenance
  * See [`fal runners` docs](https://docs.fal.ai/serverless/cli/runners)

  ## Debug production runners with interactive shell access

  Jump directly into any running container to troubleshoot issues in real-time with `fal runners shell`.

  * **SSH-like access** to inspect files, environment variables, and dependencies
  * Debug production issues without redeploying
  * See [`fal runners shell` docs](https://docs.fal.ai/serverless/cli/runners#shell)
</Update>

<Update label="October 31, 2025" tags={["Dashboard", "Serverless"]}>
  ## See everything happening in your app with the events timeline

  Complete activity history for runners, deployments, and config changes in one place.

  * **Unified timeline** of runner events, deployments, and config changes
  * Access at `https://fal.ai/dashboard/apps/{username}/{appname}/events`
</Update>

<Update label="October 25, 2025" tags={["Dashboard", "Serverless", "Onboarding"]}>
  ## Get from zero to deployed in minutes with in-app onboarding

  New interactive guide walks you through your first serverless deployment step-by-step.

  * **Step-by-step walkthrough** from installation to deployment with copy-paste examples
  * Access at `https://fal.ai/dashboard/serverless-get-started`
</Update>

<Update label="October 22, 2025" tags={["CLI", "Files"]}>
  ## Delete files from fal storage

  Remove files and directories with the new `fal files rm` command.

  * **Recursive deletion**: `fal files rm path/to/file-or-directory`
  * See [`fal files` docs](https://docs.fal.ai/serverless/cli/files)
</Update>

<Update label="October 21, 2025" tags={["Platform API", "Models API", "Analytics", "Serverless"]}>
  ## Platform APIs v1 officially released

  Programmatically manage your model deployments with the new Platform APIs.

  * **Model discovery** - search and metadata retrieval for 600+ models
  * **Pricing and cost estimation** - real-time pricing information
  * **Usage tracking** - detailed line items with quantities and prices
  * **Analytics** - request counts, error rates, and latency percentiles
  * Available at `https://api.fal.ai/v1` - see [docs](https://docs.fal.ai/platform-apis)

  ## Get notified when you hit concurrent requests limits

  Never wonder why requests are queuing—we now send notifications when you reach your concurrency limit.

  * **Email and dashboard notifications** with smart throttling (immediate, 1h, 1d, weekly)
  * **Limit value included** in 429 responses for programmatic handling

  ## Debug errors faster with the new errors page

  Comprehensive error analytics to identify and resolve issues quickly.

  * **Server vs client error rates** with 4xx/5xx breakdown and sparklines
  * **Error timeline** with status code distribution and endpoint-level breakdown
  * Access at `https://fal.ai/dashboard/apps/{username}/{appname}/errors`
</Update>

<Update label="October 20, 2025" tags={["CLI", "Runners", "Serverless"]}>
  ## Stop or kill individual runners from the command line

  Precise control over each runner's lifecycle without touching the dashboard.

  * **`fal runners stop`** - gracefully stop a runner, allowing in-flight requests to complete
  * **`fal runners kill`** - immediately terminate a runner without waiting
  * See [`fal runners` docs](https://docs.fal.ai/serverless/cli/runners)
</Update>

<Update label="October 16, 2025" tags={["Dashboard", "Serverless", "CLI"]}>
  ## See exactly how long runners spend starting up

  Identify GPU availability bottlenecks and optimize cold start times.

  * **Pending uptime metrics** show how long runners wait before becoming active
  * Track PENDING, DOCKER\_PULL, and SETUP state durations separately
</Update>

<Update label="October 15, 2025" tags={["Serverless", "MCP", "Models API"]}>
  ## Connect fal docs to Cursor with MCP

  Access the complete fal documentation directly in Cursor using Model Context Protocol.

  * **Complete documentation in your IDE** with AI-powered suggestions
  * Simple setup: add fal MCP server to your `mcp.json` - see [guide](https://docs.fal.ai/model-apis/mcp)

  ## Personalized dashboard with creator and developer views

  The dashboard now adapts to your workflow with two distinct experiences.

  * **Creator view** - gallery-focused with favorite models and visual generation history
  * **Developer view** - metrics-driven with usage stats, error tracking, and API analytics
  * **Quick stats** showing credits, requests, and errors with sparklines
</Update>

<Update label="October 13, 2025" tags={["Serverless", "Models API", "Multi-GPU"]}>
  ## Add custom headers to your API requests

  Integrate seamlessly with analytics, auth, and middleware by passing custom HTTP headers.

  * Add custom headers for analytics, authentication, or middleware integration
  * Works with all client libraries

  ## Multi-GPU inference and training with fal.distributed

  Scale AI workloads across multiple GPUs with the new `fal.distributed` module.

  * **Data parallelism** - generate multiple outputs simultaneously (e.g., 4 images on 4 GPUs)
  * **Model parallelism** - split large models across GPUs for faster generation
  * **Distributed training** - synchronized gradient updates with DDP
  * Supports 2, 4, or 8 GPU configurations on H100s and A100s
  * See [distributed docs](https://docs.fal.ai/serverless/distributed/overview)
</Update>

<Update label="October 10, 2025" tags={["Dashboard", "Serverless"]}>
  ## Dedicated pages for Analytics, Runners, Logs, and Versions

  Complete app details redesign gives each deployment aspect its own focused view.

  * **New Analytics page** - runner-focused metrics with date range filtering
  * **New Runners page** - app-scoped runner view with enhanced filters
  * **New Logs page** - dedicated log viewer for debugging
  * **New Versions page** - manage and view app revisions
  * **Enhanced Overview** - endpoint stats and performance metrics at a glance
</Update>

<Update label="October 9, 2025" tags={["Product"]}>
  ## Compare models side-by-side in the new Sandbox

  Find the perfect model by testing multiple options in parallel with the same prompt.

  * Run multiple models simultaneously with the same prompt
  * Available at `https://fal.ai/sandbox`
</Update>

<Update label="October 8, 2025" tags={["Serverless"]}>
  ## Manage deployments from Python without async/await

  New synchronous client makes serverless management feel just like the CLI.

  * Manage apps, runners, and deployments programmatically without async/await
  * Same API as CLI: `client.apps.*`, `client.runners.*`, `client.deploy()`
  * See [Python client docs](https://docs.fal.ai/serverless/python/client)
</Update>

<Update label="October 6, 2025" tags={["Serverless"]}>
  ## Bring your own container to any deployment

  Full control over your runtime environment with custom Docker images.

  * Use `ContainerImage.from_dockerfile_str()` or `ContainerImage.from_dockerfile()`
  * Install any dependencies, tools, or system packages you need
  * See [custom containers guide](https://docs.fal.ai/serverless/development/use-custom-container-image)
</Update>

<Update label="October 3, 2025" tags={["Serverless", "CLI", "Dashboard", "Files"]}>
  ## Dynamic auto-scaling with percentage-based buffers

  Scale more intelligently by setting concurrency buffers as percentages instead of fixed numbers.

  * Configure buffer as a percentage of current concurrency for dynamic scaling
  * See [scaling docs](https://docs.fal.ai/serverless/deployment-operations/scale-your-application)

  ## Runner logs with streaming and filtering

  Real-time log streaming and powerful filtering for faster debugging.

  * **Stream logs in real-time** with `fal runners logs --follow`
  * **Filter by time range** with `--since` and `--until`
  * **Search logs** with `--search` parameter
  * **Scrollable and searchable** in the dashboard with SSE-powered updates
  * See [`fal runners logs` docs](https://docs.fal.ai/serverless/cli/runners#logs)

  ## Include local files in your deployments automatically

  Bring configs, utilities, and code from your local machine into serverless apps.

  * Specify files with relative or absolute paths to include at runtime
  * Works with `fal run` and `fal deploy`
  * See [app files docs](https://docs.fal.ai/serverless/development/app-files)

  ## Find what you need faster with reorganized navigation

  Clearer dashboard structure groups features by workflow: Generate, Serverless, and Manage.

  * **Generate** group: Sandbox, Model Gallery
  * **Serverless** group: Apps, Logs, Files, Runners
  * **Manage** group: Usage, Billing, API Keys, Webhooks, Team Members
</Update>

<Update label="October 2, 2025" tags={["Dashboard", "Runners", "CLI"]}>
  ## Know exactly which version each runner is running

  Track deployments better with revision IDs shown on every runner.

  * **Revision ID displayed** on runners to track which version is running
  * **State renamed**: "DEAD" → "TERMINATED" for clarity
</Update>

<Update label="October 1, 2025" tags={["Logs", "Dashboard", "CLI", "Serverless"]}>
  ## Filter logs with custom labels and powerful queries

  Find what you need instantly with EXACT/CONTAINS matching and multi-condition filters.

  * **EXACT or CONTAINS** matching for label values
  * **Multiple conditions** with OR logic (e.g., `status IN ["error", "warning"]`)
  * Available in dashboard and API
  * Examples: `error_type = "ValidationError"`, `endpoint CONTAINS "/api/v2/"`

  ## See what runners are doing during startup

  Track exactly where runners are in the startup process—pending, pulling images, or setting up.

  * `fal runners list` now shows PENDING, DOCKER\_PULL, and SETUP states
  * Understand deployment progress in real-time

  ## View all app endpoints and config at a glance

  Redesigned app details page surfaces the information you need most.

  * Endpoints, configuration, and status all in one place
</Update>

<Update label="September 27, 2025" tags={["CLI", "Serverless"]}>
  ## Monitor and clear your request queue from the CLI

  Check how many requests are queued and flush them when needed.

  * `fal queue size app_name` - check queue size for an app
  * `fal queue flush app_name` - flush all pending requests
  * See [`fal queue` docs](https://docs.fal.ai/serverless/cli/queue)
</Update>

<Update label="September 10, 2025" tags={["CLI", "Runners", "Serverless"]}>
  ## View runner history with time-based filtering

  See terminated runners and filter by state to debug failures.

  * `fal runners list --since "1h"` - view runners from the last hour (max 24h)
  * `fal runners list --state dead` - filter by state (running, pending, setup, dead)
  * Helpful for debugging failed deployments and understanding runner lifecycle
  * See [`fal runners list` docs](https://docs.fal.ai/serverless/cli/runners#list)
</Update>

<Update label="August 29, 2025" tags={["CLI", "Files", "Serverless"]}>
  ## Reorganize files in fal storage without re-uploading

  Move and rename files instantly with the new `fal files mv` command.

  * Rename or move files in fal storage: `fal files mv source destination`
  * See [`fal files` docs](https://docs.fal.ai/serverless/cli/files)
</Update>

<Update label="August 26, 2025" tags={["CLI", "Serverless"]}>
  ## See all your endpoint URLs immediately when testing

  No more guessing which URL to use—CLI shows playground, sync, and async routes for every run.

  * CLI prints playground, synchronous, and asynchronous routes for `fal run`
</Update>


# https://fal.ai/docs/documentation/compute/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction to Compute

> Dedicated GPU instances for training, fine-tuning, and workloads that need sustained access to hardware.

fal Compute gives you dedicated GPU instances that run continuously under your control. Unlike [Serverless](/documentation/deployment/deploy-to-production), where runners scale automatically and you pay per-second of execution, Compute instances stay running for as long as you need them. You SSH in, install your stack, and use the GPU directly. This makes Compute the right choice for training runs, long-running fine-tuning jobs, batch processing, and any workload where you need sustained, predictable access to hardware rather than on-demand scaling.

Compute runs on NVIDIA H100 SXM GPUs with high-speed SSD storage. For distributed workloads, 8-GPU instances can be provisioned in the same sector, connecting them over InfiniBand for low-latency multi-node communication. Instances are billed per-hour at fixed rates, so your costs are predictable regardless of how you use the GPU. For workloads that are better served by autoscaling and pay-per-use, see [Serverless](/documentation/serverless/pricing) instead.

## Instance Types

Two instance types are available, both built on H100 SXM GPUs:

| Instance Type  | GPUs | vCPU | RAM      | VRAM   | Storage  |
| :------------- | :--- | :--- | :------- | :----- | :------- |
| **1xH100-SXM** | 1    | 16   | 200 GB   | 80 GB  | 1 TB SSD |
| **8xH100-SXM** | 8    | 128  | 1,600 GB | 640 GB | 8 TB SSD |

The **1xH100** is suited for development, single-GPU fine-tuning, and inference workloads. The **8xH100** is designed for large-scale training, multi-GPU inference, and distributed computing. Resources scale proportionally: the 8-GPU instance has 8x the CPU cores, memory, VRAM, and storage of the single-GPU instance.

## Multi-Node and InfiniBand

When you need to distribute a workload across multiple machines, provision 8xH100 instances in the same **sector**. Instances within a sector are connected over InfiniBand, providing ultra-low latency and high bandwidth for frameworks like PyTorch DDP, DeepSpeed, and Horovod.

<Note>
  InfiniBand and sector placement are only available on 8xH100 instances. 1xH100 instances run as standalone machines without inter-node connectivity.
</Note>

## When to Use Compute vs Serverless

The two products serve different workload profiles:

|                 | Compute                                     | Serverless                                      |
| :-------------- | :------------------------------------------ | :---------------------------------------------- |
| **Billing**     | Per-hour, fixed rate                        | Per-second of runner lifetime                   |
| **Scaling**     | Manual (you manage instances)               | Automatic (runners scale with traffic)          |
| **Access**      | Full SSH access to the machine              | Code runs inside managed runners                |
| **Best for**    | Training, fine-tuning, batch jobs, research | API endpoints, on-demand inference, autoscaling |
| **Cold starts** | None (instance is always running)           | Yes (new runners need startup time)             |

Use Compute when you need sustained GPU access for hours or days at a time. Use Serverless when you need an API that scales to zero and handles traffic spikes automatically.

## Getting Started

Provisioning an instance takes about 2-3 minutes. You choose an instance type, select a sector (for multi-node setups), paste your SSH public key, and click create. Once the instance is ready, you SSH in and have full control.

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/documentation/compute/quickstart">
    Provision your first instance and run a GPU workload
  </Card>

  <Card title="Pricing" icon="credit-card" href="/documentation/compute/pricing">
    Per-hour rates by instance type
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/compute/pricing.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pricing

> How billing works for fal Compute.

Dedicated GPU instances (Compute) are billed per-hour at fixed rates by instance type. Unlike [Serverless](/documentation/serverless/pricing), Compute instances run continuously regardless of utilization. Pricing is configured per instance type and visible in the [dashboard](https://fal.ai/dashboard/compute).

| Instance Type | Description                                    |
| :------------ | :--------------------------------------------- |
| 1xH100-SXM    | Single H100 GPU, 16 vCPU, 200GB RAM, 1TB SSD   |
| 8xH100-SXM    | Eight H100 GPUs, 128 vCPU, 1600GB RAM, 8TB SSD |

Contact the fal team or check the [dashboard](https://fal.ai/dashboard/compute) for current per-hour rates.

## Monitoring your usage

<CardGroup cols={2}>
  <Card title="Dashboard Billing" icon="chart-line" href="https://fal.ai/dashboard/billing">
    View your overall spend, invoices, and payment methods.
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/compute/quickstart.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart with Compute

> Get up and running with fal Compute in minutes. This guide will walk you through provisioning your first GPU instance and connecting to it.

<Warning>
  **Enterprise**

  To request access and learn more about fal Compute, please visit the [dashboard](https://fal.ai/dashboard) to get started.
</Warning>

## Prerequisites

Before you begin, make sure you have:

* A fal.ai account with Compute access
* An SSH key pair for secure instance access
* Basic familiarity with SSH and command line tools

### Generate SSH Key (if needed)

If you don’t have an SSH key pair, generate one:

```bash theme={null}
# Generate a new SSH key pair
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# Display your public key (you'll need this for instance creation)
cat ~/.ssh/id_rsa.pub
```

## Step 1: Create Your Instance

<Steps>
  <Step title="Access the Dashboard">
    * Navigate to the [fal Compute Dashboard](https://fal.ai/dashboard/compute)
    * Click the **“Create”** button
  </Step>

  <Step title="Configure Your Instance">
    * **Instance Type**: Choose between:
      * `1xH100-SXM`: Single GPU for development and smaller workloads
      * `8xH100-SXM`: Eight GPUs for large-scale training and inference
    * **Sector Selection**:
      * **Default**: For single-instance workloads
      * **Specific Sector**: For multi-node clusters with InfiniBand connectivity
    * **SSH Key**: Paste your public SSH key for secure access
  </Step>

  <Step title="Launch Instance">
    * Review your configuration
    * Click **“Create”** to provision your instance
    * Wait for the instance to reach “ready” state (typically 2-3 minutes)
  </Step>
</Steps>

## Step 2: Connect to Your Instance

Once your instance is running, you’ll receive connection details:

```bash theme={null}
# Connect via SSH (replace with your actual connection details)
ssh ubuntu@your-instance-ip

# Example connection
ssh ubuntu@203.0.113.10
```

## Step 3: Verify Your Setup

After connecting, check your GPU resources:

```bash theme={null}
# Check GPU availability
nvidia-smi

# Verify CUDA installation
nvcc --version

# Check storage
df -h

# View system resources
htop
```

Expected output for 1xH100-SXM:

```bash theme={null}
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.xx.xx    Driver Version: 525.xx.xx    CUDA Version: 12.x   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA H100-SXM...  Off  | 00000000:01:00.0 Off |                    0 |
| N/A   27C    P0    68W / 700W |      0MiB / 81920MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
```

## Step 4: Install Your Dependencies

Install your required software stack:

```bash theme={null}
# Update system packages
sudo apt update && sudo apt upgrade -y

# Install Python and pip (if not already installed)
sudo apt install python3 python3-pip -y

# Install common ML libraries
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

# Verify PyTorch can see your GPU
python3 -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}'); print(f'GPU count: {torch.cuda.device_count()}')"
```

## Step 5: Run Your First Workload

Test your setup with a simple GPU workload:

```py test_gpu.py icon="python"  theme={null}
import torch
import time

# Check if CUDA is available
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"GPU count: {torch.cuda.device_count()}")

if torch.cuda.is_available():
    # Create large tensors on GPU
    device = torch.device('cuda')

    # Simple matrix multiplication test
    print("Running GPU compute test...")
    start_time = time.time()

    a = torch.randn(10000, 10000, device=device)
    b = torch.randn(10000, 10000, device=device)
    c = torch.matmul(a, b)

    end_time = time.time()
    print(f"Matrix multiplication completed in {end_time - start_time:.2f} seconds")
    print(f"GPU memory used: {torch.cuda.memory_allocated(device) / 1024**3:.2f} GB")
```

Run the test:

```bash theme={null}
python3 test_gpu.py
```

## Step 6: Transfer Your Data

For training workloads, you’ll need to transfer your datasets:

```bash theme={null}
# Using scp to transfer files
scp -r /local/path/to/dataset user@your-instance-ip:/remote/path/

# Using rsync for large datasets
rsync -avz -P /local/path/to/dataset/ user@your-instance-ip:/remote/path/dataset/

# Or download directly on the instance
wget https://example.com/dataset.tar.gz
tar -xzf dataset.tar.gz
```

## Next Steps

Now that your instance is running, you can:

### For Machine Learning

* **Training**: Start your training scripts with dedicated GPU resources
* **Fine-tuning**: Adapt pre-trained models with your custom datasets
* **Inference**: Deploy models for batch or real-time inference

### For Multi-GPU Workloads (8xH100)

* **Distributed Training**: Use frameworks like DeepSpeed, Horovod, or PyTorch DDP
* **Model Parallelism**: Split large models across multiple GPUs
* **Data Parallelism**: Process multiple batches simultaneously

### For Multi-Node Clusters

* **InfiniBand Setup**: Configure high-speed inter-node communication
* **Cluster Management**: Use tools like SLURM or Kubernetes for job scheduling
* **Distributed Computing**: Scale workloads across multiple instances

## Managing Your Instance

```bash theme={null}
# Monitor GPU usage
watch -n 1 nvidia-smi

# Check disk usage
df -h

# Monitor system resources
htop

# Check network connectivity (for multi-node)
ibstatus  # InfiniBand status
```

## Troubleshooting

### Common Issues

**SSH Connection Failed**

* Verify your SSH key is correctly configured
* Check instance status in the dashboard
* Ensure your IP is not blocked by firewalls

**GPU Not Detected**

* Run `nvidia-smi` to check GPU status
* Verify CUDA installation with `nvcc --version`
* Restart the instance if GPU drivers aren’t loaded

**Out of Memory Errors**

* Monitor GPU memory with `nvidia-smi`
* Reduce batch sizes in your training scripts
* Use gradient checkpointing to save memory

### Getting Help

* Check the [fal.ai documentation](https://docs.fal.ai) for detailed guides
* Contact support through the dashboard for technical issues
* Join the community forums for user discussions


# https://fal.ai/docs/documentation/deployment/caching.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Caching

> How fal's multi-layer caching system reduces cold start times by caching Docker images, model weights, and compiled artifacts.

Every time a new [runner](/documentation/deployment/runners) starts, it needs Docker image layers, model weights, and potentially compiled model caches before it can serve requests. Without caching, each runner would download everything from scratch, leading to cold starts that can take minutes for large models. fal's caching system stores these artifacts at multiple levels so that subsequent runners start faster, and cold start times improve progressively as your app serves traffic.

Docker layers and files on [`/data`](/documentation/development/use-persistent-storage) are cached automatically -- you don't need to configure anything. Compiled model caches (PyTorch Inductor) require explicit use of the [`synchronized_inductor_cache()`](/documentation/serverless/optimizations/optimize-startup-with-compiled-caches) API. Understanding the cache layers helps you reason about why cold starts improve over time and how to structure your app for the best startup performance. For strategies to reduce cold starts further, see [Optimizing Cold Starts](/documentation/serverless/optimizations/optimize-cold-starts).

## Cache Layers

Docker images and `/data` storage use different caching mechanisms.

### `/data` Storage Cache

Files on [`/data`](/documentation/development/use-persistent-storage) (model weights, compiled caches, any files your app writes) go through a three-layer cache:

| Cache Layer           | Speed      | Scope                  | Use Case                            |
| :-------------------- | :--------- | :--------------------- | :---------------------------------- |
| **Local Node Cache**  | 10-15 GB/s | Same physical machine  | RAID 5 NVMe drives on the node      |
| **Distributed Cache** | 6-8 GB/s   | Same datacenter/region | 100 Gbps network across all servers |
| **Object Store**      | 1.5-8 GB/s | Global                 | Backing store for all files         |

When a runner reads a file from `/data`, it checks the local node cache first. If the file isn't found locally, it checks the distributed datacenter cache. If that also misses, it fetches from the object store and populates both caches on the way back. This means the first runner in a region pays the full download cost, but every runner after it benefits from progressively faster access.

### Docker Image Cache

Docker images are cached separately using the node's Docker daemon. The scheduler [prefers nodes](/documentation/deployment/scale-your-application) that already have your image cached. If no cached node is available, the image is pulled from the container registry. Build-time layer caching is handled through BuildKit's registry cache, so rebuilds after small Dockerfile changes only rebuild the affected layers.

## What Gets Cached

**Docker Image Layers** -- container images are split into layers, and each layer is cached independently. If you change a single dependency in your Dockerfile, only the affected layers are re-pulled. The base image and unchanged layers come from cache. See [Optimize Container Images](/documentation/serverless/optimizations/optimize-container-images) for tips on structuring your Dockerfile for better layer caching.

**Model Weights** -- files downloaded to `/data` are automatically cached across runners through the three-layer `/data` cache described above. This includes Hugging Face models (cached at `/data/.cache/huggingface` via the `HF_HOME` [environment variable](/documentation/development/environment-variables)), weights downloaded with [`download_model_weights()`](/documentation/development/working-with-files#downloading-model-weights), and any other files you write to `/data`. The first runner downloads the weights; subsequent runners read from the local or distributed cache.

**Compiled Model Caches** -- PyTorch Inductor compiled models and other JIT compilation artifacts. If you use [`torch.compile()`](https://pytorch.org/docs/stable/generated/torch.compile.html), you can persist and share the resulting compiled kernels across runners using [`synchronized_inductor_cache()`](/documentation/serverless/optimizations/optimize-startup-with-compiled-caches). This stores the cache on `/data` (at `/data/inductor-caches/<GPU_TYPE>/`), where it benefits from the same three-layer cache. See [Compiled Kernel Caching](/documentation/serverless/optimizations/optimize-startup-with-compiled-caches) for setup instructions.

## How Caches Warm Up

Caches warm progressively as your application serves traffic:

1. **First runner** -- pulls the Docker image from the registry and downloads model weights from the object store. Populates the local and distributed `/data` caches. This is the slowest cold start.
2. **Second runner on the same node** -- Docker image is already in the node's Docker cache, and model weights are in the local NVMe cache. Cold start is significantly faster.
3. **Runners on other nodes** -- model weights are served from the distributed `/data` cache. The scheduler prefers nodes where the Docker image is already cached, but may pull from the registry if needed.
4. **Over time** -- as more nodes serve your app, caches spread across the region. Cold starts converge to the time it takes to run `setup()` with all files already available locally.

<Note>
  Caches are not permanent. Local caches may be evicted when nodes are recycled or under memory pressure. If your app hasn't had traffic for a while, the first cold start after a quiet period may be slower as caches are repopulated.
</Note>


# https://fal.ai/docs/documentation/deployment/deploy-to-production.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy to Production

> Deploy your fal App to production with persistent URLs, authentication, and automatic scaling.

Deploying to production is the step that turns your local app into a permanent, scalable API endpoint. While [`fal run`](/reference/cli/run) gives you a temporary URL for testing, `fal deploy` creates a persistent deployment that stays available until you explicitly remove it. Your app gets a stable endpoint ID (e.g., `your-username/my-model`) that callers use with the [fal client SDKs](/documentation/model-apis/inference) or REST API, automatic [runner scaling](/documentation/deployment/scale-your-application), and built-in [reliability](/documentation/serverless/reliability/retries) through the queue system.

Before deploying, make sure you have [installed the CLI](/documentation/development/getting-started/installation), written your [fal.App](/documentation/development/app-lifecycle), and tested it locally with `fal run`. This page walks through the deployment process from the initial command through build, configuration, and what happens behind the scenes. For managing deployments after they are live, see [Manage Deployments](/documentation/deployment/manage-deployments).

## Development vs Production

During development, use `fal run` to get a temporary endpoint for testing. It creates an ephemeral deployment that is destroyed when you stop the process. By default, `fal run` uses `public` auth mode so you can test without an API key.

```bash theme={null}
fal run path/to/myapp.py::MyApp
```

When you are ready for production, switch to `fal deploy`. This creates a persistent deployment with a permanent URL. By default, `fal deploy` uses `private` auth mode, requiring an API key to call your app.

```bash theme={null}
fal deploy path/to/myapp.py::MyApp
```

## Deploying Your App

The simplest deployment requires just the path to your app file and class:

```bash theme={null}
fal deploy path/to/myapp.py::MyApp
```

fal builds your app into a container image remotely, pushes it to the registry, and makes it available at the endpoint ID `your-username/app-name`. Callers use this ID with `fal_client.subscribe("your-username/app-name", ...)` or via the REST API at `https://queue.fal.run/your-username/app-name`. You do not need Docker installed locally. The build happens entirely in the cloud.

### App Name

By default, your app name is derived from the class name (e.g., `TextToImage` becomes `text-to-image`). You can override it in your code or via the CLI. The app name is the second part of your endpoint ID (`your-username/app-name`).

```python theme={null}
class MyApp(fal.App):
    app_name = "my-custom-name"
```

```bash theme={null}
fal deploy my_app.py::MyApp --app-name my-custom-name
```

### Machine Type

Set the hardware your app runs on using the `machine_type` class attribute. For GPU workloads, you can also specify `num_gpus` for multi-GPU configurations. See [Machine Types](/documentation/deployment/machine-types) for the full list of available hardware and guidance on choosing the right option.

```python theme={null}
class MyApp(fal.App):
    machine_type = "GPU-A100"
    num_gpus = 1
```

You can also specify multiple machine types to expand your available hardware pool, which reduces queue wait times:

```python theme={null}
class MyApp(fal.App):
    machine_type = ["GPU-A100", "GPU-H100"]
```

### Regions

By default, your app can run in any available region. If you need data residency compliance or want to minimize latency for a specific geography, restrict it:

```python theme={null}
class MyApp(fal.App):
    machine_type = "GPU-A100"
    regions = ["us-east"]
```

### Environments

You can deploy to different [environments](/documentation/deployment/manage-environments) (e.g., staging, production) to isolate configurations and [secrets](/documentation/development/manage-secrets-securely):

```bash theme={null}
fal deploy my_app.py::MyApp --env staging
```

## Previewing a Deployment

Use the `--check` command line option or set `FAL_DEPLOY_CHECK` to `true` to review what will change before your app is actually deployed:

```bash theme={null}
fal deploy path/to/myapp.py::MyApp --check
FAL_DEPLOY_CHECK=true fal deploy path/to/myapp.py::MyApp
```

The deployment check shows the target app and environment, current revision, source object, authentication mode, deployment strategy, build-cache behavior, and effective production configuration changes. If the app has not been deployed before, it shows the effective deployment values that will be used for the first revision.

When using the deployment check feature, you will by default be prompted for confirmation before deploying. In non-interactive environments, pass `--yes` to skip the prompt while still printing the summary:

```bash theme={null}
fal deploy path/to/myapp.py::MyApp --check --yes
FAL_DEPLOY_CHECK=true fal deploy path/to/myapp.py::MyApp --yes
```

<Note>
  Scaling parameters such as `keep_alive`, `min_concurrency`, and `max_concurrency` are inherited from the previous deployment unless you pass `--reset-scale`. The deployment check calls out code values that will not apply without `--reset-scale`.
</Note>

## Authentication Modes

Authentication controls who can call your app and who pays for compute. You set it with the `--auth` flag or the `app_auth` class attribute.

**Private** is the default for `fal deploy`. Only the account owner and their [team members](/documentation/organizations/managing-teams) can call the app, and they must include an API key. All compute is billed to the owner.

**Public** is the default for `fal run`. Anyone with the URL can call the app without authentication. All compute is billed to the owner. Use this for open demos or internal tools where you control access at another layer.

**Shared** allows anyone with the URL to call the app, but callers must authenticate with their own API key. Each caller pays for their own usage. This is how all apps in the [Model Gallery](https://fal.ai/models) work. Shared mode requires admin enablement on your account. See [Publishing to the Marketplace](/documentation/serverless/publishing-to-marketplace) for the full process of making your app available as a marketplace model.

```python theme={null}
class MyApp(fal.App):
    app_auth = "private"
```

## Rollout Strategies

When you redeploy an app that is already running, fal needs to transition from the old revision to the new one. You can choose between two strategies:

**Rolling** (default) spins up a runner on the new revision *before* switching traffic. fal waits for this runner to complete `setup()` and become healthy. Only after the new runner is confirmed ready does fal switch the alias. This ensures zero downtime but takes longer to complete. If the new runner fails to start (e.g., `setup()` crashes), the deployment is aborted and traffic stays on the old revision.

**Recreate** instantly switches the app alias to the new revision. No runners are started proactively. The first request after redeployment triggers a cold start on the new revision. If your app has `min_concurrency > 0`, the scaling system will eventually bring runners up to meet that minimum, but this happens through normal scaling, not as part of the deploy itself.

```bash theme={null}
fal deploy path/to/myapp.py::MyApp --strategy recreate
```

<Note>
  With rolling deployments, you will see a runner spin up during `fal deploy` even if there is no traffic. This is the health verification step. The deploy command stays open until the runner is confirmed healthy or fails.
</Note>

For more on managing revisions and rolling back to previous versions, see [Rollbacks](/documentation/deployment/rollbacks).

## How Builds Work

When you run `fal deploy`, your code is built into a container image remotely. You do not need Docker installed locally.

<Steps>
  <Step title="Upload">
    Your app code is sent to fal's build service. For non-container apps, files listed in `app_files` are included. For [container apps](/documentation/development/use-custom-container-image), files referenced by `COPY`/`ADD` in your Dockerfile are included automatically.
  </Step>

  <Step title="Build">
    fal builds your container image in the cloud using [Depot](https://depot.dev), a remote Docker build service.
  </Step>

  <Step title="Cache check">
    A hash is computed from your Dockerfile, dependencies, build args, and container files. If an identical image already exists, the build is skipped entirely.
  </Step>

  <Step title="Push">
    The built image is stored in fal's container registry.
  </Step>

  <Step title="Ready">
    [Runners](/documentation/deployment/runners) pull the image when they start up. Image size directly affects pull time and cold start duration.
  </Step>
</Steps>

<Note>
  Since builds happen remotely, your local machine does not need Docker, GPU drivers, or large amounts of disk space. You only need the `fal` CLI and your code.
</Note>

### Build Caching

fal uses multiple levels of caching to speed up builds. Build hash deduplication checks whether anything changed since the last build -- if not, the previous image is reused with no build at all. Docker layer caching stores layers per-user in the registry, so unchanged layers from previous builds are reused and only modified layers are rebuilt.

To force a full rebuild bypassing all caching:

```bash theme={null}
fal deploy my_app.py --no-cache
```

For tips on structuring your Dockerfile for faster builds, see [Optimize Container Images](/documentation/serverless/optimizations/optimize-container-images).

## What's Next

<CardGroup cols={2}>
  <Card title="Manage Deployments" icon="list" href="/documentation/deployment/manage-deployments">
    List, update, and delete your deployed apps
  </Card>

  <Card title="Rollbacks" icon="rotate-left" href="/documentation/deployment/rollbacks">
    Roll back to previous revisions or roll out new ones gracefully
  </Card>

  <Card title="Scale Your Application" icon="arrows-up-down" href="/documentation/deployment/scale-your-application">
    Configure scaling parameters for production traffic
  </Card>

  <Card title="Optimizing Cold Starts" icon="bolt" href="/documentation/serverless/optimizations/optimize-cold-starts">
    Reduce image size and startup time
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/deployment/machine-types.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Machine Types

> Available machine types, specifications, and guidance on choosing the right GPU for your workload.

## CPU Machine Types

For lightweight workloads that don't require GPU acceleration -- routing, preprocessing, API proxies.

| Machine Type | RAM    | CPU Cores |
| :----------- | :----- | :-------- |
| **XS**       | 512 MB | 0.5       |
| **S**        | 1 GB   | 1         |
| **M**        | 2 GB   | 2         |
| **L**        | 15 GB  | 4         |
| **XL**       | 30 GB  | 8         |

## GPU Machine Types

| Machine Type                                                                               | VRAM   | RAM    | CPU | Bandwidth | Video Enc / Dec |
| :----------------------------------------------------------------------------------------- | :----- | :----- | :-- | :-------- | :-------------- |
| [**GPU-RTX4090**](https://www.nvidia.com/en-us/geforce/graphics-cards/40-series/rtx-4090/) | 24 GB  | 48 GB  | 12  | 1.0 TB/s  | 2 / 2           |
| [**GPU-RTX5090**](https://www.nvidia.com/en-us/geforce/graphics-cards/50-series/rtx-5090/) | 32 GB  | 60 GB  | 14  | 1.8 TB/s  | 3 / 3 (AV1)     |
| [**GPU-A100**](https://www.nvidia.com/en-us/data-center/a100/)                             | 40 GB  | 60 GB  | 12  | 2.0 TB/s  | -- / 5          |
| [**GPU-L40**](https://www.nvidia.com/en-us/data-center/l40s/)                              | 48 GB  | 100 GB | 6   | 0.9 TB/s  | 3 / 3 (AV1)     |
| [**GPU-H100**](https://www.nvidia.com/en-us/data-center/h100/)                             | 80 GB  | 112 GB | 12  | 3.4 TB/s  | -- / 7          |
| [**GPU-H200**](https://www.nvidia.com/en-us/data-center/h200/)                             | 141 GB | 112 GB | 12  | 4.8 TB/s  | -- / 7          |
| [**GPU-B200**](https://www.nvidia.com/en-us/data-center/b200/)                             | 192 GB | 210 GB | 19  | 8.0 TB/s  | -- / 7          |

Video encode/decode counts refer to hardware [NVENC/NVDEC](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new) engines -- dedicated hardware units that encode or decode video independently of the GPU's compute cores. GPUs with encoders (RTX 5090, L40) can output video frames without using GPU compute time. GPUs marked `--` for encode have no hardware encoder and require software encoding on the CPU.

### Choosing a GPU

**By VRAM requirement** -- pick the smallest GPU that fits your model:

* **24 GB** (RTX 4090): SDXL, Flux, most LoRA fine-tunes
* **32 GB** (RTX 5090): Larger diffusion models, video generation with [AV1 hardware encode](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new)
* **40 GB** (A100): General-purpose training and inference at a lower price point than Hopper GPUs
* **48 GB** (L40): AI inference combined with [video transcoding](https://www.cisco.com/c/dam/en/us/products/collateral/servers-unified-computing/ucs-c-series-rack-servers/nvidia-l40s-ucsc-gpu-l40s.pdf) and graphics rendering
* **80 GB** (H100): LLM inference and training, [NVLink 4.0 at 900 GB/s](https://resources.nvidia.com/en-us-data-center-overview/nvidia-tensor-core-gpu-datasheet) for multi-GPU scaling
* **141 GB** (H200): Large models and long-context workloads on a single GPU -- [76% more memory and 43% more bandwidth than H100](https://resources.nvidia.com/en-us-dgx-systems/dgx-h200-datasheet)
* **192 GB** (B200): Maximum memory and compute for the largest models, [FP4/FP6/FP8 precision support](https://www.techpowerup.com/gpu-specs/b200.c4210)

**By workload type:**

* **Image generation**: RTX 4090 or RTX 5090 (cost-effective, good throughput)
* **Video generation**: RTX 5090 (3 NVENC encoders, AV1 encode) or L40 (3 NVENC + 3 NVDEC)
* **LLM inference**: H100 or H200 (high bandwidth, large VRAM)
* **Training**: A100, H100, or H200 (depending on model size)
* **Largest models**: B200 or multi-GPU H100/H200

## Configuration

Set the machine type in your application:

```python theme={null}
class MyApp(fal.App):
    machine_type = "GPU-H100"
    num_gpus = 1
```

### Multiple Machine Types

Allow your app to use multiple machine types for a larger pool of available machines:

```python theme={null}
class MyApp(fal.App):
    machine_type = ["GPU-H100", "GPU-A100"]
```

Machine types are tried in order. If the first type has no available capacity, the next is used.

### Multi-GPU

For models that need more than one GPU:

```python theme={null}
class MyApp(fal.App):
    machine_type = "GPU-H100"
    num_gpus = 2
```

<Card title="Multi-GPU Workloads" icon="arrow-right" href="/documentation/serverless/distributed/overview">
  Learn how to distribute inference across multiple GPUs
</Card>

## Changing Machine Types

**Via Code:**

Update `machine_type` and redeploy:

```python theme={null}
class MyApp(fal.App):
    machine_type = "GPU-A100"
```

```bash theme={null}
fal deploy
```

<Note>
  `machine_type` is a code-specific parameter -- it always comes from your code and resets on every deploy. See [Scaling Configuration](/documentation/deployment/scaling-configuration) for details.
</Note>


# https://fal.ai/docs/documentation/deployment/manage-deployments.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Deployments

> Once your models are deployed to production, you need tools and strategies to manage them effectively. This guide covers listing deployments, monitoring application health, managing multiple versions, and safely removing models.

## Listing Deployments

View all your deployed models to understand your current production environment:

```bash theme={null}
fal apps list
```

This shows all your deployed models with their current status, versions, and basic configuration. Use this to get an overview of your model portfolio and identify which models need attention.

## Organizing Apps with Tags

You can assign custom tags to your apps from the [fal dashboard](https://fal.ai/dashboard) to keep your app list organized. Tags are visual labels — use them to group apps by team, project, model type, or any category that fits your workflow, then filter the app listing to quickly find what you need.

<Info>
  Tags are managed entirely through the dashboard UI — they don't isolate secrets, affect routing, or change app behavior. If you need isolated deployment stages (dev, staging, production) with separate secrets and endpoints, use [Environments](/serverless/deployment-operations/manage-environments) instead.
</Info>

## Managing Versions

### Viewing Model Revisions

Each deployment creates a new revision. List all revisions for a specific model:

```bash theme={null}
fal apps list-rev myapp
```

### Switching Between Revisions

If you need to roll back to a previous model version or switch to a different revision:

```bash theme={null}
fal apps set-rev myapp uuid_of_revision
```

This is useful for quick rollbacks when a new model version has issues in production.

## Scaling Deployments

After deployment, you can adjust scaling parameters without redeploying:

```bash theme={null}
fal apps scale myapp --min-concurrency 2 --max-concurrency 20
```

For comprehensive scaling configuration and strategies, see [Scale Your Application](/serverless/deployment-operations/scale-your-application/).

## Monitoring Health

### Basic Health Checks

Monitor your model's health and performance using the fal dashboard, or check active runners:

```bash theme={null}
fal apps runners myapp
```

<Info>
  For detailed performance monitoring, metrics collection, and alerting strategies, see [Monitor Performance](/serverless/deployment-operations/monitor-performance/).
</Info>

## Removing Deployments

### Safe Deletion Process

Before deleting a model deployment:

<Steps>
  <Step title="Verify dependencies:">
    Ensure no other services or applications depend on this model
  </Step>

  <Step title="Check traffic:">
    Review recent usage to understand impact
  </Step>

  <Step title="Backup if needed:">
    Document model configuration or export important data
  </Step>
</Steps>

### Delete a Deployment

```bash theme={null}
fal apps delete myapp
```

**Warning**: This permanently removes the model deployment. The model cannot be recovered after deletion.

### Delete Specific Revisions

To clean up old revisions while keeping the current deployment:

```bash theme={null}
fal apps delete-rev myapp --revision-id abc123
```


# https://fal.ai/docs/documentation/deployment/manage-environments.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Environments

> Organize your fal Serverless applications, secrets, and configurations across different stages of your development workflow using environments. Create isolated spaces for development, staging, and production deployments.

Environments let you isolate applications, secrets, and configurations for different stages of your workflow. By default, all resources are deployed to the `main` environment. You can create additional environments like `staging` or `dev` to test changes separately from production.

<Note>
  **Each app is attached to a single environment.** To deploy the same application code to multiple environments (e.g., dev, staging, and main), you must create a separate app deployment for each environment. Apps cannot be promoted or moved between environments—instead, deploy your code to each target environment independently.
</Note>

## Why Use Environments?

* **Isolation**: Keep development, staging, and production completely separate
* **Safe testing**: Test new configurations and secrets without affecting production
* **Team workflows**: Different team members can work in isolated environments
* **Staged deployments**: Deploy and test in staging before deploying to production

## Creating Environments

Create a new environment using the CLI:

```bash theme={null}
fal environments create staging --description "Staging environment"
```

## Listing Environments

View all your environments:

```bash theme={null}
fal environments list
```

| Name    | Description         | Default | Created At                 |
| ------- | ------------------- | ------- | -------------------------- |
| main    |                     | Yes     | 2024-01-01 00:00:00.000000 |
| staging | Staging environment |         | 2024-01-15 10:30:00.000000 |
| dev     | Development         |         | 2024-01-15 11:00:00.000000 |

## Using Environments

### Deploying to an Environment

Use the `--env` flag with `fal deploy` to create an app in a specific environment:

```bash theme={null}
# Deploy to staging (creates app in staging environment)
fal deploy path/to/myapp.py::MyApp --env staging

# Deploy to production (creates app in main environment)
fal deploy path/to/myapp.py::MyApp
```

Each deployment creates a separate app instance in the target environment. To have your application running in multiple environments, deploy it to each environment independently.

### Managing Secrets per Environment

Secrets are scoped to environments. Set different API keys or configurations for each environment:

```bash theme={null}
# Set a secret in the staging environment
fal secrets set API_KEY=staging-key-123 --env staging

# Set a different secret in production
fal secrets set API_KEY=production-key-456

# List secrets for a specific environment
fal secrets list --env staging
```

### Managing Apps per Environment

All app operations support the `--env` flag:

```bash theme={null}
# List apps in staging
fal apps list --env staging

# Scale an app in staging
fal apps scale my-app --min-concurrency 1 --env staging

# View runners for an app in staging
fal apps runners my-app --env staging

# Delete an app from staging
fal apps delete my-app --env staging
```

### Running Functions in an Environment

Use `fal run` with the `--env` flag to test functions with environment-specific secrets:

```bash theme={null}
fal run path/to/myapp.py::MyApp --env staging
```

## Deleting Environments

<Warning>
  **Deleting an environment is destructive and cannot be undone.**

  When you delete an environment, the following resources are **permanently deleted**:

  * All applications deployed to that environment
  * All secrets stored in that environment
  * All revision history for apps in that environment
</Warning>

```bash theme={null}
fal environments delete staging
```

You'll be prompted to confirm by typing the environment name. Use `--yes` to skip the confirmation:

```bash theme={null}
fal environments delete staging --yes
```

<Note>
  The `main` environment cannot be deleted.
</Note>

## Environment Workflow Example

Here's a typical workflow using environments. Note that deploying to different environments creates separate app instances—each with its own configuration, secrets, and endpoint:

```bash theme={null}
# 1. Create a staging environment
fal environments create staging

# 2. Set up staging secrets
fal secrets set DATABASE_URL=postgres://staging-db.example.com/app --env staging

# 3. Deploy to staging for testing (creates a separate app in the staging environment)
fal deploy path/to/myapp.py::MyApp --app-name my-app --env staging

# 4. Test the staging deployment (note the --staging suffix in the URL)
curl https://fal.run/your-user/my-app--staging

# 5. Once verified, deploy the same code to production (creates a separate app in main)
fal deploy path/to/myapp.py::MyApp --app-name my-app

# 6. Test the production deployment
curl https://fal.run/your-user/my-app

# 7. Clean up staging app when no longer needed
fal apps delete my-app --env staging
```

<Tip>
  When you deploy an app to a non-main environment, its endpoint URL includes an environment suffix (e.g., `my-app--staging`). Apps in the `main` environment have no suffix (e.g., `my-app`).
</Tip>

## Best Practices

* **Use descriptive names**: Name environments clearly (`staging`, `dev`, `qa`) so their purpose is obvious
* **Mirror production**: Keep staging as close to production configuration as possible
* **Separate secrets**: Never share secrets between environments; use environment-specific values
* **Clean up unused environments**: Delete environments that are no longer needed to avoid confusion
* **Document environment usage**: Make sure your team knows which environment to use for what purpose

## Reference

<CardGroup cols={2}>
  <Card title="CLI Reference" icon="terminal" href="/reference/cli/environments">
    Complete CLI documentation for `fal environments`
  </Card>

  <Card title="Secrets Guide" icon="key" href="/documentation/development/manage-secrets-securely">
    Managing secrets across environments
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/deployment/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deployment Overview

> Ship your fal applications to production, manage revisions and environments, configure scaling, and choose the right machine type.

Deployment is where your [fal App](/documentation/development/app-lifecycle) goes from local development to a production API that serves real traffic. When you run `fal deploy`, fal builds your code into a container image, pushes it to a registry, and makes it available at a permanent endpoint ID. From that point, [runners](/documentation/deployment/runners) spin up on demand to handle requests, scale automatically based on traffic, and shut down when idle. You can roll back to any previous version instantly, deploy to separate [environments](/documentation/deployment/manage-environments) for staging and production, and tune [scaling parameters](/documentation/deployment/scale-your-application) without redeploying.

Before diving into this section, make sure you have [installed the CLI](/documentation/development/getting-started/installation) and built your app following the [Development](/documentation/serverless/index) guides. The pages here cover everything after your code is written: understanding what runners are, deploying to production, managing versions and environments, choosing hardware, and configuring scaling. If you are migrating from another platform, the [migration guides](/documentation/development/migrate-external-docker-server) can help you get started faster.

## Quick Start

The simplest deployment is a single command:

```bash theme={null}
fal deploy path/to/myapp.py::MyApp
```

This builds your app remotely, creates a persistent deployment, and gives you an endpoint ID like `your-username/my-model` that callers use with the [fal client SDKs](/documentation/model-apis/inference).

## Runners and Requests

Before deploying, it helps to understand the execution model. When a caller submits a request, it enters a persistent queue and is dispatched to a runner. Runners are compute instances that pull your container image, run `setup()`, and serve requests until they scale down. Understanding how requests flow through the queue and how runners start, process, and shut down is essential for debugging latency, configuring scaling, and managing costs.

<CardGroup cols={2}>
  <Card title="Understanding Requests" icon="arrow-right-arrow-left" href="/documentation/deployment/requests">
    Request lifecycle, retry interaction, and platform architecture diagram
  </Card>

  <Card title="Understanding Runners" icon="server" href="/documentation/deployment/runners">
    Runner lifecycle states, startup, shutdown, and scaling behavior
  </Card>

  <Card title="Caching" icon="layer-group" href="/documentation/deployment/caching">
    How Docker layers, model weights, and compiled artifacts are cached across runners
  </Card>
</CardGroup>

## Deploying and Managing

Deployment creates a versioned revision of your app. Each deploy creates a new revision, so you can roll back to any previous version instantly if something goes wrong. You choose a rollout strategy (recreate for speed, rolling for zero downtime), configure authentication (private, public, or shared billing), and optionally deploy to separate environments for staging and production.

<CardGroup cols={2}>
  <Card title="Deploy to Production" icon="rocket" href="/documentation/deployment/deploy-to-production">
    Build, configure, and ship your app with rollout strategies and auth modes
  </Card>

  <Card title="Manage Deployments" icon="list-check" href="/documentation/deployment/manage-deployments">
    List, update, and delete deployed apps
  </Card>

  <Card title="Rollbacks" icon="rotate-left" href="/documentation/deployment/rollbacks">
    Switch between revisions or restart runners with rollouts
  </Card>

  <Card title="Environments" icon="sliders" href="/documentation/deployment/manage-environments">
    Isolate staging and production with separate secrets and config
  </Card>
</CardGroup>

## Scaling and Hardware

Once deployed, you control how your app scales. Scaling parameters determine how many runners stay warm, how quickly new ones spin up, and how many requests each runner handles concurrently. Machine types determine the hardware backing each runner, from lightweight CPU instances to H200 and B200 GPUs.

<CardGroup cols={2}>
  <Card title="Scaling Parameters" icon="arrows-up-down" href="/documentation/deployment/scale-your-application">
    Configure concurrency, keep-alive, multiplexing, and scaling delays
  </Card>

  <Card title="Scaling Configuration" icon="gear" href="/documentation/deployment/scaling-configuration">
    Set parameters via code, CLI, or dashboard, and understand --reset-scale
  </Card>

  <Card title="Machine Types" icon="microchip" href="/documentation/deployment/machine-types">
    Choose from CPU and GPU hardware based on memory, compute, and VRAM needs
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/deployment/requests.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Understanding Requests

> How requests flow through fal's infrastructure, from submission through queue, dispatch, processing, and retries.

When you call a model or your own deployed app on fal, the request passes through several layers before your code processes it and returns a result. Understanding these layers helps you reason about latency, retries, timeouts, and why requests behave the way they do. This page covers the request lifecycle from the caller's perspective down to the runner, and how requests interact with [runners](/documentation/deployment/runners) and the [retry system](/documentation/serverless/reliability/retries).

fal's infrastructure is built around a persistent queue that decouples callers from runners. When you use queue-based methods ([`submit()`](/documentation/model-apis/inference/queue), [`subscribe()`](/documentation/model-apis/inference/synchronous)), your request enters the queue and benefits from automatic retries, status tracking, and durability. Direct methods ([`run()`](/documentation/model-apis/inference/synchronous), [`stream()`](/documentation/model-apis/inference/streaming)) bypass the queue and connect straight to a runner, which is faster but means no retries and no status polling. Both paths share the same runner and scaling infrastructure underneath.

## Request Lifecycle (Queue-Based)

When using `submit()` or `subscribe()`, a request moves through three states visible to callers via the [queue status API](/documentation/model-apis/inference/queue#check-status). Direct calls via `run()` and `stream()` bypass the queue entirely and do not have these states.

<div className="max-w-2xl mx-auto">
  ```mermaid theme={null}
  stateDiagram-v2
      [*] --> IN_QUEUE
      IN_QUEUE --> IN_PROGRESS: Runner picks up request
      IN_PROGRESS --> COMPLETED: Response ready
      IN_PROGRESS --> IN_QUEUE: Runner fails, request retried
      COMPLETED --> [*]
  ```
</div>

| State            | What is happening                                       | Caller sees                                                                |
| ---------------- | ------------------------------------------------------- | -------------------------------------------------------------------------- |
| **IN\_QUEUE**    | Request is waiting in the queue for an available runner | `queue_position` indicating how many requests are ahead                    |
| **IN\_PROGRESS** | A runner is executing your endpoint handler             | [`logs`](/documentation/development/logging) from your code (when enabled) |
| **COMPLETED**    | Result is stored and ready for retrieval                | Full response payload                                                      |

Cancellation is handled separately from the status lifecycle. When a caller [cancels a request](/documentation/model-apis/inference/queue#cancel-a-request), queued requests are removed from the queue and in-progress requests receive a [cancellation signal](/documentation/development/handle-cancellations). The cancel API returns `CANCELLATION_REQUESTED` (202) or `ALREADY_COMPLETED` (400) rather than transitioning to a pollable status.

### How Requests Flow

<Steps>
  <Step title="Submission">
    The caller submits a request via the [SDK](/documentation/model-apis/inference) or REST API. fal assigns a [`request_id`](/documentation/model-apis/inference/queue#submit-a-request) and places the request in the persistent queue. The request enters `IN_QUEUE` state. By default there is no queue size limit and requests are never dropped. Callers can optionally set [`fal_max_queue_length`](/documentation/model-apis/common-parameters#fal-max-queue-length) to reject requests with 429 if the queue exceeds a threshold.
  </Step>

  <Step title="Dispatch">
    The dispatcher checks for available IDLE [runners](/documentation/deployment/runners). If a runner is free, the request is routed immediately and enters `IN_PROGRESS`. If all runners are busy, the request waits in the queue while fal [scales up](/documentation/deployment/scale-your-application) new runners. Runners with matching [routing hints](/documentation/serverless/optimizations/optimize-routing-behavior) are preferred when available.
  </Step>

  <Step title="Processing">
    The runner receives the request as a standard HTTP call. Your [endpoint handler](/documentation/development/endpoints-overview) runs, processes the input, and returns a response. The runner transitions from RUNNING back to IDLE. If the runner fails, the request is [retried](/documentation/serverless/reliability/retries) automatically.
  </Step>

  <Step title="Result">
    The response is stored and the request enters `COMPLETED`. The caller retrieves the result by [polling or streaming status](/documentation/model-apis/inference/queue#check-status), or receives it via [webhook](/documentation/model-apis/inference/webhooks). For direct `run()` calls, the response is returned in the same HTTP connection.
  </Step>
</Steps>

Your endpoint code receives every request as a regular HTTP call. It does not matter whether the caller used `run()`, `submit()`, or `stream()`. The queue and dispatch layer are transparent to your app code.

## Requests and Retries

Retries only apply to queue-based requests. Direct calls via `run()` and `stream()` return errors immediately with no retry.

When a runner fails while processing a queued request, the request is placed in a scheduled requeue with a backoff delay, then re-enters the queue and is dispatched to a different runner. This happens automatically for server errors (503), timeouts (504), and connection failures, up to 10 attempts. The retry is transparent to the caller -- they continue polling the same `request_id` and eventually get a result or a final failure.

<div className="max-w-2xl mx-auto">
  ```mermaid theme={null}
  stateDiagram-v2
      [*] --> IN_QUEUE
      IN_QUEUE --> IN_PROGRESS: "Attempt 1"
      IN_PROGRESS --> ScheduledRequeue: Runner returns 503
      ScheduledRequeue --> IN_QUEUE: "After backoff delay"
      IN_QUEUE --> IN_PROGRESS: "Attempt 2"
      IN_PROGRESS --> COMPLETED: Success
      COMPLETED --> [*]
  ```
</div>

The [`start_timeout`](/documentation/model-apis/inference/queue#start-timeout) clock runs continuously across all retry attempts. If you set `start_timeout=30` and the first attempt fails after 20 seconds, the second attempt only has 10 seconds left before the server returns 504. This prevents retries from running indefinitely.

You can control retry behavior at three levels: app-level with [`skip_retry_conditions`](/documentation/serverless/reliability/retries#app-level-skip_retry_conditions), per-response with the [`X-Fal-Needs-Retry`](/documentation/serverless/reliability/retries#per-response-x-fal-needs-retry) header, and per-request with the [`X-Fal-No-Retry`](/documentation/serverless/reliability/retries#per-request-client-side-control) header from the caller.

<CardGroup cols={2}>
  <Card title="Understanding Runners" icon="server" href="/documentation/deployment/runners">
    Runner lifecycle states, startup, shutdown, and scaling
  </Card>

  <Card title="Retries and Error Handling" icon="rotate" href="/documentation/serverless/reliability/retries">
    Status codes, response headers, timeouts, and retry control
  </Card>

  <Card title="Caching" icon="layer-group" href="/documentation/deployment/caching">
    How cold start caching affects request latency
  </Card>

  <Card title="Handle Cancellations" icon="xmark" href="/documentation/development/handle-cancellations">
    Implement cancel endpoints for in-progress requests
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/deployment/rollbacks.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Rollbacks & Revisions

> Manage app revisions, roll back to previous versions, and restart runners.

Every time you run `fal deploy`, a new **revision** is created. Your app's alias (e.g., `my-model`) always points to one active revision. You can switch between revisions to roll back to a previous version instantly.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=483&end=570&autoplay=1'><img src='/docs/images/video-thumbs/rollbacks.jpg' alt='Deployment Rollbacks - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Viewing Revisions

### CLI

```bash theme={null}
fal apps list-rev my-model
```

This shows all revisions with their IDs, creation dates, machine types, and scaling configuration.

### Dashboard

Navigate to [**Dashboard > Apps > \[your-app\] > Versions**](https://fal.ai/dashboard/apps). The versions page shows:

* All revisions with creation timestamps
* Status badges: **Deployed**, **Failed**, **Deploying**, **Suspended**
* The current active revision marked with a **Current** badge

***

## Rollouts

A rollout **restarts all runners** without changing the revision. Your app stays on the same code, but all runners are recycled.

### CLI

```bash theme={null}
# Graceful rollout (runners finish current requests before stopping)
fal apps rollout my-model

# Force rollout (runners are killed immediately)
fal apps rollout my-model --force
```

### When to Use Rollouts

* **After changing secrets** -- Runners need to restart to pick up new environment variable values
* **Clearing bad state** -- A runner is stuck or has corrupted in-memory state
* **Memory cleanup** -- Long-running runners have accumulated memory that won't be freed
* **After a config change** -- You changed scaling params via CLI and want runners to restart cleanly

<Warning>
  A force rollout (`--force`) kills runners immediately, dropping any in-progress requests. Use graceful rollouts in production unless you need an emergency restart.
</Warning>

***

## Rolling Back

Switch your app to a previous revision. The old code starts serving requests immediately -- no rebuild needed.

### CLI

```bash theme={null}
# List revisions to find the ID you want
fal apps list-rev my-model

# Switch to a specific revision
fal apps set-rev my-model <revision_id>
```

### Dashboard

1. Go to **Dashboard > Apps > \[your-app] > Versions**
2. Find the revision you want to roll back to
3. Click **Rollback**
4. Confirm in the dialog

<Note>
  When you roll back, runtime-tunable scaling parameters (`keep_alive`, `min_concurrency`, etc.) are inherited from the currently active revision. Code-specific parameters (`max_multiplexing`, `startup_timeout`, `machine_type`) come from the target revision's code.
</Note>

### Rollback Strategies

When you roll back with `fal apps set-rev`, you can also choose how fal rolls traffic to the target revision:

```bash theme={null}
# Switch only after the target revision has a healthy runner
fal apps set-rev my-model <revision_id> --strategy rolling

# Switch immediately and let runners start on demand
fal apps set-rev my-model <revision_id> --strategy recreate
```

* **Rolling** starts a runner on the target revision first and waits for it to complete `setup()` and become healthy before switching the alias. Use this when you want the safest rollback with the least user-visible interruption.
* **Recreate** switches the alias to the target revision immediately. No runner is started proactively, so the next request may cold start the rolled-back revision. Use this when speed matters more than avoiding a brief interruption.

<Note>
  These strategies control how the rollback is applied. A rollback still switches your app to a different revision; a rollout still restarts runners without changing revisions.
</Note>

### When to Roll Back

* A new deploy introduced a bug
* Model performance regressed after an update
* You need to quickly revert while investigating an issue

***

## Deleting Revisions

Clean up old revisions you no longer need.

### CLI

```bash theme={null}
fal apps delete-rev my-model <revision_id>
```

### Dashboard

On the **Versions** page, use the delete option on any non-current revision.

<Note>
  You cannot delete the currently active revision. Switch to a different revision first if you need to delete it.
</Note>

***

## Rollback vs Rollout

|                    | Rollback                                          | Rollout                               |
| ------------------ | ------------------------------------------------- | ------------------------------------- |
| **What changes**   | Switches to a different revision (different code) | Restarts runners on the same revision |
| **Use case**       | Revert to a previous version                      | Refresh runner state                  |
| **Rebuild needed** | No (previous image already exists)                | No                                    |
| **Downtime**       | Brief (new runners start on the old revision)     | Brief (runners restart)               |
| **CLI**            | `fal apps set-rev`                                | `fal apps rollout`                    |


# https://fal.ai/docs/documentation/deployment/runners.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Understanding Runners

> What runners are, how they start, process requests, scale, and shut down.

A runner is a compute instance of your application running on fal's infrastructure. When you [deploy](/documentation/deployment/deploy-to-production) an app, fal creates runners on demand to handle incoming requests. Each runner is tied to a specific [machine type](/documentation/deployment/machine-types) that determines its hardware resources (CPU cores, RAM, GPU type and count). Runners automatically start when requests arrive and shut down when idle, so you only pay for compute you actually use.

Understanding the runner lifecycle is essential for making good decisions about [scaling](/documentation/deployment/scale-your-application), [cold start optimization](/documentation/serverless/optimizations/optimize-cold-starts), and [cost management](/documentation/serverless/optimizations/optimizing-costs). Every scaling parameter, every caching strategy, and every startup optimization ultimately affects how runners behave. This page covers what happens from the moment a runner is scheduled to the moment it shuts down. For how requests flow through the queue and interact with runners, see [Understanding Requests](/documentation/deployment/requests).

## Runner Lifecycle and States

Runners transition through a sequence of states during their lifetime. The startup flow determines your cold start latency, and the shutdown flow determines how gracefully your app handles scale-down events.

<div className="max-w-2xl mx-auto">
  ```mermaid theme={null}
  stateDiagram-v2
      [*] --> PENDING
      PENDING --> DOCKER_PULL: Image not cached
      PENDING --> SETUP: Image cached
      DOCKER_PULL --> SETUP
      SETUP --> IDLE
      FAILURE_DELAY --> PENDING: Retry
      IDLE --> RUNNING: Request arrives
      RUNNING --> IDLE: Request completes
      RUNNING --> DRAINING: Has in-flight requests
      IDLE --> DRAINING: Has in-flight requests
      IDLE --> TERMINATING: No in-flight requests
      RUNNING --> TERMINATING: No in-flight requests
      IDLE --> TERMINATED: keep_alive expires
      DRAINING --> TERMINATING
      TERMINATING --> TERMINATED
      TERMINATED --> [*]
  ```
</div>

| State              | Description                                                                                                    |
| :----------------- | :------------------------------------------------------------------------------------------------------------- |
| **PENDING**        | Runner is waiting to be scheduled on available hardware                                                        |
| **DOCKER\_PULL**   | Pulling Docker image from registry (skipped when image is [cached](/documentation/deployment/caching))         |
| **SETUP**          | Running [`setup()`](/documentation/development/app-lifecycle) method, loading model and initializing resources |
| **FAILURE\_DELAY** | Previous runner startup failed; delaying this runner's start before retrying                                   |
| **IDLE**           | Ready and waiting for work, no active requests                                                                 |
| **RUNNING**        | Actively processing one or more [requests](/documentation/deployment/requests)                                 |
| **DRAINING**       | Finishing current requests, won't accept new ones                                                              |
| **TERMINATING**    | Shutting down, running [`teardown()`](/documentation/development/app-lifecycle) if defined                     |
| **TERMINATED**     | Runner has stopped and resources are released                                                                  |

### Startup

When demand increases, fal schedules a new runner. If the runner's Docker image isn't already [cached](/documentation/deployment/caching), it's pulled first (DOCKER\_PULL). Then your [`setup()`](/documentation/development/app-lifecycle) method runs to load models and initialize resources. Once setup completes and the health check passes, the runner enters IDLE and is ready to serve requests. The time from PENDING to IDLE is your cold start latency.

### Startup Failure

If a runner crashes during startup or `setup()` times out, the runner is terminated. To prevent a tight crash loop, the system applies an incremental backoff to all subsequent runner starts for the same app. When a new runner is about to start and previous runners have failed, it enters `FAILURE_DELAY` -- a holding state where the runner waits before attempting allocation.

The backoff works as follows:

* Each subsequent runner start is delayed by an additional 30 seconds (e.g. 30s, 60s, 90s)
* The delay is capped at 10 minutes
* If any runner succeeds during the delay, all waiting runners are woken up immediately and the backoff resets
* Scheduling failures (when hardware isn't available) also trigger a delay, but use a fixed 20-second wait instead of incremental backoff

After the delay, the runner transitions back to `PENDING` and retries the full startup flow.

When you see runners in `FAILURE_DELAY`, check your `setup()` method and runner logs for errors. Common causes include missing model files, out-of-memory errors during model loading, and dependency issues.

### Request Processing

When a request arrives, an IDLE runner transitions to RUNNING. After completing all requests, it returns to IDLE. Runners can handle multiple concurrent requests if [`max_multiplexing`](/documentation/deployment/scale-your-application) is set above 1.

### Shutdown

Runners shut down through different paths depending on their state:

* **[`keep_alive`](/documentation/deployment/scale-your-application) expiration:** An idle runner with no in-flight requests is terminated directly. The system sends SIGTERM, runs your [`teardown()` method](/documentation/development/app-lifecycle) for cleanup, and then releases resources.
* **Scale-down with in-flight requests:** The runner enters DRAINING. No new requests are routed, but existing requests continue processing. After requests complete, the runner enters TERMINATING, runs `teardown()`, and is terminated.
* **Scale-down with no in-flight requests:** The runner skips DRAINING and enters TERMINATING immediately.
* **Manual stop/kill:** You can terminate runners manually using [`fal runners stop`](/api-reference/cli/runners#stop) or [`fal runners kill`](/api-reference/cli/runners#kill), or from the dashboard.
* **Host maintenance:** The runner may be terminated if the underlying host is being drained due to a maintenance event (GPU errors, networking issues, or scheduled infrastructure updates).

For details on startup and shutdown hooks (`setup()`, `handle_exit()`, `teardown()`), see [App Lifecycle](/documentation/development/app-lifecycle).

<CardGroup cols={2}>
  <Card title="Understanding Requests" href="/documentation/deployment/requests">
    Request lifecycle, retry interaction, and how requests flow through the queue to runners
  </Card>

  <Card title="Caching" href="/documentation/deployment/caching">
    How fal's multi-layer cache reduces cold start times
  </Card>

  <Card title="CLI: fal runners" href="/api-reference/cli/runners">
    List runners, filter by state, view history, and get runner details
  </Card>

  <Card title="App Analytics" href="/documentation/serverless/observability/app-analytics">
    Dashboard metrics for requests, runners, and performance
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/deployment/scale-your-application.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Scaling Parameter Reference

> All scaling parameters for controlling runners, cold starts, and costs.

<Note>
  **WebSocket apps:** All runner scaling parameters below (`keep_alive`, `min_concurrency`, `max_concurrency`, `concurrency_buffer`, `scaling_delay`, `max_multiplexing`, `request_timeout`) apply to WebSocket-based apps the same as queue-based apps. See [Real-Time Inference](/documentation/model-apis/inference/real-time#differences-from-queue-based-inference) for differences in queue-level parameters like retries and priority.
</Note>

### min\_concurrency

**Default:** 0

Minimum number of runners always alive, regardless of traffic.

```python theme={null}
class MyApp(fal.App):
    min_concurrency = 2
```

```bash theme={null}
fal apps scale myapp --min-concurrency 2
```

**When to use:** Your app has slow cold starts and you need guaranteed baseline capacity.

**Trade-off:** Costs money even with zero traffic.

### concurrency\_buffer

**Default:** 0

Extra runners kept warm beyond current demand.

```python theme={null}
class MyApp(fal.App):
    concurrency_buffer = 2
```

```bash theme={null}
fal apps scale myapp --concurrency-buffer 2
```

**When to use:** You expect traffic spikes and want headroom.

<Note>
  When `concurrency_buffer` is higher than `min_concurrency`, it takes precedence. The system keeps whichever is higher.
</Note>

### concurrency\_buffer\_perc

**Default:** 0

Buffer as a percentage of current request volume.

```python theme={null}
class MyApp(fal.App):
    concurrency_buffer_perc = 20  # 20% buffer
```

```bash theme={null}
fal apps scale myapp --concurrency-buffer-perc 20
```

<Note>
  The actual buffer is the **maximum** of `concurrency_buffer` and `concurrency_buffer_perc / 100 * request volume`. So `concurrency_buffer` acts as a minimum floor for the buffer.
</Note>

### max\_concurrency

Upper limit for total runners. Prevents runaway costs.

```python theme={null}
class MyApp(fal.App):
    max_concurrency = 10
```

```bash theme={null}
fal apps scale myapp --max-concurrency 10
```

### keep\_alive

**Default:** 60 seconds

Seconds to keep a runner alive after its last request. Longer values reduce cold starts for sporadic traffic but increase cost.

```python theme={null}
class MyApp(fal.App):
    keep_alive = 300  # 5 minutes
```

```bash theme={null}
fal apps scale myapp --keep-alive 300
```

<Note>
  If your app does not set `min_concurrency` or `concurrency_buffer`, a newly started runner that has not picked up any request yet is shut down after 10 seconds instead of waiting for the full `keep_alive` period.
</Note>

### scaling\_delay

**Default:** 0 seconds

Seconds to wait before scaling up when a request is queued. Prevents premature scaling for brief spikes.

```python theme={null}
class MyApp(fal.App):
    scaling_delay = 30
```

```bash theme={null}
fal apps scale myapp --scaling-delay 30
```

### max\_multiplexing

**Default:** 1

Maximum concurrent requests per runner. Only increase this if your handlers are async and your model has capacity for concurrent inference (e.g., enough GPU memory).

```python theme={null}
class MyApp(fal.App):
    max_multiplexing = 4  # Each runner handles up to 4 requests
```

### startup\_timeout

Maximum seconds allowed for `setup()` to complete.

```python theme={null}
class MyApp(fal.App):
    startup_timeout = 600  # 10 minutes
```

**When to use:** Large model downloads or complex initialization that exceeds the default timeout.

### termination\_grace\_period\_seconds

**Default:** 5 seconds | **Maximum:** 30 seconds

The termination grace period sets the total time window between the runner receiving a shutdown signal (`SIGTERM`) and being forcefully killed (`SIGKILL`). By default, this window is **5 seconds** and can be set to a maximum of **30 seconds**. This time is shared between finishing in-flight requests and running your `teardown()` method.

A runner can be shut down for several reasons:

* **Scaling down** -- demand has decreased and the autoscaler is removing excess runners.
* **`keep_alive` expiration** -- the runner has been idle longer than its configured keep-alive window.
* **New deployment** -- a newer revision of your application is replacing existing runners.
* **Host maintenance** -- the underlying host requires intervention due to GPU failures, networking instability, or scheduled infrastructure updates.

In all cases, the same shutdown sequence occurs:

1. **`SIGTERM` received** -- `handle_exit()` is called immediately. Use this to signal your request handlers to stop processing early.
2. **In-flight requests finish** -- the runner stops accepting new requests but continues processing existing ones.
3. **`teardown()` runs** -- called after all in-flight requests complete, to clean up resources.
4. **`SIGKILL` sent** -- when the grace period expires, the process is forcefully killed regardless of whether `teardown()` has finished.

Without a sufficient grace period, long-running requests may consume the entire window, causing `teardown()` to be skipped when `SIGKILL` arrives. See [App Lifecycle](/documentation/development/app-lifecycle) for more details on the shutdown lifecycle.

```python theme={null}
class MyApp(fal.App):
    termination_grace_period_seconds = 20  # total seconds for requests + teardown

    def handle_exit(self):
        # Called immediately on SIGTERM.
        # Signal your handlers to stop early so teardown() has time to run.
        self.should_stop = True

    def teardown(self):
        # Called after in-flight requests complete.
        # Must finish before the grace period expires or it will be killed.
        self.save_checkpoint()
        self.upload_results()
```

<Warning>
  The grace period is a **shared budget** between finishing in-flight requests and running `teardown()`. If your requests take 90 seconds to complete and your grace period is 120 seconds, `teardown()` only has 30 seconds to run. Use `handle_exit()` to stop request processing early and leave enough time for cleanup.
</Warning>

<Note>
  During the grace period, the runner is still billed as active compute. Set this to the minimum value needed for your workload to shut down cleanly.
</Note>

### machine\_type

GPU/CPU instance type for your runners.

```python theme={null}
class MyApp(fal.App):
    machine_type = "GPU-A100"

# With fallback options (tried in order)
class MyApp(fal.App):
    machine_type = ["GPU-H100", "GPU-A100"]
```

***

## Scaling Examples

#### Same buffer and min concurrency

App with `min_concurrency=1`, `concurrency_buffer=1`, `max_multiplexing=1`, `max_concurrency=10`:

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/examples/scaling-same-buffer-and-min-concurrency.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=cf1a7cc234b7a0ad44cff1074c6fab6c" width="1200" height="800" data-path="images/examples/scaling-same-buffer-and-min-concurrency.png" />
</Frame>

#### No multiplexing

App with `min_concurrency=3`, `concurrency_buffer=2`, `max_multiplexing=1`, `max_concurrency=10`:

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/examples/scaling-no-multiplexing.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=1fb0e1b18956e253dc14fd1765f25ede" width="1200" height="800" data-path="images/examples/scaling-no-multiplexing.png" />
</Frame>

#### With multiplexing

App with `min_concurrency=0`, `concurrency_buffer=2`, `max_multiplexing=4`, `max_concurrency=6`:

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/examples/scaling-with-multiplexing.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=147a42ec4854780366bf4328dd401f9f" width="1200" height="800" data-path="images/examples/scaling-with-multiplexing.png" />
</Frame>

With multiplexing of 4, a single runner handles up to 4 requests simultaneously. Even with `min_concurrency=0`, the system keeps 2 runners alive for the buffer.

***

## Cost Optimization

* **Start conservative** and adjust based on actual traffic
* **Use `concurrency_buffer`** for apps with slow startup instead of high `min_concurrency`
* **Enable multiplexing** when your model has spare GPU capacity for concurrent requests
* **Monitor with analytics** and tune parameters based on real usage patterns
* **Set `max_concurrency`** to prevent runaway costs during unexpected traffic spikes

<Card title="Updating Your Configuration" icon="arrow-right" href="/documentation/deployment/scaling-configuration">
  Learn how to set parameters via code, CLI, or dashboard -- and how they behave across deploys
</Card>

## Video Walkthrough

See concurrency buffer and scaling delay in action:

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=75&end=222&autoplay=1'><img src='/docs/images/video-thumbs/scale-your-application.jpg' alt='Scaling Parameters - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>


# https://fal.ai/docs/documentation/deployment/scaling-configuration.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Updating Your Configuration

> How to set scaling parameters via code, CLI, or dashboard -- and how they behave across deploys.

## How to Set Parameters

You can set scaling parameters in three ways.

### In Your Code

```python theme={null}
import fal

class MyApp(fal.App):
    machine_type = "GPU-A100"
    max_multiplexing = 1
    startup_timeout = 600

    keep_alive = 300
    min_concurrency = 2
    max_concurrency = 10
    concurrency_buffer = 2
    scaling_delay = 30
```

### Via CLI

Adjust parameters for a deployed app without redeploying:

```bash theme={null}
fal apps scale myapp \
  --min-concurrency 5 \
  --max-concurrency 20 \
  --keep-alive 600 \
  --concurrency-buffer 3
```

### Via Dashboard

Navigate to [**Dashboard > Apps > \[your-app\]**](https://fal.ai/dashboard/apps) and adjust scaling parameters from the app settings.

***

## How Parameters Behave Across Deploys

Not all parameters behave the same when you deploy. Understanding this prevents surprises.

### Runtime-tunable parameters

`keep_alive`, `min_concurrency`, `max_concurrency`, `concurrency_buffer`, `concurrency_buffer_perc`, `scaling_delay`, `request_timeout`, `regions`

These affect **cost and performance** and are safe to change without understanding the code. When you adjust them via CLI or dashboard:

* Changes take effect immediately
* Changes **persist across deploys** -- your next `fal deploy` inherits the CLI/dashboard values, not what's in your code

### Code-specific parameters

`max_multiplexing`, `startup_timeout`, `machine_type`

These affect **correctness** -- changing them without updating code can break your app:

* **`max_multiplexing`**: Your code must handle concurrent requests. Setting this to 4 via CLI when your handlers are synchronous would break things.
* **`startup_timeout`**: Depends on what your `setup()` does. Only the code author knows the right value.
* **`machine_type`**: Your model is sized for specific GPU memory. Switching GPUs without code changes risks OOM crashes.

You can change these via CLI for **immediate but temporary** testing, but they **reset to code values on the next deploy**.

<Warning>
  CLI changes to code-specific params take effect immediately but reset on deploy. To make changes permanent, update your application code.
</Warning>

***

## `--reset-scale`

By default, `fal deploy` inherits runtime-tunable params from the previous revision. If you want to discard all CLI/dashboard overrides and go back to what's in your code:

```bash theme={null}
fal deploy --reset-scale
```

This resets **all parameters** to code values.

**When to use:**

* You want to go back to the values in your code after tuning via CLI
* You're making a major change and want a clean slate
* You've updated scaling values in code and want them to take effect

***

## Example

```python theme={null}
class MyApp(fal.App):
    min_concurrency = 1
    keep_alive = 60
```

1. **Deploy**: `min_concurrency=1`, `keep_alive=60`
2. **CLI**: `fal apps scale myapp --min-concurrency 5 --keep-alive 300`
   * Now: `min_concurrency=5`, `keep_alive=300`
3. **Deploy again** (`fal deploy`):
   * `min_concurrency=5`, `keep_alive=300` (inherited from step 2)
4. **Deploy with reset** (`fal deploy --reset-scale`):
   * `min_concurrency=1`, `keep_alive=60` (reset to code)

<Card title="Parameter Reference" icon="arrow-right" href="/documentation/deployment/scale-your-application">
  See what each scaling parameter does
</Card>


# https://fal.ai/docs/documentation/development/add-health-check-endpoint.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Health Check Endpoint

> Add a health check endpoint to your fal app so the platform can detect and replace unhealthy runners.

Health check endpoints let fal verify that your [runners](/documentation/deployment/runners) are functioning correctly. When a health check fails repeatedly, fal automatically terminates the unhealthy runner and provisions a new one. This is useful for apps that depend on external services, database connections, or other resources that can become unavailable during a runner's lifetime.

You define a health check by adding an `@fal.endpoint` with the `health_check` parameter. The endpoint should be lightweight and raise an exception if the runner is in an unrecoverable state. For more on how runners start up and shut down, see [App Lifecycle](/documentation/development/app-lifecycle). For how status codes affect runner lifecycle and retries, see [Retries and Error Handling](/documentation/serverless/reliability/retries).

## Basic Usage

Use the `health_check` keyword argument in the `@fal.endpoint()` decorator to designate an endpoint as your health check:

```python theme={null}
import fal
from pydantic import BaseModel

class HealthResponse(BaseModel):
    status: str

class MyApp(fal.App):
    def setup(self):
        self.model = load_model()
        self.connection = connect_to_something()

    @fal.endpoint("/")
    def predict(self, input: Input) -> Output:
        x = self.connection.do_something(input)
        return self.model.run(x)

    @fal.endpoint(
        "/health",
        health_check=fal.HealthCheck(
            start_period_seconds=10,
            timeout_seconds=5,
            failure_threshold=3,
            call_regularly=True,
        ),
    )
    def health(self) -> HealthResponse:
        if not self.connection.is_alive():
            raise RuntimeError("Lost connection to the external service")
        return HealthResponse(status="ok")
```

<Note>
  Only one endpoint can be designated as the health check endpoint per app.
</Note>

## Configuration

| Parameter              | Type | Default | Description                                                                                                                                                |
| ---------------------- | ---- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `start_period_seconds` | int  | `30`    | Minimum time the runner has been running before health check failures count. Replaced by `startup_timeout` if that value is higher.                        |
| `timeout_seconds`      | int  | `5`     | Timeout in seconds for the health check request.                                                                                                           |
| `failure_threshold`    | int  | `3`     | Number of consecutive failures before the runner is considered unhealthy and terminated.                                                                   |
| `call_regularly`       | bool | `True`  | If true, fal calls the health check every 15 seconds. If false, health checks only run when manually triggered via the `x-fal-runner-health-check` header. |

## How It Works

By default, fal calls your health check endpoint every 15 seconds. During the `start_period_seconds` window after a runner starts, failures are ignored to give your app time to initialize. After that, if the health check fails or times out for `failure_threshold` consecutive calls, the runner is terminated and replaced. To signal an unhealthy state, raise an exception inside the health check method. Returning a normal response means the runner is healthy.

<Warning>
  The health check endpoint can be called while another request is being processed. Avoid heavy computations or acquiring GPU resources in your health check, as it could interfere with in-flight requests.
</Warning>

## Manual Health Checks

You can trigger a health check from within a regular endpoint by setting the `x-fal-runner-health-check` header on the response. This is useful when your endpoint detects a degraded state and wants the platform to verify runner health immediately.

```python theme={null}
@fal.endpoint("/predict")
def predict(self, input: Input, response: Response) -> Output:
    response.headers["x-fal-runner-health-check"] = "true"
    return self.model.run(input)
```

Manually triggered health checks bypass `failure_threshold` and `start_period_seconds`. If the subsequent health check fails, the runner is terminated immediately.

## Writing Good Health Checks

Keep your health check lightweight. It runs concurrently with normal requests, so heavy GPU work could contend with or slow down in-flight inference. For most apps, checking external dependencies (database connections, upstream APIs) is sufficient. If you do need to verify GPU health, keep the operation minimal (e.g., a small tensor allocation) to avoid interfering with active requests.

Only raise exceptions for truly unrecoverable states that require a fresh runner. For transient issues, try to recover within the health check before failing:

```python theme={null}
@fal.endpoint("/health", health_check=fal.HealthCheck(timeout_seconds=10))
def health(self) -> HealthResponse:
    if not self.connection.is_alive():
        try:
            self.connection.reconnect()
        except Exception as e:
            raise RuntimeError(f"Failed to reconnect: {e}")
    return HealthResponse(status="ok")
```

If you are concerned about the performance impact of periodic health checks, set `call_regularly=False` and trigger checks manually from your endpoints when you detect a problem.


# https://fal.ai/docs/documentation/development/advanced/optimize-routing-behavior.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimize Routing Behavior

> Use routing hints to direct requests to runners that already have the right model or state loaded in memory.

When you scale to multiple runners, fal normally treats them as interchangeable and routes requests to any available runner. This works well when every runner is identical, but falls short when runners hold different state. For example, an app that serves multiple diffusion models but can only keep a few loaded in GPU memory at once. Routing a request for FLUX.1 to a runner that already has FLUX.1 loaded avoids a costly model swap, while routing it to a runner with a different model loaded means waiting for a full model load.

Routing hints solve this with a two-sided mechanism. On the caller side, you pass a [`hint` parameter](/documentation/model-apis/inference/queue#hint) (sent as the `X-Fal-Runner-Hint` header) that describes what the request needs. On the server side, your app implements a `provide_hints()` method that tells fal what each runner is currently specialized for. When both are present, fal's router tries to match requests to runners with compatible hints. If no matching runner is available or all matching runners are busy, the request goes to any available runner without waiting. Hints are best-effort: they improve cache hit rates but never block a request from being processed.

## How It Works

The router matches the hint string from the caller against the list of strings each runner reports via `provide_hints()`. The matching is exact: if the caller sends `hint="flux-schnell"` and a runner's `provide_hints()` returns `["flux-schnell", "sd-xl"]`, that runner is preferred. If no runner has a matching hint, the request goes to any available runner.

`provide_hints()` is called after every response and the result is sent back to the platform as a response header. This means hints update dynamically as the runner loads and unloads models. A runner that starts empty will initially match any request, and as it loads models, it becomes specialized for those models.

## Example

This app serves any Hugging Face diffusion model by name. Each runner maintains a cache of loaded models. The hint is the model name, which matches what `provide_hints()` reports.

### Application

```python theme={null}
from typing import Any

import fal
from fal.toolkit import Image
from pydantic import BaseModel, Field


class Input(BaseModel):
    model: str = Field(description="Hugging Face model ID")
    prompt: str = Field(description="Text prompt")


class Output(BaseModel):
    image: Image


class AnyModelRunner(fal.App):
    machine_type = "GPU-A100"

    def setup(self) -> None:
        self.models = {}

    def provide_hints(self) -> list[str]:
        return list(self.models.keys())

    def load_model(self, name: str) -> Any:
        from diffusers import DiffusionPipeline

        if name in self.models:
            return self.models[name]

        pipeline = DiffusionPipeline.from_pretrained(name)
        pipeline.to("cuda")

        self.models[name] = pipeline
        return pipeline

    @fal.endpoint("/")
    def run_model(self, input: Input) -> Output:
        model = self.load_model(input.model)
        result = model(input.prompt)
        return Output(image=Image.from_pil(result.images[0]))
```

When a runner starts, `provide_hints()` returns an empty list, so it matches any request. As it loads models, the hints update to include the loaded model names. Over time, the router naturally specializes runners by directing repeat requests for the same model to the same runner.

### Client

The caller passes the model name as both an argument (for the app logic) and a hint (for the router). The hint is processed at the gateway before the request reaches your app, so it cannot be extracted from the request body automatically.

```python theme={null}
import fal_client

model = "black-forest-labs/FLUX.1-schnell"

handler = fal_client.submit(
    "myuser/myapp",
    arguments={
        "model": model,
        "prompt": "a cat",
    },
    hint=model,
)

result = handler.get()
```

## When to Use Hints

Hints are most valuable when your app serves multiple models or configurations that are expensive to swap. Common patterns include multi-model serving (as shown above), per-user LoRA adapters where each user's adapter is cached on a specific runner, and pipeline configurations with different preprocessing states.

If every runner in your app is identical (same model, same state), you do not need hints. The default round-robin routing is sufficient.

<Warning>
  Hints are sent as a response header, which counts toward the **16 KB total response header limit**. If `provide_hints()` returns many values or long strings, the combined headers can exceed this limit and cause the response to fail. Keep hint values short and limit the number of hints per runner.
</Warning>


# https://fal.ai/docs/documentation/development/app-lifecycle.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# App Lifecycle

> The complete lifecycle of a fal app, from writing code to runner shutdown.

Every fal app follows the same lifecycle, whether it is a simple Hello World or a production image generation pipeline. Understanding this sequence helps you write more efficient apps, debug startup issues, and handle shutdown gracefully.

This page walks through each stage in order using `fal.App`, the class-based approach. If you prefer a decorator-based approach or are migrating an existing Docker server, see [`fal.function`](/documentation/development/migrate-external-docker-server#fal-function-reference), which supports all the same scaling parameters. For how to define your app's environment (pip packages vs Docker containers), see [Defining Your Environment](/documentation/development/container-setup). For how runners scale up and down based on demand, see [Runners and Caching](/documentation/getting-started/runners-and-caching).

## Defining Your App

You write a Python class that inherits from `fal.App`. This class declares what hardware it needs, what packages to install, how to initialize your model, and what endpoints are available. At this stage, nothing runs remotely. You are just defining the blueprint.

```python theme={null}
import fal
from pydantic import BaseModel

class Input(BaseModel):
    prompt: str

class Output(BaseModel):
    result: str

class MyApp(fal.App):
    machine_type = "GPU-H100"
    requirements = ["torch", "transformers"]

    def setup(self):
        from transformers import pipeline
        self.pipe = pipeline("text-generation", model="gpt2", device="cuda")

    @fal.endpoint("/")
    def generate(self, input: Input) -> Output:
        result = self.pipe(input.prompt, max_length=50)[0]["generated_text"]
        return Output(result=result)

    def teardown(self):
        del self.pipe
```

## Serialization and Build

When you run `fal run` or `fal deploy`, fal pickles your app class on your local machine and ships it to the cloud. All top-level code in your file (module imports, constants, helper functions) executes locally during this step. fal then builds a container from your [requirements](/documentation/development/fal-runtime) list or [custom Dockerfile](/documentation/development/use-custom-container-image), installing your dependencies into the remote environment.

This serialization step creates a boundary between what runs locally and what runs remotely. Understanding this boundary is essential for debugging, managing secrets, and controlling what gets shipped.

### What runs locally

When Python imports your app file, all top-level code executes on your machine: class bodies are evaluated, module-level variables are assigned, and helper functions are defined. If you reference an environment variable at the top level, it reads from your local environment, not the remote runner's. If you construct a large object at module scope, it will be serialized (pickled) and shipped as part of the app payload.

```python theme={null}
import os
import fal

CONFIG = {"api_key": os.environ["MY_API_KEY"]}

def helper(x):
    import torch
    return torch.tensor(x)
```

In this example, `CONFIG` is evaluated locally and pickled into the app payload. The `helper` function is defined locally but its body only executes remotely when called. The `import torch` inside the function runs on the remote runner, not on your machine.

### What runs remotely

Your `fal.App` subclass is pickled locally, then unpickled and instantiated on the remote runner in the environment you configured. All methods on the class, including `setup()`, your `@fal.endpoint` handlers, and `teardown()`, execute on the remote machine.

Symbols referenced by your app are handled in one of two ways. Small objects (closures, constants, simple data structures) are pickled and shipped as part of the payload. Importable packages that are installed in the remote environment are imported there rather than being serialized. This is why you often see imports inside methods rather than at the top of the file: it ensures the import happens in the remote environment where the package is installed.

```python theme={null}
import fal

CONFIG = {"model_name": "stabilityai/sdxl-base"}

class MyApp(fal.App):
    machine_type = "GPU-A100"
    requirements = ["torch", "diffusers"]

    def setup(self):
        from diffusers import StableDiffusionXLPipeline
        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            CONFIG["model_name"]
        ).to("cuda")

    @fal.endpoint("/")
    def generate(self, input: dict) -> dict:
        result = self.pipe(input["prompt"]).images[0]
        return {"image": result}
```

In this example, `CONFIG` is a small dictionary that gets pickled and shipped to the runner. The `diffusers` import happens inside `setup()`, so it runs remotely where the package is installed via `requirements`. The `StableDiffusionXLPipeline` is loaded into GPU memory on the runner, not on your laptop.

### The serialization boundary

Objects that pickle well (strings, numbers, dicts, lists, simple dataclasses) can be freely referenced from top-level code. Objects that do not pickle well (database connections, file handles, GPU tensors, large numpy arrays) should be created inside `setup()` or endpoint methods, where they run on the remote machine.

If you need to pass secrets to your app, avoid putting them in top-level code where they would be pickled into the payload. Instead, use fal's [secrets management](/documentation/development/manage-secrets-securely) to store them securely and access them via [environment variables](/documentation/development/environment-variables) on the runner.

## Runner Startup

New [runners](/documentation/deployment/runners) are created in several situations: when incoming requests exceed the capacity of existing runners, when [min\_concurrency](/documentation/deployment/scale-your-application) requires runners to be warm even without traffic, or when [concurrency\_buffer](/documentation/deployment/scale-your-application) maintains spare runners ahead of demand so new requests hit a warm runner instead of triggering a cold start. If a request arrives and an idle runner is already available, it is routed there immediately with no startup needed. Only when no idle runner is available does fal provision a new machine, pull the container image, and start your app. The platform calls `setup()` before routing any requests to the new runner.

`setup()` is the right place for expensive one-time work: downloading model weights, loading them into GPU memory, compiling kernels, or running a warmup inference. The runner is not considered ready until `setup()` completes successfully. If it fails or exceeds the [startup\_timeout](/documentation/deployment/scale-your-application), the runner is terminated and replaced. Requests that were waiting for this runner stay in the queue and are routed to the next available runner.

Because `setup()` runs once per runner (not once per request), expensive operations only happen at startup. Subsequent requests reuse the loaded model. For strategies to speed up this step, see [Optimizing Cold Starts](/documentation/serverless/optimizations/optimize-cold-starts).

```python theme={null}
def setup(self):
    import torch
    from diffusers import StableDiffusionXLPipeline

    self.pipe = StableDiffusionXLPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        torch_dtype=torch.float16,
    ).to("cuda")

    self.pipe("warmup")  # first inference compiles kernels
```

## Serving Requests

Once `setup()` completes, the runner enters the IDLE state and starts accepting requests. Each incoming request is routed to an available runner and dispatched to the matching `@fal.endpoint` method. If [max\_multiplexing](/documentation/deployment/scale-your-application) is greater than 1, a single runner can handle multiple requests concurrently.

Your endpoint methods run on the remote machine with full access to `self` (including anything you loaded in `setup()`). Inputs and outputs are validated through your Pydantic models. For details on defining schemas and how they map to the Playground UI, see [Handle Inputs and Outputs](/documentation/development/handle-inputs-and-outputs).

Between requests, the runner stays alive for the duration of the [keep\_alive](/documentation/deployment/scale-your-application) period. If no new requests arrive before keep\_alive expires, the runner begins shutting down.

## Shutdown

Runners shut down when they reach their keep\_alive expiration, when you manually stop them via the CLI or dashboard, or when fal scales down due to reduced demand. The shutdown sequence follows a strict order with a **5-second grace period**:

1. The runner receives `SIGTERM`. No new requests are routed to it.
2. `handle_exit()` is called immediately.
3. In-flight requests finish processing (or stop early if `handle_exit()` signaled them).
4. `teardown()` is called after all requests complete.
5. After 5 seconds from `SIGTERM`, the runner is forcefully terminated with `SIGKILL`.

### handle\_exit

`handle_exit()` is called the moment `SIGTERM` arrives. Use it to signal long-running request handlers to stop processing early, so there is time left for cleanup in `teardown()`. Without `handle_exit()`, a long-running request may consume the entire 5-second grace period, causing `teardown()` to be skipped when `SIGKILL` arrives.

### teardown

`teardown()` is called after all in-flight requests have finished. Use it to close database connections, release resources, flush logs, or perform any final cleanup before the runner is terminated.

### Example

```python theme={null}
import threading
import fal

class MyApp(fal.App):
    machine_type = "GPU-A100"

    def setup(self):
        self.model = load_model()
        self.db = connect_to_database()
        self.exit = threading.Event()

    @fal.endpoint("/")
    def run(self, input: dict) -> dict:
        for i in range(30):
            if self.exit.is_set():
                break
            result = self.model.process_step(i)
        return {"result": result}

    def handle_exit(self):
        self.exit.set()

    def teardown(self):
        self.db.close()
```

In this example, `setup()` loads a model and opens a database connection. The endpoint checks `self.exit` on each iteration so it can stop early when `SIGTERM` arrives. `handle_exit()` sets the flag, and `teardown()` closes the database connection after the request finishes.

<Warning>
  If you are using `fal` versions before 1.61.0, runners are terminated immediately without a grace period.
</Warning>

<Note>
  While it is possible to add your own signal handlers, we recommend using `handle_exit()` instead. The `setup()`, `handle_exit()`, and `teardown()` methods provide a clean and predictable lifecycle without the complexity of custom signal handling.
</Note>

## Next Steps

From here, [Defining Your Environment](/documentation/development/container-setup) covers how to choose between pip requirements and custom Docker containers. [Runners and Caching](/documentation/getting-started/runners-and-caching) explains runner states, scaling behavior, and the multi-layer caching system. For handling graceful cancellation of in-flight requests from the caller side, see [Handle Cancellations](/documentation/development/handle-cancellations).


# https://fal.ai/docs/documentation/development/app-setup.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Application Setup

> Prepare your app's runtime environment: load models, download weights, and configure persistent storage.

Once you have defined your [environment](/documentation/development/container-setup) (pip requirements or a Docker container) and written your [app class](/documentation/development/app-lifecycle), the next step is preparing what happens when a runner starts. This section covers the resources your app needs at runtime: where to store model weights, how to download them efficiently, and how to structure your [setup()](/documentation/development/app-lifecycle#runner-startup) method so that cold starts are as fast as possible.

Everything in `setup()` runs once per [runner](/documentation/deployment/runners), not once per request. This is where you load model weights into GPU memory, initialize connections, and prepare any state that your endpoint methods will use. Objects you attach to `self` (like `self.model`) persist for the lifetime of the runner, so expensive operations only happen at startup. The trade-off is that everything in `setup()` contributes to your app's cold start time, which is the delay a request experiences when no idle runner is available and a new one must be provisioned.

```python theme={null}
class MyModel(fal.App):
    machine_type = "GPU-A100"
    requirements = ["torch", "diffusers"]

    def setup(self):
        import torch
        from diffusers import StableDiffusionXLPipeline

        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
        ).to("cuda")

        self.pipe("warmup")

    @fal.endpoint("/")
    def generate(self, input: dict) -> dict:
        image = self.pipe(input["prompt"]).images[0]
        return {"image": image}
```

In this example, `setup()` downloads SDXL weights (cached to `/data` automatically for HuggingFace models), loads them into GPU memory, and runs a warmup inference to compile any lazy kernels. All of this happens once. Every subsequent request reuses `self.pipe` without any initialization overhead.

## What to Read Next

The pages in this section cover the infrastructure that supports your setup method. [Persistent Storage](/documentation/development/use-persistent-storage) explains the `/data` volume where model weights and datasets are cached across runners, including how the distributed filesystem works, how to upload files outside of your app, and how to handle concurrent writes safely. [Downloading Models and Files](/documentation/development/download-model-weights-and-files) covers the `download_file()` and `download_model_weights()` toolkit utilities, along with detailed Hugging Face optimization techniques for faster initial downloads, parallel file pre-reading, and compiled kernel caching.

For strategies to reduce cold start time beyond what is covered here, see [Optimizing Cold Starts](/documentation/serverless/optimizations/optimize-cold-starts), which covers container image optimization, scaling parameters, and [FlashPack](/documentation/serverless/optimizations/flashpack) for high-throughput tensor loading.


# https://fal.ai/docs/documentation/development/calling-your-endpoints.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Calling Your Endpoints

> How to call your deployed serverless endpoints using the fal client SDKs.

Once your app is deployed, you can call it using the same client SDKs and patterns used for any model on fal. Your app's endpoint ID is `your-username/your-app-name`, and all of the [inference methods](/documentation/model-apis/inference) work identically whether you are calling a marketplace model or your own deployed app.

This page shows quick examples of each calling pattern. `subscribe` is the simplest option since it handles polling for you and blocks until the result is ready. For production workloads where you need to manage many requests in parallel, `submit` gives you full control over the request lifecycle. For full details on parameters, response shapes, status polling, and cancellation, see the [Inference documentation](/documentation/model-apis/inference).

## Subscribe

Submits a request to the queue, polls automatically, and returns the result when ready. This is the simplest calling pattern since it handles the request lifecycle for you. Optionally receive progress updates via callbacks.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import fal_client

    result = fal_client.subscribe("your-username/your-app-name", arguments={
        "prompt": "a sunset over mountains"
    })
    print(result)
    ```

    With progress updates:

    ```python theme={null}
    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(
        "your-username/your-app-name",
        arguments={"prompt": "a sunset over mountains"},
        with_logs=True,
        on_queue_update=on_queue_update,
    )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const result = await fal.subscribe("your-username/your-app-name", {
      input: { prompt: "a sunset over mountains" },
    });
    console.log(result.data);
    ```

    With progress updates:

    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const result = await fal.subscribe("your-username/your-app-name", {
      input: { prompt: "a sunset over mountains" },
      logs: true,
      onQueueUpdate: (update) => {
        if (update.status === "IN_PROGRESS") {
          update.logs?.map((log) => console.log(log.message));
        }
      },
    });
    ```
  </Tab>
</Tabs>

<Card title="Synchronous Inference" href="/documentation/model-apis/inference/synchronous">
  Full details on subscribe, progress updates, and timeout handling
</Card>

## Queue (Async)

For fire-and-forget workflows. Submit a request, get a request ID, and retrieve the result later by polling or webhook.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import fal_client

    handler = fal_client.submit("your-username/your-app-name", arguments={
        "prompt": "a sunset over mountains"
    })

    print(f"Request ID: {handler.request_id}")

    # Check status
    status = handler.status()
    print(status)

    # Get result when ready
    result = handler.get()
    print(result)
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const { request_id } = await fal.queue.submit("your-username/your-app-name", {
      input: { prompt: "a sunset over mountains" },
    });

    console.log(`Request ID: ${request_id}`);

    // Check status
    const status = await fal.queue.status("your-username/your-app-name", {
      requestId: request_id,
      logs: true,
    });

    // Get result when ready
    const result = await fal.queue.result("your-username/your-app-name", {
      requestId: request_id,
    });
    ```
  </Tab>
</Tabs>

<Card title="Asynchronous Inference" href="/documentation/model-apis/inference/queue">
  Full details on the queue system, status polling, and REST API reference
</Card>

## Streaming

For apps that produce progressive output via Server-Sent Events (SSE). Your app must define a streaming endpoint at `/stream` using `@fal.endpoint("/stream")`.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import fal_client

    for event in fal_client.stream("your-username/your-app-name", arguments={
        "prompt": "a sunset over mountains"
    }):
        print(event)
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const stream = await fal.stream("your-username/your-app-name", {
      input: { prompt: "a sunset over mountains" },
    });

    for await (const event of stream) {
      console.log(event);
    }

    const finalResult = await stream.done();
    ```
  </Tab>
</Tabs>

<CardGroup cols={2}>
  <Card title="Building Streaming Endpoints" href="/documentation/development/streaming">
    How to implement SSE streaming in your fal.App
  </Card>

  <Card title="Streaming Inference" href="/documentation/model-apis/inference/streaming">
    Client-side streaming details and REST API
  </Card>
</CardGroup>

## Real-Time (WebSocket)

For bidirectional, low-latency communication over a persistent connection. Your app must define a `@fal.realtime("/realtime")` endpoint.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import fal_client

    with fal_client.realtime("your-username/your-app-name") as connection:
        connection.send({"prompt": "Hello, world!"})
        result = connection.recv()
        print(result)
    ```

    Async version:

    ```python theme={null}
    import asyncio
    import fal_client

    async def main():
        async with fal_client.realtime_async("your-username/your-app-name") as connection:
            await connection.send({"prompt": "Hello, world!"})
            result = await connection.recv()
            print(result)

    asyncio.run(main())
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const connection = fal.realtime.connect("your-username/your-app-name", {
      onResult: (result) => {
        console.log(result);
      },
    });

    connection.send({ prompt: "Hello, world!" });
    ```
  </Tab>
</Tabs>

<CardGroup cols={2}>
  <Card title="Building Realtime Endpoints" href="/documentation/development/realtime">
    How to implement WebSocket endpoints in your fal.App
  </Card>

  <Card title="Real-Time Inference" href="/documentation/model-apis/inference/real-time">
    Client-side real-time details and proxy setup
  </Card>
</CardGroup>

## Webhooks

Submit a request and receive the result at a URL you specify, instead of polling.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import fal_client

    handler = fal_client.submit(
        "your-username/your-app-name",
        arguments={"prompt": "a sunset over mountains"},
        webhook_url="https://your-server.com/api/webhook",
    )

    print(f"Request ID: {handler.request_id}")
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const { request_id } = await fal.queue.submit("your-username/your-app-name", {
      input: { prompt: "a sunset over mountains" },
      webhookUrl: "https://your-server.com/api/webhook",
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://queue.fal.run/your-username/your-app-name?fal_webhook=https://your-server.com/api/webhook" \
      -H "Authorization: Key $FAL_KEY" \
      -H "Content-Type: application/json" \
      -d '{"prompt": "a sunset over mountains"}'
    ```
  </Tab>
</Tabs>

When the request completes, fal sends a `POST` to your webhook URL with the result:

```json theme={null}
{
  "request_id": "abc-123",
  "status": "OK",
  "payload": { ... }
}
```

<Card title="Webhooks API" href="/documentation/model-apis/inference/webhooks">
  Full details on webhook payloads, retries, verification, and IP allowlisting
</Card>

## Passing Headers

You can pass custom headers with any calling method to control platform behavior:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import fal_client

    result = fal_client.subscribe(
        "your-username/your-app-name",
        arguments={"prompt": "a sunset"},
        headers={
            "x-fal-no-retry": "1",
        },
    )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const result = await fal.subscribe("your-username/your-app-name", {
      input: { prompt: "a sunset" },
      headers: {
        "x-fal-no-retry": "1",
      },
    });
    ```
  </Tab>
</Tabs>

See [Platform Headers](/documentation/model-apis/common-parameters) for all available headers, and [Retries](/documentation/serverless/reliability/retries) for retry control. Each inference method page also documents its available SDK parameters.

## Next Steps

<CardGroup cols={2}>
  <Card title="Inference Documentation" href="/documentation/model-apis/inference">
    Full details on all calling methods, parameters, status polling, and the request handle
  </Card>

  <Card title="Async Inference (Queue)" href="/documentation/model-apis/inference/queue">
    Submit, status, result, cancel, webhooks, and streaming status updates
  </Card>

  <Card title="Client Setup" href="/documentation/model-apis/inference/client-setup">
    Install and configure the fal client SDK
  </Card>

  <Card title="Handle Inputs & Outputs" href="/documentation/development/handle-inputs-and-outputs">
    Define the input/output schema for your endpoints
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/development/container-setup.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment and Runtime

> Choose how to define the environment your fal app runs in.

Before your app can run on fal, the platform needs to know what packages, system libraries, and runtime your code depends on. This page helps you choose between two approaches: using fal's managed Python runtime with a pip requirements list, or bringing your own Docker container for full control over the environment.

If your app only needs pip packages, the managed runtime is the simplest option. You list your dependencies in the `requirements` attribute and fal handles CUDA setup and environment isolation, so you do not need to write or maintain a Dockerfile. If you need system-level packages (like `ffmpeg`), a specific CUDA version, a non-Python runtime, or you are migrating an existing Docker-based server, the custom container path gives you full control over the build. Both approaches produce the same kind of [runner](/documentation/getting-started/runners-and-caching) and support all the same scaling, observability, and deployment features.

## fal Runtime

For apps that only need pip packages, the managed runtime is the simplest setup. You define your pip dependencies in the `requirements` attribute of your app class and fal builds the container for you. This approach handles CUDA and PyTorch setup automatically based on your chosen [machine type](/documentation/deployment/machine-types), so you do not need to manage base images or CUDA library versions.

```python theme={null}
class MyApp(fal.App):
    machine_type = "GPU-A100"
    requirements = ["torch==2.4.0", "diffusers", "transformers"]
```

If your project has local Python modules or external repositories you need to include, the [Import Code](/documentation/development/import-code) page covers `app_files`, `local_python_modules`, and git clone patterns.

See [fal Runtime](/documentation/development/fal-runtime) for the full guide including CUDA handling, extra index URLs, and best practices.

## Custom Container

When you need full control over the environment, use a Dockerfile. This is the right choice when your app requires system packages, a specific base image, non-Python dependencies, or you are bringing an existing Docker image from another platform.

```python theme={null}
from fal.container import ContainerImage

class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
        RUN apt-get update && apt-get install -y ffmpeg
        RUN pip install diffusers transformers
    """)
```

You can also pull from private registries (Docker Hub, Google Artifact Registry, AWS ECR) with authentication. See [Custom Container Images](/documentation/development/use-custom-container-image) for the full Dockerfile reference and [Private Registries](/documentation/development/private-registries) for registry authentication setup.

## Which Should I Use?

| Situation                                  | Recommended                                                                                   |
| ------------------------------------------ | --------------------------------------------------------------------------------------------- |
| New Python model with pip packages         | [fal Runtime](/documentation/development/fal-runtime)                                         |
| Need system packages (ffmpeg, imagemagick) | [Custom Container](/documentation/development/use-custom-container-image)                     |
| Specific CUDA or PyTorch version           | [Custom Container](/documentation/development/use-custom-container-image)                     |
| Migrating an existing Docker server        | [Custom Container + exposed\_port](/documentation/development/migrate-external-docker-server) |
| Non-Python runtime (Node.js, Go, etc.)     | [Custom Container](/documentation/development/use-custom-container-image)                     |
| Local modules or git repositories          | [fal Runtime + Import Code](/documentation/development/import-code)                           |


# https://fal.ai/docs/documentation/development/docker-templates.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker Templates and Best Practices

> Production-ready Dockerfile templates and optimization tips for fal Serverless.

This page provides ready-to-use Dockerfile templates for common deployment patterns and covers best practices for building efficient container images on fal. If you are new to custom containers on fal, start with [Use a Custom Container Image](/documentation/development/use-custom-container-image) for the core setup.

For optimizing container images specifically for cold start performance (layer ordering, image size reduction, FlashPack), see [Optimize Container Images](/documentation/serverless/optimizations/optimize-container-images).

## Templates

### Base Python

For applications that only need pip packages and basic system tools.

```dockerfile theme={null}
FROM falai/base:3.11-12.1.0

USER root

RUN apt-get update && apt-get install -y --no-install-recommends \
    git wget curl \
    && rm -rf /var/lib/apt/lists/*

RUN pip install --no-cache-dir \
    requests==2.31.0 \
    numpy==1.24.3

# Install fal last to ensure compatible dependency versions
RUN pip install --no-cache-dir fal
```

### PyTorch and HuggingFace

For deep learning applications using PyTorch and the HuggingFace ecosystem.

```dockerfile theme={null}
FROM falai/base:3.11-12.1.0

RUN pip install --no-cache-dir \
    torch==2.6.0 \
    accelerate==1.6.0 \
    transformers==4.51.3 \
    diffusers==0.31.0 \
    hf_transfer==0.1.9 \
    peft==0.15.0 \
    sentencepiece==0.2.0 \
    --extra-index-url \
    https://download.pytorch.org/whl/cu124

# Install fal last to ensure compatible dependency versions
RUN pip install --no-cache-dir fal

ENV CUDA_HOME=/usr/local/cuda
ENV PATH=$CUDA_HOME/bin:$PATH
ENV LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH
ENV TORCH_CUDA_ARCH_LIST="6.0 6.1 7.0 7.5 8.0 8.6 8.9 9.0 9.0a"
```

### Custom CUDA Version

When you need a specific CUDA runtime that differs from the fal base image.

```dockerfile theme={null}
FROM nvidia/cuda:12.8.0-runtime-ubuntu22.04

ENV DEBIAN_FRONTEND=noninteractive \
    PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

RUN apt-get update && apt-get install -y --no-install-recommends \
    software-properties-common \
    && add-apt-repository ppa:deadsnakes/ppa \
    && apt-get update && apt-get install -y --no-install-recommends \
    python3.11 \
    python3.11-dev \
    python3.11-venv \
    python3-pip \
    wget curl ca-certificates ffmpeg libsndfile1 \
    && rm -rf /var/lib/apt/lists/*

# fal requires the python binary at standard paths
RUN ln -sf /usr/bin/python3.11 /usr/bin/python3 && \
    ln -sf /usr/bin/python3.11 /usr/bin/python

RUN python3 -m pip install --no-cache-dir --upgrade pip

# Install your packages
RUN pip install --no-cache-dir \
    torch==2.7.0 -f https://download.pytorch.org/whl/cu128/torch_stable.html

# Install fal last to ensure compatible dependency versions
RUN pip install --no-cache-dir fal
```

## Best Practices

### Use the fal base image

`falai/base:3.11-12.1.0` comes with the correct Python version, CUDA libraries, and a small image size that reduces container pull times during cold starts.

### Pin all package versions

Unpinned versions can break your app when a new release introduces incompatibilities. Pin everything for reproducible builds.

```dockerfile theme={null}
# Pinned versions - reproducible
RUN pip install torch==2.6.0 transformers==4.51.3

# Unpinned - may break on next deploy
RUN pip install torch transformers
```

### Clean up package caches

Removing caches reduces image size, which speeds up container pulls during cold starts.

```dockerfile theme={null}
RUN apt-get update && apt-get install -y ffmpeg \
    && rm -rf /var/lib/apt/lists/*

RUN pip install --no-cache-dir torch==2.6.0
```

### Use multi-stage builds for smaller images

Separate your build dependencies from your runtime to reduce the final image size.

```dockerfile theme={null}
FROM python:3.11 as builder
COPY requirements.txt .
RUN pip install --user -r requirements.txt

FROM python:3.11-slim
COPY --from=builder /root/.local /root/.local
```

### Store model weights on /data, not in the image

Download model weights to [persistent storage](/documentation/development/use-persistent-storage) (`/data`) in your `setup()` method rather than baking them into the Docker image. This keeps your image small, speeds up container pulls, and allows weights to be cached across runner restarts.

## Common Issues

### Python binary not found

**Problem**: `python: command not found` when using a custom base image.

**Solution**: Create symlinks so fal can find the Python binary:

```dockerfile theme={null}
RUN ln -sf /usr/bin/python3.11 /usr/bin/python3 && \
    ln -sf /usr/bin/python3.11 /usr/bin/python
```

### CUDA not available

**Problem**: `RuntimeError: No CUDA GPUs are available`

**Solution**: Ensure CUDA environment variables are set in your Dockerfile:

```dockerfile theme={null}
ENV CUDA_HOME=/usr/local/cuda
ENV PATH=$CUDA_HOME/bin:$PATH
ENV LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH
```

### Dependency version conflicts

**Problem**: `ImportError` or version conflicts with pydantic, protobuf, or boto3.

**Solution**: Install the `fal` package (or these three packages) as the last `RUN pip install` step in your Dockerfile so they override any conflicting versions installed by earlier layers.


# https://fal.ai/docs/documentation/development/download-model-weights-and-files.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Download Model Weights and Files

> Download model weights, datasets, and external files to your runner using fal toolkit utilities and Hugging Face best practices.

Most AI applications need to download model weights or datasets before they can serve requests. This page covers the fal toolkit utilities for downloading files (`download_file` and `download_model_weights`), as well as best practices for optimizing Hugging Face downloads on fal's infrastructure. All downloaded files should be stored on [persistent storage](/documentation/development/use-persistent-storage) at `/data` so they are cached across runner restarts.

These download operations typically happen inside your [setup()](/documentation/development/app-lifecycle) method, which runs once when a new runner starts. Faster downloads mean shorter cold starts, so the optimization techniques in this guide directly affect your app's responsiveness when scaling up. For broader cold start strategies beyond downloads, see [Optimizing Cold Starts](/documentation/serverless/optimizations/optimize-cold-starts).

## Downloading Files

You can download files from external sources using the `download_file` function. This function handles downloading files from URLs with built-in caching and error handling.

This is particularly useful for downloading datasets, configuration files, or any external resources your application needs.

```python theme={null}
from fal.toolkit import download_file, FAL_PERSISTENT_DIR


class MyApp(fal.App):
    def setup(self):
        path = download_file(
            "https://example.com/myfile.txt",
            FAL_PERSISTENT_DIR / "mydir",
        )
        ...
```

## Downloading Model Weights

You can download model weights from external sources using the `download_model_weights` function. This function is specifically designed for downloading model weights and provides several useful features:

* **Predefined storage location**: Automatically stores weights in an optimized directory structure
* **Smart caching**: Avoids re-downloading weights that are already present unless forced
* **Authentication support**: Supports custom request headers for private repositories

This function is particularly useful for downloading pre-trained model weights from Hugging Face, custom model repositories, or private storage locations.

```python theme={null}
from fal.toolkit import download_model_weights


class MyApp(fal.App):
    def setup(self):
        path = download_model_weights(
            "https://example.com/myfile.txt",
            # Optional: force download even if the weights are already present
            force=False,
            # Optional: specify request headers
            request_headers={
                "Authorization": "Bearer <token>",
            },
        )
        ...
```

## Improving Hugging Face download speeds

The Hugging Face library caches files locally to prevent duplicate downloads. Within Fal, this cache is automatically placed on the [`/data` persistent volume](./use-persistent-storage) via the `HF_HOME` environment variable that is set to `/data/.cache/huggingface`.

The steps below offer additional speedups.

### Set Hugging Face token

Ensure you have your Hugging Face token set to be used by Fal runs. Authenticated downloads seem to be faster than anonymous ones:

`fal secret set HF_TOKEN=xxx`

### Save weights to the `/data` volume

Hugging Face weights need to be stored within the `/data` volume. This:

* Speeds up runner starts by removing the need for files to be reconstructed from the cache (which is already on `/data`)
* Ensures enough disk space is available

```python theme={null}
snapshot_download(
    repo_id=model_id,
    local_dir="/data/models/deepseek-ai",
    ...
)
```

### Speed up initial weights downloading

Depending on the size of the weights, the initial call to `snapshot_download` can take a while.

Hugging Face seems to reduce download speeds for large models after some time. While individual transfer thread often start at 50+ MB/s, after a while the speed drops to 5-6 MB/s.

There are 3 ways to speed up downloads:

* Increase concurrency, `max_workers` and cache size:

  ```python theme={null}
  os.environ["HF_XET_HIGH_PERFORMANCE"] = "1"
  os.environ["HF_XET_CHUNK_CACHE_SIZE_BYTES"] = "1000000000000"
  os.environ["HF_XET_NUM_CONCURRENT_RANGE_GETS"] = "32"

  snapshot_download(
      repo_id=model_id,
      local_dir=model_dir,
      max_workers=32
  )
  ```

* Download many models in parallel: when downloading multiple models, it helps to start a separate Fal run for each one. The different source IP address reduces the risk of rate limiting.

* Restart slow downloads: restart the run after e.g. 10 minutes, which will likely cause it to go to a different physical server, and the download will resume at higher speeds.

### Speed up model files check

Even after fully caching weights, calling `snapshot_download` with a large model can sometimes take 45+ seconds.

The Hugging Face library takes this time to do API calls and metadata checks. You can use `local_files_only=True` to skip this step, which typically makes the call return in less than 1 second.

Using `local_files_only=True` will throw an error if the files are not completely cached. To prevent that, it is a good idea to wrap the call in a try/catch block and retry it without `local_files_only`:

```python theme={null}
from huggingface_hub.errors import LocalEntryNotFoundError

try:
    snapshot_download(
        ...
        local_files_only=True,
    )
except LocalEntryNotFoundError:
    snapshot_download(
        ...
    )
```

### Speed up model loads

Hugging face models are typically split into multiple files, and loading them happens serially. This is sub-optimal if the files are not cached locally as they will be fetched one by one.

It is advisable to pre-read all the files in parallel which will create missing caches concurrently, at much higher speeds.

Please refer to [Sequential vs parallel reading](./use-persistent-storage#sequential-vs-parallel-reading).

## Caching Compiled Kernels

Once your model weights are stored on `/data`, you can also cache compiled PyTorch kernels to `/data/inductor-caches/`. This is particularly useful for models using `torch.compile()`, as it avoids recompiling kernels on every worker startup.

<Tip>
  Learn how to share compiled kernels across workers in [Optimize Startup with Compiled Caches](/documentation/serverless/optimizations/optimize-startup-with-compiled-caches).
</Tip>


# https://fal.ai/docs/documentation/development/endpoints-overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Define Your Endpoints

> How to define, structure, and configure the API endpoints your fal App exposes to callers.

Every [fal App](/documentation/getting-started/apps-and-execution) exposes one or more endpoints that callers interact with through the fal client SDKs or REST API. An endpoint is a Python method decorated with `@fal.endpoint("/path")` that receives input, runs your model or logic, and returns output. The simplest app has a single root endpoint at `/`, but you can define as many endpoints as you need at different paths, including specialized [streaming](/documentation/development/streaming) and [real-time](/documentation/development/realtime) endpoints for progressive and bidirectional communication.

This section covers everything involved in building endpoints, from defining input and output schemas to handling files, cancellations, and observability. If you have already set up your [application environment](/documentation/development/app-setup) and [loaded your model](/documentation/development/download-model-weights-and-files), this is where you define how users interact with it. Each page below focuses on a specific aspect of endpoint development. Start with a basic endpoint, then layer on the capabilities you need.

## A Basic Endpoint

At minimum, an endpoint is a method on your `fal.App` class decorated with `@fal.endpoint`. It receives typed input and returns typed output. The types you use determine both the API schema and how the [Playground](/documentation/model-apis/playground) renders the input form and output preview.

```python theme={null}
import fal
from pydantic import BaseModel

class Input(BaseModel):
    prompt: str

class Output(BaseModel):
    text: str

class MyApp(fal.App):
    machine_type = "GPU-A100"

    def setup(self):
        self.model = load_model()

    @fal.endpoint("/")
    def generate(self, input: Input) -> Output:
        result = self.model(input.prompt)
        return Output(text=result)
```

You can define multiple endpoints on the same app at different paths. Callers reach non-root endpoints by appending the path to the endpoint URL (e.g., `https://fal.run/your-username/your-app/enhance`).

```python theme={null}
class MyApp(fal.App):
    @fal.endpoint("/")
    def generate(self, input: GenerateInput) -> GenerateOutput:
        ...

    @fal.endpoint("/enhance")
    def enhance(self, input: EnhanceInput) -> EnhanceOutput:
        ...
```

## What's in This Section

The pages below cover each aspect of endpoint development. [Handle Inputs and Outputs](/documentation/development/handle-inputs-and-outputs) explains how to define Pydantic schemas that control both API validation and how the Playground renders your input form and output preview. [Working with Files](/documentation/development/working-with-files) covers downloading input files and uploading generated outputs to the CDN at runtime.

For progressive output, [Streaming](/documentation/development/streaming) shows how to send partial results to clients via Server-Sent Events. For bidirectional communication with persistent connections, see [Realtime](/documentation/development/realtime). [Testing](/documentation/development/test-models-and-endpoints) covers automated endpoint testing and CI setup, [Health Checks](/documentation/development/add-health-check-endpoint) let fal detect and replace unhealthy runners, and [Cancellations](/documentation/development/handle-cancellations) show how to free GPU resources when callers cancel in-flight requests.


# https://fal.ai/docs/documentation/development/environment-variables.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment Variables

> Built-in environment variables that fal injects into every runner, covering authentication, app identity, region, lifecycle state, and storage.

fal automatically injects several environment variables into every [runner](/documentation/deployment/runners) when it starts. These provide your app with authentication credentials, identity information, lifecycle state, and storage paths without any configuration. You access them via `os.getenv()` just like any other environment variable.

These platform variables are separate from your own [secrets](/documentation/development/manage-secrets-securely), which you configure manually and which are also injected as environment variables. Platform variables are always present on every runner; secrets are specific to what you've set. Both are available at runtime (in `setup()` and endpoint handlers) but not during the image build stage.

```python theme={null}
import os
import fal

class MyApp(fal.App):
    def setup(self):
        app_name = os.getenv("FAL_APP_NAME")
        job_id = os.getenv("FAL_JOB_ID")
        print(f"Setting up {app_name} on runner {job_id}")
```

***

## Authentication

| Variable  | Description                                                                                                                                                                |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FAL_KEY` | An auto-generated API key scoped to your account, formatted as `key_id:key_secret`. Use this to call other fal models from within your app without hardcoding credentials. |

The `FAL_KEY` variable is set automatically when your app runs with privileged access (the default for deployed apps). The fal client SDKs read it automatically, so you can call other fal endpoints without any additional configuration.

```python theme={null}
import fal_client

class MyApp(fal.App):
    @fal.endpoint("/")
    def run(self, prompt: str):
        result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
            "prompt": prompt
        })
        return result
```

<Warning>
  `FAL_KEY` is scoped to **your account** (the app owner). Any fal API calls made with this key are billed to you, not to the end user calling your app. If your app chains calls to marketplace models, you pay for those calls on top of your own runner costs.
</Warning>

<Note>
  `FAL_KEY` is not available during the image build stage. It is only injected at runtime.
</Note>

***

## App Identity

| Variable            | Description                                                |
| ------------------- | ---------------------------------------------------------- |
| `FAL_APP_NAME`      | Your application's full alias (e.g., `your-user/my-model`) |
| `FAL_APP_ID`        | Your application's unique identifier                       |
| `FAL_USER_NICKNAME` | Your account username                                      |
| `FAL_JOB_ID`        | The current runner's unique job ID                         |
| `FAL_HOST`          | The fal API host (e.g., `api.fal.ai`)                      |
| `FAL_REGION`        | The region where the runner is executing (e.g., `us-east`) |

These are useful for structured logging, metrics tagging, and conditional logic. For example, you might log the runner ID and region with every request so you can correlate issues in the [dashboard](/documentation/serverless/observability/monitor-performance).

```python theme={null}
import os
import logging

class MyApp(fal.App):
    def setup(self):
        self.logger = logging.getLogger(os.getenv("FAL_APP_NAME", "app"))
        self.logger.info(
            f"Runner {os.getenv('FAL_JOB_ID')} starting in {os.getenv('FAL_REGION')}"
        )
```

***

## Lifecycle

| Variable           | Values                            | Description                                 |
| ------------------ | --------------------------------- | ------------------------------------------- |
| `FAL_RUNNER_STATE` | `SETUP`, `RUNNING`, `TERMINATING` | The current phase of the runner's lifecycle |

fal sets this variable at each stage of the [runner lifecycle](/documentation/development/app-lifecycle): `SETUP` during `setup()`, `RUNNING` while serving requests, and `TERMINATING` after a shutdown signal is received. You can read it to make decisions in shared code paths, but for handling shutdown gracefully, use the [`handle_exit()` and `teardown()` methods](/documentation/development/app-lifecycle) on your App class instead of raw signal handlers.

```python theme={null}
import os

class MyApp(fal.App):
    @fal.endpoint("/")
    def run(self) -> dict:
        state = os.getenv("FAL_RUNNER_STATE")
        return {"runner_state": state}

    def handle_exit(self):
        print("Shutdown signal received, stopping early")

    def teardown(self):
        print("Cleaning up resources")
```

***

## Storage

| Variable  | Value                      | Description                                                                                                                   |
| --------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `HF_HOME` | `/data/.cache/huggingface` | Hugging Face cache directory, persisted across runners via [/data storage](/documentation/development/use-persistent-storage) |

fal sets `HF_HOME` to a path on the [persistent /data filesystem](/documentation/development/use-persistent-storage) so that Hugging Face models are automatically cached across runner restarts. The first runner downloads the model weights, and subsequent runners reuse the cached files without re-downloading.

```python theme={null}
from transformers import AutoModel

class MyApp(fal.App):
    def setup(self):
        self.model = AutoModel.from_pretrained("bert-base-uncased")
```

***

## User Secrets

Any [secrets](/documentation/development/manage-secrets-securely) you configure are also injected as environment variables alongside the platform variables listed above.

<Card title="Managing Secrets" href="/documentation/development/manage-secrets-securely">
  Set, update, and scope secrets per environment via CLI, Dashboard, or Python SDK
</Card>


# https://fal.ai/docs/documentation/development/fal-runtime.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal Runtime

> How to use fal's managed Python runtime to run your models.

The fal runtime is the recommended way to define your app's environment. Instead of writing a Dockerfile, you list your pip dependencies in the `requirements` attribute and fal builds an optimized, cached environment for you. This approach handles CUDA setup, PyTorch index URLs, and environment isolation automatically based on your chosen [machine type](/documentation/deployment/machine-types).

If you need system-level packages, a specific base image, or a non-Python runtime, use a [custom container](/documentation/development/use-custom-container-image) instead. If you need to include local Python modules or clone external repositories, see [Import Code](/documentation/development/import-code). For an overview of when to use which approach, see [Environment and Runtime](/documentation/development/container-setup).

## Defining Requirements

The `requirements` attribute in your `fal.App` class is where you specify the Python packages your model needs. fal ensures these are installed in the [runner's](/documentation/deployment/runners) environment before [setup()](/documentation/development/app-lifecycle#runner-startup) is called.

```python theme={null}
import fal

class MyModel(fal.App):
    machine_type = "GPU-A100"
    
    requirements = [
        "torch==2.4.0",
        "transformers",
        "diffusers",
        "accelerate"
    ]
    
    def setup(self):
        import torch
        ...
```

Pin your package versions (e.g., `torch==2.4.0`) to ensure reproducible builds. Use the `requirements` attribute instead of running `pip install` inside `setup()`, since packages in `requirements` are installed during the container build and cached across deploys. Only include the packages your app actually needs to keep startup times short.

When you deploy, fal creates an isolated environment based on your `machine_type`, installs your listed packages, and caches the resulting container image. On subsequent deploys, unchanged requirements are served from cache. Your `setup()` method then runs on the provisioned runner to load the model into memory.

## Using Prebuilt Wheels

You can install packages directly from wheel URLs. This is useful for custom-built packages or packages not available on PyPI.

### Direct URL

Provide the full URL to a wheel file:

```python theme={null}
requirements = [
    "https://your-storage.example.com/wheels/mypackage-1.0.0-cp311-cp311-linux_x86_64.whl",
]
```

### Package @ URL (PEP 440)

Use the `package@url` syntax to give the package a name for dependency resolution:

```python theme={null}
requirements = [
    "mypackage@https://your-storage.example.com/wheels/mypackage-1.0.0-cp311-cp311-linux_x86_64.whl",
]
```

This syntax is recommended when other packages depend on `mypackage`, as pip can properly track the dependency.

## Alternative Package Indexes

Use `--extra-index-url` or `--find-links` to install packages from alternative sources.

### Extra Index URL

Install packages from an additional PyPI-compatible index:

```python theme={null}
requirements = [
    "torch==2.5.0",
    "--extra-index-url",
    "https://download.pytorch.org/whl/cu124",
]
```

<Warning>
  The `--extra-index-url` flag must appear **before** any packages that need it. Place index flags at the beginning or directly before the relevant packages.
</Warning>

### Find Links

Use `--find-links` to search for packages in a directory or URL containing wheel files:

```python theme={null}
requirements = [
    "mypackage",
    "--find-links",
    "https://github.com/your-org/releases/download/v1.0.0/",
]
```

### Multiple Indexes

Combine multiple index sources when needed:

```python theme={null}
requirements = [
    "--extra-index-url",
    "https://download.pytorch.org/whl/cu124",
    "--extra-index-url",
    "https://your-company.example.com/simple",
    "torch==2.5.0",
    "your-internal-package==1.0.0",
]
```

## Private Packages

### Private Git Repositories

Install directly from a private GitHub repository using a personal access token:

```python theme={null}
requirements = [
    "git+https://YOUR_TOKEN@github.com/your-org/private-repo.git",
]
```

Pin to a specific commit or tag for reproducibility:

```python theme={null}
requirements = [
    "git+https://YOUR_TOKEN@github.com/your-org/private-repo.git@v1.0.0",
    "git+https://YOUR_TOKEN@github.com/your-org/private-repo.git@abc123def",
]
```

<Warning>
  **Security Consideration**: Tokens embedded in requirements are visible in your code. For better security:

  * Use short-lived tokens when possible
  * Consider hosting wheels on a storage service with pre-signed URLs
  * Use [fal secrets](/documentation/development/manage-secrets-securely) for sensitive values in your app code
</Warning>

### Private PyPI Index

Install from a private PyPI server with authentication:

```python theme={null}
requirements = [
    "--extra-index-url",
    "https://username:password@pypi.your-company.com/simple",
    "your-private-package==1.0.0",
]
```

### Pre-signed URLs

For private storage (S3, GCS, etc.), generate a pre-signed URL with an expiration time:

```python theme={null}
requirements = [
    "https://your-bucket.s3.amazonaws.com/wheels/mypackage-1.0.0.whl?AWSAccessKeyId=...&Signature=...&Expires=...",
]
```

## Dynamic Wheel Selection

When you need different wheels for different Python versions or platforms, use a helper function:

```python theme={null}
def get_package_wheel():
    import sys
    wheels = {
        10: "https://example.com/wheels/mypackage-1.0.0-cp310-cp310-linux_x86_64.whl",
        11: "https://example.com/wheels/mypackage-1.0.0-cp311-cp311-linux_x86_64.whl",
    }
    return wheels[sys.version_info.minor]


class MyApp(fal.App):
    machine_type = "GPU-A100"
    requirements = [
        "torch==2.5.0",
        get_package_wheel(),
    ]
```

<Note>
  Helper functions are evaluated at deploy time on your local machine, so they have access to local environment variables and can make decisions based on the target Python version.
</Note>

***

<Card title="Importing Local Code" href="/documentation/development/import-code">
  Learn how to bring your local Python modules and files into the fal runtime.
</Card>


# https://fal.ai/docs/documentation/development/getting-started/deploy-your-first-image-generator.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Your First Image Generator

> Deploy a text-to-image AI model in under 5 minutes. This tutorial walks you through creating your own image generation API using Stable Diffusion XL.

This tutorial builds on the [Quick Start](/documentation/development/getting-started/quick-start) by deploying a real AI model. You will create a text-to-image API powered by Stable Diffusion XL that runs on GPU infrastructure, loads model weights from Hugging Face, and returns generated images through a typed Pydantic schema. The result is a production-ready endpoint with a [Playground](/documentation/model-apis/playground) for browser-based testing.

Along the way, you will encounter several concepts that are central to building Serverless apps: the [setup()](/documentation/development/app-lifecycle) hook for one-time model loading, the [keep\_alive](/documentation/deployment/scale-your-application) parameter for controlling runner lifetime, pip [requirements](/documentation/development/fal-runtime) for environment setup, and the [fal.toolkit.Image](/documentation/development/handle-inputs-and-outputs#image-output) class for returning media outputs. If any of these are new to you, the [Serverless Introduction](/documentation/serverless) provides a quick overview.

## Before You Start

You'll need:

* Python - we recommend 3.11
* A [fal account](https://fal.ai/dashboard) (sign up is free)
* Basic familiarity with Python and AI models

## Step 1: Install the CLI

If you haven't already:

```bash theme={null}
pip install fal
```

## Step 2: Authenticate

Get your API key from the [fal dashboard](https://fal.ai/dashboard) and authenticate:

```bash theme={null}
fal auth login
```

This opens your browser to authenticate with fal. Once complete, your credentials are saved locally.

## Step 3: Create Your Image Generator

Create a file called `image_generator.py` with this Stable Diffusion XL text-to-image model:

```python theme={null}
import fal
from pydantic import BaseModel, Field
from fal.toolkit import Image

class Input(BaseModel):
    prompt: str = Field(
        description="The prompt to generate an image from",
        examples=["A beautiful image of a cat"],
    )

class Output(BaseModel):
    image: Image

class MyApp(fal.App):
    keep_alive = 300
    app_name = "my-demo-app"
    machine_type = "GPU-H100"
    requirements = [
        "hf-transfer==0.1.9",
        "diffusers[torch]==0.32.2",
        "transformers[sentencepiece]==4.51.0",
        "accelerate==1.6.0",
    ]

    def setup(self):
        # Enable HF Transfer for faster downloads
        import os

        os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"

        import torch
        from diffusers import StableDiffusionXLPipeline

        # Load any model you want, we'll use stabilityai/stable-diffusion-xl-base-1.0
        # Huggingface models will be automatically downloaded to
        # the persistent storage of your account (/data)
        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
            variant="fp16",
            use_safetensors=True,
        ).to("cuda")

        # Warmup the model before the first request
        self.warmup()

    def warmup(self):
        self.pipe("A beautiful image of a cat")

    @fal.endpoint("/")
    def run(self, request: Input) -> Output:
        result = self.pipe(request.prompt)
        image = Image.from_pil(result.images[0])
        return Output(image=image)
```

## Step 4: Test Your Image Generator

Run your model to test it:

```bash theme={null}
fal run image_generator.py::MyApp
```

This starts your app, downloads the Stable Diffusion XL model weights (cached after the first run), and prints two URLs: a direct HTTP endpoint and a web playground. The first run takes a couple of minutes for the model download. Subsequent runs are faster.

Once you see `Application startup complete`, test it with curl using the URL from the output:

```bash theme={null}
curl $FAL_RUN_URL -H 'Content-Type: application/json' \
  -d '{"prompt":"A cyberpunk cityscape at night with neon lights"}'
```

You can also use the playground URL to test through a browser interface.

## Step 5: Deploy Your Model

Once you are satisfied with the results, deploy your app to create a persistent URL. Deployed apps scale automatically, with [runners](/documentation/deployment/runners) managed by fal's infrastructure. You can configure scaling behavior through parameters like `keep_alive`, `min_concurrency`, and `max_concurrency`. See [Scale Your Application](/documentation/deployment/scale-your-application) to learn more.

```bash theme={null}
fal deploy image_generator.py::MyApp
```

## Step 6: Call Your Deployed App

Once deployed, call your image generator from any Python or JavaScript application using the fal client SDK.

<Tabs>
  <Tab title="Python">
    ```bash theme={null}
    pip install fal-client
    ```

    ```python theme={null}
    import fal_client

    result = fal_client.subscribe(
        "your-username/my-demo-app",
        arguments={"prompt": "A cyberpunk cityscape at night with neon lights"},
    )
    print(result["image"]["url"])
    ```
  </Tab>

  <Tab title="JavaScript">
    ```bash theme={null}
    npm install @fal-ai/client
    ```

    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const result = await fal.subscribe("your-username/my-demo-app", {
      input: { prompt: "A cyberpunk cityscape at night with neon lights" },
    });
    console.log(result.data.image.url);
    ```
  </Tab>
</Tabs>

Replace `your-username/my-demo-app` with the endpoint ID shown after deploying. See [Calling Your Endpoints](/documentation/development/calling-your-endpoints) for all calling patterns including async queue, streaming, real-time, and webhooks.

## Next Steps

The [App Lifecycle](/documentation/development/app-lifecycle) page explains how apps are structured, where code runs, and how runners start up and shut down. To define richer input and output schemas (sliders, image uploads, multiple outputs), see [Handle Inputs and Outputs](/documentation/development/handle-inputs-and-outputs). For all the ways to call your deployed app from client code, including async queue, streaming, and real-time patterns, see [Calling Your Endpoints](/documentation/development/calling-your-endpoints).


# https://fal.ai/docs/documentation/development/getting-started/installation.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation & Setup

> Complete setup guide for the fal CLI and development environment. This guide covers all platforms and authentication methods.

The fal CLI is the primary tool for developing, testing, and deploying Serverless applications. This page covers installing the CLI, authenticating with your account, and switching between team contexts. By the end, you will have a working development environment ready for the [Quick Start](/documentation/development/getting-started/quick-start).

If you are only using [Model APIs](/documentation/model-apis/overview) to call pre-trained models, you do not need the CLI. You only need an [API key](/documentation/model-apis/authentication/index) and the client SDK (`fal-client` for Python or `@fal-ai/client` for JavaScript). The CLI is specifically for the Serverless workflow: writing, testing, and deploying your own apps. For an overview of how accounts, keys, and profiles relate to each other, see [Accounts and Identity](/documentation/setting-up/accounts-and-identity).

## System Requirements

* **Python**: 3.8 or later
* **Operating System**: macOS, Linux, or Windows

## Install the CLI

### Using pip

```bash theme={null}
pip install fal
```

### Verify Installation

Check that the CLI installed correctly:

```bash theme={null}
fal --version
```

You should see the version number printed.

## Authentication

### Option 1: Interactive Login (Recommended)

```bash theme={null}
fal auth login
```

This opens your browser to authenticate with fal. Once complete, your credentials are saved locally.

<Tip>
  If you are a member of multiple teams, the login process will prompt you to select which team account you want to use as your default. This affects which resources you can access and deploy to.
</Tip>

### Option 2: API Key

Create an API key at [API Keys](https://fal.ai/dashboard/keys) with the `ADMIN` scope. If creating a key for a team, make sure to select your team on the top left corner.

Set it as an environment variable:

```bash theme={null}
export FAL_KEY="your-api-key-here"
```

Or add it to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.) to persist across sessions.

If you work with multiple API keys (for example, personal and team accounts), you can use `fal profile` to save keys and switch between them. See the [Accounts and Identity](/documentation/setting-up/accounts-and-identity#switching-accounts) page for details on profiles versus team switching.

## Team Accounts

After authentication, you can switch between different teams or your personal account using the `fal team` command.

### View Available Teams

To list teams that you are a member of:

```bash theme={null}
fal team list
```

| Default | Team      | Full Name  | ID                               |
| ------- | --------- | ---------- | -------------------------------- |
| \*      | myteam    | My Team    | github\|1kbr8zjkk377xfs5tl2erl4x |
|         | otherteam | Other Team | github\|v11vo11w2kqakm99ke00258q |

The `*` indicates your currently active team.

### Switch Teams

To switch to a different team:

```bash theme={null}
fal team set otherteam
```

To switch back to your personal account:

```bash theme={null}
fal team unset
```

## Verify Authentication

Test your authentication setup:

```bash theme={null}
fal auth whoami
```

This should display your account information, including your current team (if any). Example output:

```
User: john@example.com
Team: myteam (My Team)
```

If you see an error, double-check your authentication method and API key configuration.

## Upgrading

Keep your CLI up to date:

```bash theme={null}
pip install --upgrade fal
```

Check for breaking changes in the [changelog](https://github.com/fal-ai/fal/releases).

## Getting Help

If you run into issues, `fal --help` and `fal COMMAND --help` provide inline documentation for every command. For community support, join the [fal Discord](https://discord.gg/fal-ai). To report bugs or request features, open an issue on [GitHub](https://github.com/fal-ai/fal/issues).


# https://fal.ai/docs/documentation/development/getting-started/quick-start.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start - Hello World

> Deploy your first fal app in under 2 minutes. Learn the basics with a simple Hello World example.

This guide walks you through building and deploying a Hello World app on fal Serverless. By the end, you will have a working app running on cloud infrastructure with a persistent URL, a [Playground](/documentation/model-apis/playground) for browser-based testing, and client SDK code you can copy into any project. The entire process takes about two minutes.

The workflow you will learn here is the same one you will use for every fal app, from simple utilities to production AI models. You write a Python class, test it with `fal run`, deploy it with `fal deploy`, and call it with the [fal client SDK](/documentation/development/calling-your-endpoints). Once you are comfortable with this loop, the [Deploy Your First Image Generator](/documentation/development/getting-started/deploy-your-first-image-generator) tutorial shows how to apply it to a real Stable Diffusion XL model.

## Before You Start

You'll need:

* Python - we recommend 3.11
* A [fal account](https://fal.ai/dashboard) (sign up is free)

## Step 1: Install the CLI

```bash theme={null}
pip install fal
```

## Step 2: Authenticate

Get your API key from the [fal dashboard](https://fal.ai/dashboard) and authenticate:

```bash theme={null}
fal auth login
```

This opens your browser to authenticate with fal. Once complete, your credentials are saved locally.

## Step 3: Create Your First App

Create a file called `hello_world.py` with this simple app:

```python theme={null}
import fal

class MyApp(fal.App):
    @fal.endpoint("/")
    def run(self) -> dict:
        print("Processing Hello World request...")
        return {"message": "Hello, World!"}
```

## Step 4: Test Your App Locally

Run your app to test it:

```bash theme={null}
fal run hello_world.py::MyApp
```

This starts your app and prints two URLs: a direct HTTP endpoint and a web playground. By default, `fal run` uses `public` auth mode so you can test without an API key.

<Tip>
  Use `--auth private` if you want to require API key authentication during development. See [Authentication Modes](/documentation/deployment/deploy-to-production#authentication-modes) for details.
</Tip>

Once you see `Application startup complete`, test it with curl using the URL from the output:

```bash theme={null}
curl $FAL_RUN_URL -H 'Content-Type: application/json' -d '{}'
```

```json theme={null}
{"message": "Hello, World!"}
```

You can also use the playground URL to test through a browser interface.

## Step 5: Deploy Your App

Once you are satisfied, deploy to create a persistent URL:

```bash theme={null}
fal deploy hello_world.py::MyApp
```

This deploys your app to fal's infrastructure with runners managed automatically based on demand. The output includes your app's endpoint ID and persistent URL.

## Step 6: Call Your Deployed App

Once deployed, you can call your app from any Python or JavaScript application using the fal client SDK.

<Tabs>
  <Tab title="Python">
    ```bash theme={null}
    pip install fal-client
    ```

    ```python theme={null}
    import fal_client

    result = fal_client.subscribe("your-username/hello-world", arguments={})
    print(result)
    # {"message": "Hello, World!"}
    ```
  </Tab>

  <Tab title="JavaScript">
    ```bash theme={null}
    npm install @fal-ai/client
    ```

    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const result = await fal.subscribe("your-username/hello-world", {
      input: {},
    });
    console.log(result.data);
    // { message: "Hello, World!" }
    ```
  </Tab>
</Tabs>

Replace `your-username/hello-world` with the endpoint ID shown after deploying. See [Calling Your Endpoints](/documentation/development/calling-your-endpoints) for all calling patterns including async queue, streaming, real-time, and webhooks.

## Next Steps

From here, the [Deploy Your First Image Generator](/documentation/development/getting-started/deploy-your-first-image-generator) tutorial applies the same workflow to a real Stable Diffusion XL model. To understand how apps are structured and how runners start up and shut down, read [App Lifecycle](/documentation/development/app-lifecycle). For all the ways to call your deployed app, including async queue, streaming, real-time, and webhooks, see [Calling Your Endpoints](/documentation/development/calling-your-endpoints).


# https://fal.ai/docs/documentation/development/handle-cancellations.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Handle Request Cancellations

> Handle in-flight request cancellations to free GPU resources when callers cancel queued or processing requests.

When a caller [cancels a request](/documentation/model-apis/inference/queue#cancel-a-request) through the queue API, fal handles it differently depending on the request's state. If the request is still waiting in the [queue](/documentation/model-apis/inference/queue), it is removed and never processed. If a runner is already processing the request, fal sends a cancellation signal to your app so you can stop work, release GPU resources, and leave the app in a clean state.

For direct connections ([`run()`](/documentation/model-apis/inference/synchronous), [streaming](/documentation/model-apis/inference/streaming), and [real-time](/documentation/model-apis/inference/real-time)), cancellation also triggers automatically when the caller drops the HTTP or WebSocket connection -- for example, if their process crashes or the connection times out. This does not apply to queue-based requests ([`submit()`](/documentation/model-apis/inference/queue), [`subscribe()`](/documentation/model-apis/inference/synchronous)), where the connection closes after submission and only an explicit cancel API call can stop the request.

Without cancellation handling, a cancelled request continues consuming GPU time until it finishes naturally. For long-running operations like video generation or training, this can waste significant compute. By implementing a cancel endpoint, you give fal a way to tell your running code to stop early, so the runner can move on to the next request.

## How Cancellation Works

fal routes cancellation requests to your endpoint's path with a `/cancel` suffix. For an endpoint at `/predict`, the cancellation arrives at `/predict/cancel`. Both the original request and the cancellation carry the same `x-fal-request-id` header, which you use to match the cancellation to the right in-flight task.

<Steps>
  <Step title="Caller submits a request">
    fal assigns a `request_id` and routes the request to a runner. The caller receives the request handle.

    <CodeGroup>
      ```python Python theme={null}
      handler = fal_client.submit("your-username/your-app", arguments={"prompt": "a sunset"})
      print(handler.request_id)
      ```

      ```javascript JavaScript theme={null}
      const { request_id } = await fal.queue.submit("your-username/your-app", {
        input: { prompt: "a sunset" },
      });
      ```
    </CodeGroup>
  </Step>

  <Step title="Your endpoint begins processing">
    The runner calls your endpoint. You wrap the work in an `asyncio.Task` and store it by request ID so the cancel endpoint can find it later.

    ```python focus={9-19} theme={null}
    class MyApp(fal.App):
        def setup(self):
            self._tasks: dict[str, asyncio.Task] = {}

        async def _generate(self, input: GenerateInput):
            await asyncio.sleep(30)
            return {"result": f"Generated from: {input.prompt}"}

        @fal.endpoint("/predict")
        async def predict(
            self,
            input: GenerateInput,
            x_fal_request_id: str | None = fastapi.Header(None),
        ):
            if not x_fal_request_id:
                raise ValueError("x-fal-request-id is required")

            task = asyncio.create_task(self._generate(input))
            self._tasks[x_fal_request_id] = task
            try:
                return await task
            except asyncio.CancelledError:
                print(f"Request {x_fal_request_id} was cancelled")
                raise RequestCancelledException("Request cancelled")
            finally:
                self._tasks.pop(x_fal_request_id, None)

        @fal.endpoint("/predict/cancel")
        async def predict_cancel(
            self,
            x_fal_request_id: str | None = fastapi.Header(None),
        ):
            if not x_fal_request_id:
                raise ValueError("x-fal-request-id is required")

            task = self._tasks.get(x_fal_request_id)
            if task is None:
                raise ValueError("No task found for this request ID")

            if task.done():
                raise ValueError("Task has already completed")

            task.cancel()
    ```
  </Step>

  <Step title="Caller cancels the request">
    The caller decides to cancel -- either via the SDK, the REST API, or by disconnecting (for direct connections only).

    <CodeGroup>
      ```python Python theme={null}
      handler.cancel()
      ```

      ```javascript JavaScript theme={null}
      await fal.queue.cancel("your-username/your-app", {
        requestId: request_id,
      });
      ```

      ```bash cURL theme={null}
      curl -X PUT "https://queue.fal.run/your-username/your-app/requests/{request_id}/cancel" \
        -H "Authorization: Key $FAL_KEY"
      ```
    </CodeGroup>
  </Step>

  <Step title="fal calls your cancel endpoint">
    fal tracks which endpoint path each request was sent to. When a cancel arrives, it looks up the original path and appends `/cancel`. So if the request was routed to `/predict`, fal sends the cancellation to `/predict/cancel` on the same runner, with the same `x-fal-request-id` header. Your cancel endpoint looks up the task and cancels it.

    ```python focus={28-43} theme={null}
    class MyApp(fal.App):
        def setup(self):
            self._tasks: dict[str, asyncio.Task] = {}

        async def _generate(self, input: GenerateInput):
            await asyncio.sleep(30)
            return {"result": f"Generated from: {input.prompt}"}

        @fal.endpoint("/predict")
        async def predict(
            self,
            input: GenerateInput,
            x_fal_request_id: str | None = fastapi.Header(None),
        ):
            if not x_fal_request_id:
                raise ValueError("x-fal-request-id is required")

            task = asyncio.create_task(self._generate(input))
            self._tasks[x_fal_request_id] = task
            try:
                return await task
            except asyncio.CancelledError:
                print(f"Request {x_fal_request_id} was cancelled")
                raise RequestCancelledException("Request cancelled")
            finally:
                self._tasks.pop(x_fal_request_id, None)

        @fal.endpoint("/predict/cancel")
        async def predict_cancel(
            self,
            x_fal_request_id: str | None = fastapi.Header(None),
        ):
            if not x_fal_request_id:
                raise ValueError("x-fal-request-id is required")

            task = self._tasks.get(x_fal_request_id)
            if task is None:
                raise ValueError("No task found for this request ID")

            if task.done():
                raise ValueError("Task has already completed")

            task.cancel()
    ```
  </Step>

  <Step title="Your main endpoint handles the cancellation">
    Back in step 2, the `await task` now raises `CancelledError`. Your main endpoint catches it and raises `RequestCancelledException` to signal to fal that the cancellation was handled cleanly (returns a 499 status code). The `finally` block cleans up the task reference regardless of outcome.

    ```python focus={20-26} theme={null}
    class MyApp(fal.App):
        def setup(self):
            self._tasks: dict[str, asyncio.Task] = {}

        async def _generate(self, input: GenerateInput):
            await asyncio.sleep(30)
            return {"result": f"Generated from: {input.prompt}"}

        @fal.endpoint("/predict")
        async def predict(
            self,
            input: GenerateInput,
            x_fal_request_id: str | None = fastapi.Header(None),
        ):
            if not x_fal_request_id:
                raise ValueError("x-fal-request-id is required")

            task = asyncio.create_task(self._generate(input))
            self._tasks[x_fal_request_id] = task
            try:
                return await task
            except asyncio.CancelledError:
                print(f"Request {x_fal_request_id} was cancelled")
                raise RequestCancelledException("Request cancelled")
            finally:
                self._tasks.pop(x_fal_request_id, None)

        @fal.endpoint("/predict/cancel")
        async def predict_cancel(
            self,
            x_fal_request_id: str | None = fastapi.Header(None),
        ):
            if not x_fal_request_id:
                raise ValueError("x-fal-request-id is required")

            task = self._tasks.get(x_fal_request_id)
            if task is None:
                raise ValueError("No task found for this request ID")

            if task.done():
                raise ValueError("Task has already completed")

            task.cancel()
    ```
  </Step>
</Steps>

<Note>
  Cancellation is cooperative. If your task is blocked on a synchronous GPU operation (like a PyTorch inference call), the cancellation won't take effect until the operation completes and Python checks for the cancel signal. For long-running synchronous operations, consider breaking them into checkpoints where you can check for cancellation.
</Note>

`RequestCancelledException` is a special exception from `fal.exceptions` that returns a 499 status code to fal, signaling that the cancellation was handled cleanly. This tells the gateway that the runner is in a good state and can accept new requests. If you let `CancelledError` propagate unhandled instead, FastAPI returns a 500 error, which does not terminate the runner but does not cleanly signal that cancellation was handled either.

## Full Example

```python theme={null}
import asyncio

import fal
from fal.exceptions import RequestCancelledException
import fastapi
from pydantic import BaseModel


class GenerateInput(BaseModel):
    prompt: str


class MyApp(fal.App):
    def setup(self):
        self._tasks: dict[str, asyncio.Task] = {}

    async def _generate(self, input: GenerateInput):
        await asyncio.sleep(30)
        return {"result": f"Generated from: {input.prompt}"}

    @fal.endpoint("/predict")
    async def predict(
        self,
        input: GenerateInput,
        x_fal_request_id: str | None = fastapi.Header(None),
    ):
        if not x_fal_request_id:
            raise ValueError("x-fal-request-id is required")

        task = asyncio.create_task(self._generate(input))
        self._tasks[x_fal_request_id] = task
        try:
            return await task
        except asyncio.CancelledError:
            print(f"Request {x_fal_request_id} was cancelled")
            raise RequestCancelledException("Request cancelled")
        finally:
            self._tasks.pop(x_fal_request_id, None)

    @fal.endpoint("/predict/cancel")
    async def predict_cancel(
        self,
        x_fal_request_id: str | None = fastapi.Header(None),
    ):
        if not x_fal_request_id:
            raise ValueError("x-fal-request-id is required")

        task = self._tasks.get(x_fal_request_id)
        if task is None:
            raise ValueError("No task found for this request ID")

        if task.done():
            raise ValueError("Task has already completed")

        task.cancel()
```


# https://fal.ai/docs/documentation/development/handle-inputs-and-outputs.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Handle Inputs and Outputs

> Define input and output schemas for your fal App endpoints that render correctly in the Playground.

Every [fal App](/documentation/getting-started/apps-and-execution) endpoint defines its interface through Python type annotations. The types you choose for your function parameters and return values determine what the [Playground](/documentation/model-apis/playground) renders: text inputs, sliders, file uploaders, image galleries, video players, and more. Getting these right means your model is immediately testable from the browser without building a custom UI.

fal endpoints are fully compatible with [Pydantic](https://docs.pydantic.dev/) models. You can use standard Pydantic features like field validation, default values, and nested models. On top of that, fal provides `FalBaseModel` for field ordering and hidden fields, specialized field helpers (`ImageField`, `VideoField`, `AudioField`) for Playground rendering, and toolkit types (`Image`, `Video`, `Audio`, `File`) for returning media with metadata. For the runtime side of file handling (downloading user inputs and uploading generated outputs to CDN), see [Working with Files](/documentation/development/working-with-files).

## FalBaseModel

For the best experience defining inputs and outputs, use `FalBaseModel` from the fal SDK. It extends Pydantic's `BaseModel` with features specifically designed for fal applications:

* **Field ordering** - Control the order fields appear in the playground and API schema
* **Hidden fields** - Mark parameters as API-only, hiding them from the playground and API schema.

```python theme={null}
from fal.toolkit import FalBaseModel, Field, Hidden

class TextToImageInput(FalBaseModel):
    FIELD_ORDERS = ["prompt", "negative_prompt", "image_size"]

    prompt: str = Field(description="Text description of the image")
    negative_prompt: str = Field(default="", description="What to avoid")
    image_size: str = Field(default="1024x1024", description="Output dimensions")

    # Hidden from playground UI but accessible via API
    debug_mode: bool = Hidden(Field(default=False))
    internal_seed: int = Hidden(Field(default=-1))
```

### Field ordering

Use the `FIELD_ORDERS` class variable to control the order fields appear in the API schema and playground. Fields listed in `FIELD_ORDERS` appear first, in the specified order, followed by any remaining fields.

This is particularly useful when you have a base model with common fields that multiple models inherit from. By default, Pydantic places child class fields before parent class fields in the schema. `FIELD_ORDERS` lets you ensure base model fields (like `prompt`) appear first for a consistent user experience.

```python theme={null}
from fal.toolkit import FalBaseModel, Field, ImageField

# Base model with common fields
class BaseTextInput(FalBaseModel):
    FIELD_ORDERS = ["prompt", "negative_prompt"]

    prompt: str = Field(description="Text prompt")
    negative_prompt: str = Field(default="", description="What to avoid")

# Extended model for image-to-image
class ImageToImageInput(BaseTextInput):
    # Override FIELD_ORDERS to control the full order
    FIELD_ORDERS = ["prompt", "negative_prompt", "image_url", "strength"]

    image_url: str = ImageField(description="Input image")
    strength: float = Field(default=0.8, description="How much to transform")

# Without FIELD_ORDERS, schema would show: image_url, strength, prompt, negative_prompt
# With FIELD_ORDERS, schema shows: prompt, negative_prompt, image_url, strength
```

### Hidden fields

Use `Hidden()` to wrap any field that should be available via API but hidden from the playground UI. This is useful for:

* Testing parameters you want to expose to select API integrations
* Internal debugging flags
* Advanced options that would clutter the UI

<Warning>
  Hidden fields must have a default value or `default_factory` since they cannot be required inputs in the UI.
</Warning>

```python theme={null}
from fal.toolkit import FalBaseModel, Field, Hidden

class MyInput(FalBaseModel):
    prompt: str = Field(description="User prompt")

    # These won't appear in the playground
    enable_profiling: bool = Hidden(Field(default=False))
    custom_config: dict = Hidden(Field(default_factory=dict))
```

### Media field helpers

For better playground rendering, use the specialized field helpers instead of plain `Field()`:

| Helper            | UI Rendering         |
| ----------------- | -------------------- |
| `FileField(...)`  | Generic file upload  |
| `ImageField(...)` | Image upload/preview |
| `AudioField(...)` | Audio upload/player  |
| `VideoField(...)` | Video upload/player  |

```python theme={null}
from fal.toolkit import FalBaseModel, ImageField, AudioField

class MyInput(FalBaseModel):
    # Renders as image upload in playground
    input_image: str = ImageField(description="Source image")

    # Renders as audio upload in playground
    voice_sample: str = AudioField(description="Voice sample for cloning")
```

These helpers work with both Pydantic v1 and v2. See the [Standard Inputs and Outputs](#standard-inputs-and-outputs) section below for more details on each media type, including naming conventions and output handling.

## Output Format for Playground Rendering

The Playground detects media outputs by checking for objects that have both a `url` and `content_type` field. If you use the toolkit types (`Image`, `Video`, `Audio`, `File`), these fields are set automatically. But if you are returning raw dicts from a [custom Docker container](/documentation/development/use-custom-container-image) or a [`fal.function`](/documentation/development/migrate-external-docker-server#fal-function-reference) endpoint, you must include both fields for the Playground to render the output as media instead of raw JSON.

```json theme={null}
{
  "image": {
    "url": "https://v3.fal.media/files/...",
    "content_type": "image/png"
  }
}
```

The Playground recognizes these field names for automatic rendering:

| Output field                           | Renders as              |
| -------------------------------------- | ----------------------- |
| `image` or `images`                    | Image preview / gallery |
| `video`                                | Video player            |
| `audio`, `audio_file`, or `audio_url`  | Audio player            |
| `model_glb`, `model_obj`, `model_mesh` | 3D model viewer         |

Each object in the response must have at minimum `url` and `content_type`. Without `content_type`, the Playground falls back to displaying the result as raw JSON. Additional fields like `file_name`, `file_size`, `width`, and `height` are optional but improve the display.

For [streaming endpoints](/documentation/development/streaming) that send results via SSE, the same format applies to each event. Streaming endpoints typically use `data:` URIs (base64-encoded inline content) instead of CDN URLs, since uploading each intermediate frame to CDN would add latency. The Playground renders data URIs the same way as CDN URLs.

```json theme={null}
{"image": {"url": "data:image/jpeg;base64,...", "content_type": "image/jpeg"}}
```

## Standard Inputs and Outputs

### File Input

Name your field with a `file_url` suffix and it will be rendered as a file in the playground, allowing users to upload or download the file.

```python theme={null}
from pydantic import BaseModel

class MyInput(BaseModel):
    file_url: str

class MyOutput(BaseModel):
    ...

class MyApp(fal.App):
    @fal.endpoint("/")
    def predict(self, input: MyInput) -> MyOutput:
        input_path = download_file(input.file_url)
        ...
        return MyOutput(...)
```

Alternatively if that naming convention is not suitable, you can use the `FileField` helper:

```python theme={null}
from fal.toolkit import FalBaseModel, FileField

class MyInput(FalBaseModel):
    document: str = FileField(description="Upload a document")
```

<Accordion title="Manual approach with json_schema_extra">
  For advanced use cases, you can manually specify the `ui` metadata. The syntax differs between Pydantic versions:

  <CodeGroup>
    ```python Pydantic v2 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        document: str = Field(..., json_schema_extra={"ui": {"field": "file"}})
    ```

    ```python Pydantic v1 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        document: str = Field(..., ui={"field": "file"})
    ```
  </CodeGroup>
</Accordion>

### File Output

Use the `File` type from `fal.toolkit` in your output schema. The Playground renders it as a download link.

```python theme={null}
from fal.toolkit import File
from pydantic import BaseModel

class MyOutput(BaseModel):
    file: File
```

The response includes file metadata:

```json theme={null}
{
  "file": {
    "url": "https://v3.fal.media/files/...",
    "content_type": "application/octet-stream",
    "file_name": "file.bin",
    "file_size": 1024
  }
}
```

See [Working with Files](/documentation/development/working-with-files#creating-files) for how to create `File` objects from local paths or bytes.

### Image Input

Name your field with a `image_url` suffix and it will be rendered as an image in the playground, allowing users to upload or download the image.

```python theme={null}
from pydantic import BaseModel
from fal.toolkit import download_file

class MyInput(BaseModel):
    image_url: str

class MyOutput(BaseModel):
    ...

class MyApp(fal.App):
    @fal.endpoint("/")
    def predict(self, input: MyInput) -> MyOutput:
        input_path = download_file(input.image_url)
        ...
        return MyOutput(...)
```

Alternatively if that naming convention is not suitable, you can use the `ImageField` helper:

```python theme={null}
from fal.toolkit import FalBaseModel, ImageField

class MyInput(FalBaseModel):
    photo: str = ImageField(description="Upload a photo")
```

<Accordion title="Manual approach with json_schema_extra">
  For advanced use cases, you can manually specify the `ui` metadata. The syntax differs between Pydantic versions:

  <CodeGroup>
    ```python Pydantic v2 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        photo: str = Field(..., json_schema_extra={"ui": {"field": "image"}})
    ```

    ```python Pydantic v1 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        photo: str = Field(..., ui={"field": "image"})
    ```
  </CodeGroup>
</Accordion>

### Image Output

Use the `Image` type in your output schema. The Playground renders it as an image preview.

```python theme={null}
from fal.toolkit import Image
from pydantic import BaseModel

class MyOutput(BaseModel):
    image: Image
```

The response includes image metadata with dimensions:

```json theme={null}
{
  "image": {
    "url": "https://v3.fal.media/files/...",
    "content_type": "image/png",
    "file_name": "image.png",
    "file_size": 1024,
    "width": 1024,
    "height": 1024
  }
}
```

See [Working with Files](/documentation/development/working-with-files#creating-files) for how to create `Image` objects from PIL images, bytes, or local files.

### Multiple Image Output

Return a list of `Image` objects to output multiple images. The Playground renders them in a gallery grid.

```python theme={null}
from typing import List
from fal.toolkit import Image
from pydantic import BaseModel

class MyOutput(BaseModel):
    images: List[Image]
    has_nsfw_concepts: List[bool]

class MyApp(fal.App):
    @fal.endpoint("/")
    def predict(self, prompt: str, num_images: int = 1) -> MyOutput:
        results = self.pipe(prompt, num_images=num_images).images
        return MyOutput(
            images=[Image.from_pil(img) for img in results],
            has_nsfw_concepts=[False] * len(results),
        )
```

Response:

```json theme={null}
{
  "images": [
    {"url": "https://v3.fal.media/files/.../image_0.png", "width": 1024, "height": 1024},
    {"url": "https://v3.fal.media/files/.../image_1.png", "width": 1024, "height": 1024},
    {"url": "https://v3.fal.media/files/.../image_2.png", "width": 1024, "height": 1024}
  ],
  "has_nsfw_concepts": [false, false, false]
}
```

**Playground gallery layout:**

Images are displayed in **array order** (index 0 first), laid out in a 2-column grid:

* **1 image**: Full width
* **2 images**: Side by side (index 0 left, index 1 right)
* **3 images**: First image full width on top, then index 1 left and index 2 right below
* **4 images**: 2x2 grid (index 0 top-left, index 1 top-right, index 2 bottom-left, index 3 bottom-right)

For odd numbers of images, the first image always spans the full width. The `has_nsfw_concepts` array maps by index: `has_nsfw_concepts[i]` corresponds to `images[i]`.

### Image Dataset Input

Use `image_urls` suffix to render a dataset of images in the playground.

```python theme={null}
from typing import List
from pydantic import BaseModel

class MyInput(BaseModel):
    image_urls: List[str]
```

### Audio Input

Name your field with a `audio_url` suffix and it will be rendered as an audio in the playground, allowing users to upload or download the audio.

```python theme={null}
from typing import List
from pydantic import BaseModel

class MyInput(BaseModel):
    audio_url: str

class MyOutput(BaseModel):
    ...

class MyApp(fal.App):
    @fal.endpoint("/")
    def predict(self, input: MyInput) -> MyOutput:
        input_path = download_file(input.audio_url)
        ...
        return MyOutput(...)
```

Alternatively if that naming convention is not suitable, you can use the `AudioField` helper:

```python theme={null}
from fal.toolkit import FalBaseModel, AudioField

class MyInput(FalBaseModel):
    voice_sample: str = AudioField(description="Upload a voice sample")
```

<Accordion title="Manual approach with json_schema_extra">
  For advanced use cases, you can manually specify the `ui` metadata. The syntax differs between Pydantic versions:

  <CodeGroup>
    ```python Pydantic v2 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        voice_sample: str = Field(..., json_schema_extra={"ui": {"field": "audio"}})
    ```

    ```python Pydantic v1 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        voice_sample: str = Field(..., ui={"field": "audio"})
    ```
  </CodeGroup>
</Accordion>

### Audio Output

Use the `Audio` type in your output schema. The Playground renders it as an audio player with waveform visualization.

```python theme={null}
from fal.toolkit import Audio
from pydantic import BaseModel

class MyOutput(BaseModel):
    audio: Audio
```

The response includes audio metadata:

```json theme={null}
{
  "audio": {
    "url": "https://v3.fal.media/files/...",
    "content_type": "audio/mpeg",
    "file_name": "audio.mp3",
    "file_size": 1024
  }
}
```

See [Working with Files](/documentation/development/working-with-files#creating-files) for how to create `Audio` objects from local files or bytes.

### Multiple Audio Output

Return a list of `Audio` objects. The Playground renders each as a stacked waveform player.

```python theme={null}
from typing import List
from fal.toolkit import Audio
from pydantic import BaseModel

class MyOutput(BaseModel):
    audios: List[Audio]
```

The Playground accepts `audios` (array), `audio` (single or array), or `audio_file`. Audio outputs are displayed vertically with waveform visualization and playback controls, in array order.

### Audio Dataset Input

Use `audio_urls` suffix to render a dataset of audios in the playground.

```python theme={null}
from typing import List
from pydantic import BaseModel

class MyInput(BaseModel):
    audio_urls: List[str]
```

### Video Input

Name your field with a `video_url` suffix and it will be rendered as a video in the playground, allowing users to upload or download the video.

```python theme={null}
from typing import List
from pydantic import BaseModel

class MyInput(BaseModel):
    video_url: str

class MyOutput(BaseModel):
    ...

class MyApp(fal.App):
    @fal.endpoint("/")
    def predict(self, input: MyInput) -> MyOutput:
        input_path = download_file(input.video_url)
        ...
        return MyOutput(...)
```

Alternatively if that naming convention is not suitable, you can use the `VideoField` helper:

```python theme={null}
from fal.toolkit import FalBaseModel, VideoField

class MyInput(FalBaseModel):
    clip: str = VideoField(description="Upload a video clip")
```

<Accordion title="Manual approach with json_schema_extra">
  For advanced use cases, you can manually specify the `ui` metadata. The syntax differs between Pydantic versions:

  <CodeGroup>
    ```python Pydantic v2 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        clip: str = Field(..., json_schema_extra={"ui": {"field": "video"}})
    ```

    ```python Pydantic v1 theme={null}
    from pydantic import BaseModel, Field

    class MyInput(BaseModel):
        clip: str = Field(..., ui={"field": "video"})
    ```
  </CodeGroup>
</Accordion>

### Video Output

Use the `Video` type in your output schema. The Playground renders it as a video player.

```python theme={null}
from fal.toolkit import Video
from pydantic import BaseModel

class MyOutput(BaseModel):
    video: Video
```

The response includes video metadata:

```json theme={null}
{
  "video": {
    "url": "https://v3.fal.media/files/...",
    "content_type": "video/mp4",
    "file_name": "video.mp4",
    "file_size": 1024
  }
}
```

See [Working with Files](/documentation/development/working-with-files#creating-files) for how to create `Video` objects from local files or bytes.

### Multiple Video Output

Return a list of `Video` objects. The Playground renders each video as a stacked player (not a grid).

```python theme={null}
from typing import List
from fal.toolkit import Video
from pydantic import BaseModel

class MyOutput(BaseModel):
    videos: List[Video]
```

The Playground accepts `videos` (array of objects with `url`) or `video` (single object or array). Videos are displayed vertically, one player per video, in array order.

### Video Dataset Input

Use `video_urls` suffix to render a dataset of videos in the playground.

```python theme={null}
from typing import List
from pydantic import BaseModel

class MyInput(BaseModel):
    video_urls: List[str]
```

### Mask Image Input

Name your field with a `mask_image_url` or `mask_url` suffix (or prefix) and the Playground renders an image upload with a built-in mask painting tool. Users can upload a mask image directly or click "Create..." to draw a mask over a reference image. The reference image is automatically pulled from an `image_url` or `inpaint_image_url` field in the same input schema.

```python theme={null}
from pydantic import BaseModel

class InpaintInput(BaseModel):
    image_url: str
    mask_image_url: str
    prompt: str
```

The mask painter produces a black-and-white image where white regions indicate areas to inpaint. Both `mask_image_url` and `mask_url` prefixes/suffixes are supported (e.g., `mask_url_face`, `custom_mask_image_url`).

### Color Input

If your input uses a Pydantic model named `RGBColor` with `r`, `g`, `b` integer fields, the Playground renders a color picker with a visual swatch and individual R/G/B inputs (0-255). A list of `RGBColor` values renders a color palette editor where users can add and remove colors.

```python theme={null}
from pydantic import BaseModel, Field
from typing import List

class RGBColor(BaseModel):
    r: int = Field(ge=0, le=255)
    g: int = Field(ge=0, le=255)
    b: int = Field(ge=0, le=255)

class MyInput(BaseModel):
    background_color: RGBColor = RGBColor(r=255, g=255, b=255)
    color_palette: List[RGBColor] = []
```

<Note>
  The Playground detects this by the type name `RGBColor`. The model must be named exactly `RGBColor` for the color picker to render.
</Note>

### Image Size Input

Use `ImageSizeInput` from `fal.toolkit` to render an image size selector with preset buttons (square, landscape, portrait) and custom width/height inputs. This is the same type used by most image generation models on fal.

```python theme={null}
from fal.toolkit import ImageSizeInput, get_image_size

class MyInput(BaseModel):
    image_size: ImageSizeInput = "square_hd"

class MyApp(fal.App):
    @fal.endpoint("/")
    def generate(self, input: MyInput) -> dict:
        size = get_image_size(input.image_size)
        width, height = size.width, size.height
        ...
```

The available presets are `"square_hd"` (1024x1024), `"square"` (512x512), `"portrait_4_3"` (768x1024), `"portrait_16_9"` (576x1024), `"landscape_4_3"` (1024x768), and `"landscape_16_9"` (1024x576). Users can also enter custom dimensions directly.

### Camera Image Input

Name your field with a `face_image_url` suffix and the Playground renders a camera capture widget that lets users take a photo with their webcam, in addition to the standard file upload options.

```python theme={null}
from pydantic import BaseModel

class FaceSwapInput(BaseModel):
    face_image_url: str
    target_image_url: str
```

### Camera Control Input

Use `ui.field = "camera_control"` or name your field ending with `advanced_camera_control` to render a visual camera motion selector. Users pick a movement type (roll, pan, tilt, zoom, horizontal, vertical) and a value, which is useful for video generation models that accept camera motion parameters.

```python theme={null}
from fal.toolkit import FalBaseModel, Field

class VideoInput(FalBaseModel):
    prompt: str
    camera_control: dict = Field(
        default={"movement_type": "default", "movement_value": 0},
        json_schema_extra={"ui": {"field": "camera_control"}}
    )
```

### 3D Model Input

Name your field with a `model_url` suffix and the Playground renders a 3D model upload widget.

```python theme={null}
from pydantic import BaseModel

class TextureInput(BaseModel):
    model_url: str
    prompt: str
```

### Archive and Dataset Input

Name your field with a `data_url` or `archive_url` suffix to render a dataset upload widget. This is useful for training endpoints or batch processing that accept ZIP archives or collections of files.

```python theme={null}
from pydantic import BaseModel

class TrainingInput(BaseModel):
    training_data_url: str
    trigger_word: str
```

### Presets Input

Fields ending in `model_name` automatically render as a preset selector. The Playground shows a dropdown populated from the field's `examples` metadata, with an option to enter a custom value. This is useful for model selection fields where you want to suggest common options while allowing arbitrary input.

```python theme={null}
from pydantic import BaseModel, Field

class MyInput(BaseModel):
    model_name: str = Field(
        default="stabilityai/stable-diffusion-xl-base-1.0",
        examples=[
            "stabilityai/stable-diffusion-xl-base-1.0",
            "runwayml/stable-diffusion-v1-5",
            "black-forest-labs/FLUX.1-dev",
        ]
    )
```

***

### EXR / HDR Output

The Playground can render [OpenEXR](https://openexr.com/) files with HDR tone mapping. When your endpoint returns a file with a URL ending in `.exr`, the Playground automatically displays it using a WebGL-based HDR viewer with ACES Filmic tone mapping.

Use `File.from_path()` to return EXR files — the `Image` toolkit class does not support EXR format.

```python theme={null}
import fal
import numpy as np
from pydantic import BaseModel
from fal.toolkit import File

class DepthInput(BaseModel):
    image_url: str

class DepthOutput(BaseModel):
    depth_map: File

class DepthApp(fal.App):
    machine_type = "GPU-A100"

    def setup(self):
        import cv2
        self.cv2 = cv2

    @fal.endpoint("/")
    def predict(self, input: DepthInput) -> DepthOutput:
        depth = self.run_depth_estimation(input.image_url)

        # Save as EXR — preserves full float32 precision
        output_path = "/tmp/depth.exr"
        self.cv2.imwrite(output_path, depth.astype(np.float32))

        return DepthOutput(
            depth_map=File.from_path(output_path, content_type="image/x-exr"),
        )
```

<Note>
  EXR rendering in the Playground is **output only**. Uploading EXR files as input is not currently supported.
</Note>

***

### 3D Model Output

The Playground can render 3D model files with an interactive viewer (orbit controls, lighting, zoom). When your endpoint returns a file with one of the supported extensions, the Playground automatically displays it as a 3D scene.

Supported formats:

| Format        | Extension | Renderer                         |
| ------------- | --------- | -------------------------------- |
| glTF Binary   | `.glb`    | Google Model Viewer (AR-capable) |
| Wavefront OBJ | `.obj`    | Three.js with orbit controls     |
| FBX           | `.fbx`    | Three.js with animation support  |
| Mesh          | `.mesh`   | Google Model Viewer              |

Use `File.from_path()` to return 3D files with the correct extension:

```python theme={null}
import fal
from pydantic import BaseModel
from fal.toolkit import File

class MeshInput(BaseModel):
    image_url: str

class MeshOutput(BaseModel):
    mesh: File

class MeshApp(fal.App):
    machine_type = "GPU-A100"

    def setup(self):
        self.pipeline = load_3d_pipeline()

    @fal.endpoint("/")
    def generate(self, input: MeshInput) -> MeshOutput:
        mesh = self.pipeline.generate(input.image_url)

        output_path = "/tmp/output.glb"
        mesh.export(output_path)

        return MeshOutput(
            mesh=File.from_path(output_path, content_type="model/gltf-binary"),
        )
```

The Playground detects 3D output by checking the URL file extension. GLB is the recommended format for best Playground compatibility, as it supports textures, materials, and AR preview.

<Tip>
  For examples of deploying 3D models on fal, see [Deploy 3D Progressive Rendering](/examples/video-generation/deploy-3d-progressive-rendering).
</Tip>

***

## Playground UI Mapping

Your Pydantic schema controls how the Playground renders each input field. The Playground automatically selects the right widget based on the field's type, name, and metadata.

### Widget Reference

| Python Type / Pattern                            | Playground Widget                      |
| ------------------------------------------------ | -------------------------------------- |
| `str`                                            | Text input                             |
| `str` named `prompt` or ending in `_prompt`      | Textarea (3 rows)                      |
| `bool`                                           | Toggle switch                          |
| `int` or `float` with `ge` and `le`              | Slider + number input                  |
| `int` ending in `seed`                           | Number input + randomize button        |
| `Literal["a", "b", "c"]` or `Enum`               | Dropdown select                        |
| `List[Literal[...]]` or `List[Enum]`             | Checkboxes                             |
| `str` ending in `_image_url` or `ImageField`     | Image upload (drag-drop, paste, URL)   |
| `str` ending in `_face_image_url`                | Camera capture + image upload          |
| `str` ending in `_mask_image_url` or `_mask_url` | Image upload + mask painter            |
| `str` ending in `_video_url` or `VideoField`     | Video upload with preview              |
| `str` ending in `_audio_url` or `AudioField`     | Audio upload + microphone recording    |
| `str` ending in `_file_url` or `FileField`       | Generic file upload                    |
| `str` ending in `_model_url`                     | 3D model upload                        |
| `str` ending in `_data_url` or `_archive_url`    | Dataset/archive upload                 |
| `str` ending in `model_name` with `examples`     | Preset selector + custom input         |
| `List[Image]` or ending in `_image_urls`         | Multi-image picker                     |
| `RGBColor` model (with `r`, `g`, `b` fields)     | Color picker                           |
| `List[RGBColor]`                                 | Color palette editor                   |
| `ImageSizeInput` (from `fal.toolkit`)            | Image size selector (presets + custom) |
| `ui.field = "camera_control"`                    | Camera motion selector                 |
| Nested Pydantic model                            | Recursive form (indented section)      |
| `List[str]` or `List[int]`                       | Add/remove input list                  |

### Examples

**Slider** - any `int` or `float` with both `ge` (min) and `le` (max) renders as a slider. Use `multiple_of` to control the step precision:

```python theme={null}
class MyInput(BaseModel):
    guidance_scale: float = Field(default=7.5, ge=1.0, le=20.0, multiple_of=0.5)
    num_inference_steps: int = Field(default=30, ge=1, le=100)
    strength: float = Field(default=0.8, ge=0.0, le=1.0, multiple_of=0.01)
```

**Dropdown** - `Literal` types or Python `Enum` classes render as dropdown selects:

```python theme={null}
from typing import Literal

class MyInput(BaseModel):
    scheduler: Literal["euler", "ddim", "dpm++"] = "euler"
    image_size: Literal["square_hd", "landscape_16_9", "portrait_4_3"] = "square_hd"
```

**Seed** - any `int` field with a name ending in `seed` gets a randomize button:

```python theme={null}
class MyInput(BaseModel):
    seed: int = Field(default=42, description="Random seed for reproducibility")
```

**Textarea** -- fields named `prompt` automatically render as a multi-line textarea. For other fields, use `ui.field`:

```python theme={null}
from fal.toolkit import FalBaseModel, Field

class MyInput(FalBaseModel):
    prompt: str = Field(description="This automatically renders as textarea")
    system_message: str = Field(
        default="",
        json_schema_extra={"ui": {"field": "textarea"}}
    )
```

**Checkboxes** - a list of enum values renders as a multi-select checkbox group:

```python theme={null}
from typing import List, Literal

class MyInput(BaseModel):
    styles: List[Literal["photorealistic", "anime", "oil-painting", "watercolor"]] = []
```

### UI Metadata

You can control Playground behavior with `json_schema_extra` metadata on any field:

```python theme={null}
from fal.toolkit import FalBaseModel, Field

class MyInput(FalBaseModel):
    prompt: str = Field(description="Main prompt")

    # Override the widget type
    notes: str = Field(
        default="",
        json_schema_extra={"ui": {"field": "textarea"}}
    )

    # Show helper text below the field
    lora_url: str = Field(
        default="",
        json_schema_extra={"ui": {"hint": "Paste a HuggingFace or Civitai URL"}}
    )

    # Mark as read-only in Playground (API-only parameter)
    internal_config: str = Field(
        default="",
        json_schema_extra={"ui": {"frozen": True}}
    )

    # Force field into the main form (not "Additional Settings")
    negative_prompt: str = Field(
        default="",
        json_schema_extra={"ui": {"important": True}}
    )
```

| Property       | Effect                                                                                                                    |
| -------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `ui.field`     | Override widget type (`"textarea"`, `"image"`, `"video"`, `"audio"`, `"file"`, `"seed"`, `"camera_control"`, `"presets"`) |
| `ui.hint`      | Helper text shown below the field                                                                                         |
| `ui.frozen`    | Field is read-only with an "API only" badge                                                                               |
| `ui.important` | Field appears in the main form section                                                                                    |

### Field Grouping

The Playground automatically groups fields into two sections:

* **Main form**: Required fields and fields marked with `ui.important = true`
* **Additional Settings**: Optional fields with defaults

This keeps the Playground clean for users who just want to enter a prompt and generate, while still exposing all parameters for advanced use.

```python theme={null}
class MyInput(BaseModel):
    # These appear in the main form (required or important)
    prompt: str = Field(description="Required -- always visible")

    # These collapse into "Additional Settings"
    guidance_scale: float = Field(default=7.5, ge=1.0, le=20.0)
    seed: int = Field(default=-1)
    num_images: int = Field(default=1, ge=1, le=4)
```


# https://fal.ai/docs/documentation/development/import-code.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Import Code

> Bring local Python modules, files, and external repositories into your fal app's remote environment.

When your app spans multiple files, uses local utility modules, or depends on code from a private repository, you need a way to include that code in the remote environment where your [runners](/documentation/getting-started/runners-and-caching) execute. This page covers the mechanisms fal provides: `app_files` for local files and directories, `local_python_modules` for Python modules that should be serialized alongside your app, and `clone_repository` for pulling external Git repos at startup.

These mechanisms work with the [fal Runtime](/documentation/development/fal-runtime) (pip requirements). They are not available when using a [custom Docker container](/documentation/development/use-custom-container-image), where you should use `COPY` in your Dockerfile to include local files instead.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=864&end=923&autoplay=1'><img src='/docs/images/video-thumbs/import-code.jpg' alt='App Files - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

<Warning>
  `app_files` and `local_python_modules` are only supported with the fal Runtime. If your app uses a custom `ContainerImage`, use `COPY` in your Dockerfile to include local files.
</Warning>

## Choosing the Right Mechanism

fal provides three ways to bring code into the remote environment, each suited to a different situation.

Use **`app_files`** when you have a multi-file project and want the remote environment to mirror your local directory structure. Files are uploaded and placed at the same relative paths, so imports and file reads work identically to local development. This is the recommended approach for most projects.

Use **`local_python_modules`** when you have a simple Python module that your app imports at the top level. The module is serialized (pickled) alongside your app class and made available on the remote Python path. This is lighter-weight than `app_files` but only works for importable Python packages.

Use **`clone_repository`** when you need to pull code from an external Git repository at runner startup. The clone happens inside `setup()`, so the code is available before your first request.

## App Files

The `app_files` attribute includes local files and directories in the remote environment, mirroring your local file layout exactly. Imports and file paths work the same way they do on your machine.

```python theme={null}
class MyApp(fal.App):
    app_files = [
        "utils/helper.py",
        "models",
        "checkpoint.pt",
    ]

    @fal.endpoint("/")
    def predict(self, input: MyInput) -> MyOutput:
        from utils.helper import process_data
        from models.classifier import MyModel

        result = process_data(input)
        model = MyModel.load_checkpoint("checkpoint.pt")
        return model.predict(result)
```

If your local project looks like this:

```
project/
├── my_fal_app.py
├── utils/
│   └── helper.py
└── models/
    └── classifier.py
```

Then on the runner, `from utils.helper import process_data` and `from models.classifier import MyModel` work exactly as they do locally. Files are placed relative to your app file location.

### Context Directory

By default, all file paths are resolved relative to the directory containing your fal app file. You can change this base directory with `app_files_context_dir`, which is useful for monorepos or when you need to include files from a parent directory:

```python theme={null}
class MyApp(fal.App):
    app_files_context_dir = "../"
    app_files = [
        "src/data_processing",
        "src/models",
        "weights",
        "utils",
    ]
```

All paths must be relative and within the context directory. Absolute paths and paths that escape the context directory (e.g., `../../outside`) are rejected. Included files are read-only on the runner.

### Ignoring Files

Use `app_files_ignore` to exclude files using regex patterns. fal excludes `.pyc`, `__pycache__/`, `.git/`, and `.DS_Store` by default.

```python theme={null}
class MyApp(fal.App):
    app_files = ["my_project/"]
    app_files_ignore = [
        r"\.pyc$",
        r"__pycache__/",
        r"\.git/",
        r"\.env$",
        r"test_.*\.py$",
    ]
```

Only include the files your app actually needs. Smaller deployments mean faster uploads and faster runner startup.

## Local Python Modules

The `local_python_modules` attribute ships a Python module alongside your app by serializing it into the deployment payload. This is a simpler mechanism than `app_files` - it adds the specified modules to the remote Python path so they can be imported directly. Use it when you have a small utility module that your app imports at the top level.

```python theme={null}
from mymodule import myfunction

class MyApp(fal.App):
    local_python_modules = ["mymodule"]

    @fal.endpoint("/")
    def predict(self, input: MyInput) -> MyOutput:
        myfunction(input)
        ...
```

For projects with multiple files, directories, or non-Python assets (configs, weights), `app_files` is the better choice because it preserves the full directory structure and supports ignore patterns.

## Git Repositories

Use `clone_repository` to pull code from a Git repository at runner startup. The clone happens inside `setup()`, so the repository is available before any requests are processed. Pin to a specific commit hash for reproducibility.

```python theme={null}
from fal.toolkit import clone_repository

class MyApp(fal.App):
    def setup(self):
        path = clone_repository(
            "https://github.com/myorg/myrepo",
            commit_hash="1418c53bcfaf4efc1034207dcb39d093d5fff645",
            include_to_path=True,
        )

        import myproject
        ...
```

Setting `include_to_path=True` adds the cloned directory to `PYTHONPATH`, so you can import modules from the repository directly. For private repositories, include a personal access token in the URL: `https://YOUR_TOKEN@github.com/myorg/private-repo.git`.


# https://fal.ai/docs/documentation/development/logging.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging

> Understand how logs are captured, scoped, and surfaced across runner logs, request logs, and the Playground.

Logging is essential for debugging your [fal App](/documentation/getting-started/apps-and-execution) during development and monitoring it after [deployment](/documentation/deployment/deploy-to-production). Every message your app writes to `stdout` or `stderr` is captured by fal and made available through the dashboard, CLI, and queue status API. This means `print()` statements, Python `logging` output, and even error tracebacks are all collected automatically.

The most important thing to understand about logging on fal is that logs exist at different scopes, and each scope determines who can see them and where they appear. Runner logs capture everything a runner does across its lifetime. Request logs are the subset visible to callers. Playground logs appear in real-time during testing. Knowing which scope you are working with helps you decide what information is safe to log and where to look when debugging.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=345&end=441&autoplay=1'><img src='/docs/images/video-thumbs/logging.jpg' alt='Logs - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Runner Logs

Runner logs capture the full output of a [runner](/documentation/deployment/runners) process from the moment it starts until it shuts down. This includes output from `setup()` (model loading, initialization), every request the runner handles, and any background output between requests. Runner logs are visible only to the app owner through the [dashboard](https://fal.ai/dashboard/logs) and CLI.

Use runner logs for internal diagnostics: model loading times, memory usage, cache behavior, and anything that spans the runner's lifetime rather than a single request.

```python theme={null}
class MyApp(fal.App):
    def setup(self):
        print("Loading model weights...")  # This appears in runner logs
        self.model = load_model()
        print(f"Model loaded, VRAM: {torch.cuda.memory_allocated() / 1e9:.1f}GB")
```

You can view runner logs in the CLI with [`fal runners logs <runner-id>`](/reference/cli/runners), or in the [dashboard](https://fal.ai/dashboard/logs) filtered by runner ID.

## Request Logs

Request logs are the portion of runner logs emitted while a specific request is being processed. They are time-scoped: fal captures the start and end of each request and extracts the log messages in between. These are the logs that callers see when they poll for [queue status](/documentation/model-apis/inference/queue#check-status) with `with_logs=True` (Python) or `logs: true` (JavaScript).

```python theme={null}
class MyApp(fal.App):
    @fal.endpoint("/")
    def run(self, prompt: str) -> dict:
        print(f"Generating for prompt: {prompt}")  # Visible to callers
        result = self.model(prompt)
        print(f"Generation complete, inference time: {result.time:.2f}s")
        return {"image": result.image}
```

Because request logs are visible to anyone calling your app, be careful about what you log during request handling. Avoid logging secrets, user data, or internal model details that should not be exposed.

### Private Logs

If your request logs contain sensitive information, you can make them private so only you (the app owner) can see them. Callers polling the queue will see no log output — logs are still captured and visible in the dashboard and CLI, but non-owners receive empty log arrays in their status responses.

There are two ways to make logs private: per-app via the `private_logs` option, or account-wide via the Log Privacy setting.

#### Per-app

Set `private_logs=True` in the class definition to make logs private for that app only:

```python theme={null}
class MyApp(fal.App, private_logs=True):
    @fal.endpoint("/")
    def run(self, prompt: str) -> dict:
        print("This log is only visible to the app owner")
        return {"result": "..."}
```

A per-app `private_logs=True` always makes that app's logs private, regardless of the account-level default.

#### Account-wide default

Under [Dashboard → Settings → Log Privacy](https://fal.ai/dashboard/account/log-privacy), the **Default Private Logs** toggle controls the default visibility of logs across all your apps.

When enabled, log visibility for non-owners is restricted on newly deployed apps — they inherit `private_logs=True` at registration time without needing to set it explicitly in code. Existing apps retain their current setting until redeployed; redeploy an app to pick up the current account default.

An app that explicitly sets `private_logs=True` is always private. An app that does not set `private_logs` at all follows the account default in effect when it was deployed.

## Playground Logs

When you test your app in the [Playground](/documentation/model-apis/playground), logs appear in real-time in the output panel as your endpoint processes the request. The Playground shows request logs (the same logs callers would see via the queue API), so you can verify exactly what output your users will receive.

During development with [`fal run`](/reference/cli/run), logs also stream directly to your terminal, giving you immediate feedback without needing the dashboard.

## Writing Logs

For quick debugging, `print()` is the simplest approach. Both `stdout` and `stderr` are captured.

```python theme={null}
import fal
import sys

class MyApp(fal.App):
    @fal.endpoint("/")
    def run(self) -> dict:
        print("Processing request...")
        print("Warning: cache miss", file=sys.stderr)
        return {"message": "Hello, World!"}
```

For production apps, use Python's standard `logging` module to control log levels and message format. A good pattern is to route INFO and WARNING to `stdout` and ERROR and above to `stderr`, so you can filter by severity when reviewing logs.

```python theme={null}
import logging
import sys
import fal


def get_logger():
    stdout_handler = logging.StreamHandler(sys.stdout)
    stdout_handler.setLevel(logging.INFO)
    stdout_handler.addFilter(lambda record: record.levelno < logging.ERROR)

    stderr_handler = logging.StreamHandler(sys.stderr)
    stderr_handler.setLevel(logging.ERROR)

    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(levelname)s %(name)s: %(message)s",
        handlers=[stdout_handler, stderr_handler],
    )
    return logging.getLogger("my_app")


class MyApp(fal.App):
    def setup(self):
        self.logger = get_logger()

    @fal.endpoint("/")
    def run(self) -> dict:
        self.logger.info("Started request processing")
        try:
            result = {"message": "Hello, World!"}
            self.logger.info("Request completed successfully")
            return result
        except Exception:
            self.logger.exception("Request failed")
            raise
```

<Tip>
  Include the request ID in your log output for easier debugging. You can access it via `self.current_request.request_id` in your endpoint handler. See [Request Headers](/documentation/development/request-headers) for all available per-request context including caller identity and custom headers.
</Tip>

<Warning>
  Avoid logging secrets, API keys, or large raw payloads. Log IDs, sizes, and high-level status instead.
</Warning>

## Log Sources

When filtering logs in the dashboard or CLI, the `source` field tells you where the logs came from:

* `run` - logs from runners created by [`fal run`](/reference/cli/run) during development
* `gateway` - logs from runners serving deployed apps in production
* `deploy` - logs emitted by the deployment process itself when using [`fal deploy`](/reference/cli/deploy)

## Where to View Logs

| What you need                       | Where to look                                                                                                                                                      |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| All logs for a specific runner      | [Dashboard](https://fal.ai/dashboard/logs) filtered by runner ID, or [`fal runners logs <runner-id>`](/reference/cli/runners) in the CLI                           |
| Logs for a specific request         | [Dashboard](https://fal.ai/dashboard/logs) filtered by request ID, or [queue status API](/documentation/model-apis/inference/queue#check-status) with logs enabled |
| Real-time logs during development   | Terminal output from [`fal run`](/reference/cli/run)                                                                                                               |
| Real-time logs in the browser       | [Dashboard logs page](https://fal.ai/dashboard/logs) streams all runner logs in real-time. Playground shows request-filtered logs only.                            |
| Logs filtered by deployment version | [Dashboard](https://fal.ai/dashboard/logs) filtered by version ID                                                                                                  |


# https://fal.ai/docs/documentation/development/manage-secrets-securely.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets

> Store API keys, credentials, and other sensitive configuration securely, accessible to your fal App at runtime.

Most AI applications need credentials to call external services -- Hugging Face tokens for gated models, database URLs, third-party API keys, or [private Docker registry](/documentation/development/private-registries) credentials. Secrets let you store these values securely on fal instead of hardcoding them in your code or committing them to version control. Once set, secrets are encrypted and their values are never displayed again.

Secrets are injected into your [runners](/documentation/getting-started/runners-and-caching) as environment variables when they start. You access them via `os.getenv()` just like any other environment variable. Secrets can be scoped to specific [environments](/documentation/deployment/manage-environments) (e.g., different API keys for staging vs production) and are separate from the [platform environment variables](/documentation/development/environment-variables) that fal injects automatically.

## Setting Secrets

You can set secrets from the [Dashboard](https://fal.ai/dashboard/secrets), the CLI, or the Python SDK.

### Dashboard

Navigate to [**Dashboard > Secrets**](https://fal.ai/dashboard/secrets) to create, edit, and delete secrets. Select the environment (e.g., main, staging) from the dropdown, then add your key-value pairs. Values are encrypted and never displayed after creation.

### CLI

```bash theme={null}
fal secrets set HF_TOKEN=hf_abc123 DATABASE_URL=postgres://...
```

You can set multiple secrets in a single command. To target a specific environment, use the `--env` flag:

```bash theme={null}
fal secrets set HF_TOKEN=hf_staging_token --env staging
```

### Python SDK

```python theme={null}
from fal.api import SyncServerlessClient

client = SyncServerlessClient()
client.secrets.set("HF_TOKEN", "hf_abc123")
client.secrets.set("HF_TOKEN", "hf_staging_token", environment_name="staging")
```

## Accessing Secrets at Runtime

Secrets are available as standard environment variables inside your app. Use `os.getenv()` to read them in `setup()`, endpoint handlers, or anywhere else in your runner code.

```python theme={null}
import os
import fal

class MyApp(fal.App):
    def setup(self):
        import huggingface_hub
        huggingface_hub.login(token=os.getenv("HF_TOKEN"))
        self.pipe = load_gated_model()

    @fal.endpoint("/")
    def generate(self, prompt: str) -> dict:
        result = self.pipe(prompt)
        return {"output": result}
```

<Note>
  Secrets are injected when a runner starts. If you update a secret, running runners keep the old value. Only new runners (from a new deploy or scale-up) pick up the updated value. To force all runners to use the new value, redeploy your app with `fal deploy`.
</Note>

## Secrets During Build

For security, secrets are **not** available as environment variables during the image build stage. The built image is cached and may be shared across environments, so injecting secrets into the build would risk leaking them.

Instead, use the `${}` substitution syntax in your `requirements` list. fal replaces `${SECRET_NAME}` with the secret value at build time without exposing it in the cached image.

```python theme={null}
import fal

class MyApp(fal.App):
    requirements = [
        "git+https://${GITHUB_TOKEN}@github.com/myorg/private-package"
    ]
```

This is the only way to use secrets during dependency installation. The substitution happens server-side before pip runs, and the token is not stored in the final image.

### Docker Build Secrets

If you use a [custom container image](/documentation/development/use-custom-container-image), you can pass build-time secrets via the `secrets` parameter on `ContainerImage`. These are mounted as Docker build secrets (via `--mount=type=secret`) and are available inside your Dockerfile during the build but not persisted in the final image.

```python theme={null}
from fal.container import ContainerImage

image = ContainerImage.from_dockerfile_str(
    """
    FROM python:3.11
    RUN --mount=type=secret,id=hf_token cat /run/secrets/hf_token
    """,
    secrets={"hf_token": os.getenv("HF_TOKEN")},
)
```

## Secrets Per Environment

Secrets can be scoped to specific [environments](/documentation/deployment/manage-environments), letting you use different credentials for development, staging, and production. When you deploy to an environment, the runner receives the secrets set for that environment.

```bash theme={null}
fal secrets set DATABASE_URL=postgres://prod-db.example.com/app
fal secrets set DATABASE_URL=postgres://staging-db.example.com/app --env staging
```

If a secret is not set for a specific environment, the runner does not fall back to the main environment's value -- the variable is simply not present.

## Managing Secrets

### Listing

List your secrets to see their names, environments, and creation dates. Values are never displayed.

```bash theme={null}
fal secrets list
```

| Name          | Env  | Created At          |
| ------------- | ---- | ------------------- |
| HF\_TOKEN     | main | 2026-01-15 10:30:00 |
| DATABASE\_URL | main | 2026-01-15 10:31:00 |

To list secrets for a specific environment:

```bash theme={null}
fal secrets list --env staging
```

### Removing

Delete a secret to prevent it from being injected into new runners:

```bash theme={null}
fal secrets unset HF_TOKEN
fal secrets unset HF_TOKEN --env staging
```

Running runners are not affected by deletion. The secret is removed from new runners only.


# https://fal.ai/docs/documentation/development/migrate-external-docker-server.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate an External Docker Server

> Deploy an existing Docker-based server (ComfyUI, custom APIs) to fal's serverless platform.

If you already have a working Docker container that runs a server, you can deploy it on fal with minimal changes. This guide covers two approaches: exposing your server's port directly for zero-code migration, or wrapping it with a `fal.App` proxy for full control over the API surface. Both approaches give you autoscaling, [analytics](/documentation/serverless/observability/app-analytics), and the same infrastructure that powers every model in the marketplace.

This is the fastest path for teams migrating from self-hosted infrastructure, Kubernetes, or other serverless platforms. Your existing server code stays unchanged. You just need to define a [Dockerfile](/documentation/development/use-custom-container-image) (or reference an existing image from a [private registry](/documentation/development/private-registries)) and tell fal how to start your server. If you are starting from scratch rather than migrating, the [Quick Start](/documentation/development/getting-started/quick-start) is a better starting point.

## fal.function vs fal.App

Most of the Serverless documentation focuses on `fal.App`, the class-based approach where you define `setup()`, endpoints, and `teardown()` as methods on a class. For server migration, this guide uses `@fal.function` instead. It is a decorator-based alternative that wraps a single function rather than a class. You pass all configuration (machine type, scaling parameters, container image) as decorator arguments, and the function body runs on the remote machine.

`fal.function` is the natural fit for existing servers because you typically just need to start a process and expose a port. You do not need lifecycle hooks or multiple endpoints since your server already handles those. Both `fal.function` and `fal.App` support the same scaling parameters (`keep_alive`, `min_concurrency`, `max_concurrency`, and more). See the [full parameter reference](#fal-function-reference) below for the complete list.

## Option 1: Direct Server Mode

Use `exposed_port` to route requests directly to your container's port. fal forwards all incoming traffic to that port without any intermediate processing. The port can be any valid port number, just ensure it matches the port your server listens on.

```mermaid theme={null}
flowchart LR
    Client --> Gateway[fal Gateway]
    Gateway --> Container[Your Container]
    Container --> Server[Server :exposed_port]
```

```python theme={null}
import subprocess
import fal
from fal.container import ContainerImage

DOCKERFILE = """
FROM your-base-image
# ... your setup
"""

@fal.function(
    image=ContainerImage.from_dockerfile_str(DOCKERFILE),
    machine_type="GPU-A100",
    exposed_port=8000,
    keep_alive=300,
)
def run_server():
    subprocess.run(
        ["your-server", "--host", "0.0.0.0", "--port", "8000"],
        check=True,
    )
```

Your server's API is exposed as-is. Requests go directly to the exposed port, and your existing routes, middleware, and response formats all work without modification.

<Warning>
  To unlock the full fal dashboard experience, including the [Playground](/documentation/model-apis/playground), analytics, and error tracking, fal needs your OpenAPI specification. For `fal.function` with `exposed_port`, pass the spec via the `metadata` parameter. For `fal.App`, the framework generates the OpenAPI spec automatically from your Pydantic models.

  Without an OpenAPI spec, the Playground and endpoint listing will not be available for your deployment. See [Providing an OpenAPI Spec via Metadata](#providing-an-openapi-spec-via-metadata) for a working example.
</Warning>

***

## Option 2: Proxy App Mode

Use `fal.App` to wrap your server with custom endpoints. This gives you control over the API surface: you can validate inputs with Pydantic, transform outputs, upload files to the [fal CDN](/documentation/model-apis/fal-cdn), and define a typed schema that powers the Playground UI.

```mermaid theme={null}
flowchart LR
    Client --> Gateway[fal Gateway]
    Gateway --> App[fal.App]
    App <--> Server[Internal Server]
    App --> CDN[fal CDN]
```

```python theme={null}
import subprocess
import time
import fal
import requests
from fal.container import ContainerImage
from fal.toolkit import Image
from fastapi import Request
from pydantic import BaseModel, Field

DOCKERFILE = """
FROM your-base-image
# ... your setup
"""

SERVER_PORT = 8000

class GenerateRequest(BaseModel):
    prompt: str = Field(description="Text prompt")

class GenerateResponse(BaseModel):
    image: Image

class MyServerProxy(fal.App, keep_alive=300, max_concurrency=1):
    machine_type = "GPU-A100"
    image = ContainerImage.from_dockerfile_str(DOCKERFILE)

    def setup(self):
        self.process = subprocess.Popen(
            ["your-server", "--host", "127.0.0.1", "--port", str(SERVER_PORT)],
        )
        self._wait_for_server()

    def _wait_for_server(self, timeout=120):
        start = time.time()
        while time.time() - start < timeout:
            try:
                if requests.get(f"http://127.0.0.1:{SERVER_PORT}/", timeout=5).ok:
                    return
            except requests.ConnectionError:
                pass
            time.sleep(1)
        raise TimeoutError("Server did not start")

    @fal.endpoint("/generate")
    def generate(self, input: GenerateRequest, request: Request) -> GenerateResponse:
        resp = requests.post(
            f"http://127.0.0.1:{SERVER_PORT}/api/generate",
            json={"prompt": input.prompt},
            timeout=300,
        )
        resp.raise_for_status()

        image = Image.from_path(resp.json()["path"], request=request)
        return GenerateResponse(image=image)
```

Your `fal.App` controls the API. The internal server runs on localhost inside the same container, and your proxy endpoints handle input validation, output processing, and CDN uploads. This approach is ideal when you want a clean typed API over an existing server that has its own internal protocol.

## Using an External Registry

If your image is already hosted on an external registry (Docker Hub, Google Artifact Registry, Amazon ECR), you can pull it directly instead of building from a Dockerfile string. This avoids rebuilding the image on every deploy and is the recommended approach for production containers that are already built in CI. See [Using Private Docker Registries](/documentation/development/use-custom-container-image#using-private-docker-registries) for setup instructions including authentication for each registry type.

## fal.function Reference

The `@fal.function` decorator used in Option 1 accepts all the same infrastructure and scaling parameters that `fal.App` supports as class attributes. If you have been using `fal.function` and did not realize you could configure scaling, this table covers every available parameter.

| Parameter                 | Type                 | Default      | Description                                                                                                                                                |
| ------------------------- | -------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `image`                   | `ContainerImage`     | None         | Custom Docker container for the function                                                                                                                   |
| `machine_type`            | `str` or `list[str]` | `"XS"` (CPU) | Hardware to run on. Use a list for fallback types.                                                                                                         |
| `num_gpus`                | `int`                | None         | Number of GPUs to allocate                                                                                                                                 |
| `exposed_port`            | `int`                | None         | Route traffic directly to this port (for existing servers)                                                                                                 |
| `requirements`            | `list[str]`          | None         | Pip packages to install (when not using `image`)                                                                                                           |
| `keep_alive`              | `int`                | 10           | Seconds an idle runner stays alive before shutting down                                                                                                    |
| `min_concurrency`         | `int`                | 0            | Minimum runners kept warm at all times                                                                                                                     |
| `max_concurrency`         | `int`                | None         | Maximum runners to scale up to                                                                                                                             |
| `max_multiplexing`        | `int`                | 1            | Maximum concurrent requests per runner                                                                                                                     |
| `concurrency_buffer`      | `int`                | 0            | Extra runners to keep warm above current load                                                                                                              |
| `concurrency_buffer_perc` | `int`                | 0            | Percentage buffer of runners above current load                                                                                                            |
| `scaling_delay`           | `int`                | None         | Seconds to wait before scaling up for a new request                                                                                                        |
| `request_timeout`         | `int`                | None         | Maximum seconds for a single request                                                                                                                       |
| `startup_timeout`         | `int`                | None         | Maximum seconds for the function to start                                                                                                                  |
| `setup_function`          | `Callable`           | None         | One-time initialization function (runs before first request)                                                                                               |
| `regions`                 | `list[str]`          | None         | Restrict to specific regions                                                                                                                               |
| `serve`                   | `bool`               | False        | Run as an HTTP server on port 8080                                                                                                                         |
| `metadata`                | `dict`               | None         | App metadata. Pass `{"openapi": {...}}` to provide your OpenAPI spec for Playground and endpoint listing. Required for `fal.function` with `exposed_port`. |
| `local_python_modules`    | `list[str]`          | None         | Local Python modules to ship to the remote environment. See [Import Code](/documentation/development/import-code).                                         |
| `python_version`          | `str`                | None         | Python version to use (for virtualenv kind).                                                                                                               |

A realistic example using scaling parameters:

```python theme={null}
@fal.function(
    image=ContainerImage.from_dockerfile_str(DOCKERFILE),
    machine_type="GPU-A100",
    exposed_port=8000,
    keep_alive=300,
    min_concurrency=1,
    max_concurrency=5,
    max_multiplexing=1,
    request_timeout=600,
    startup_timeout=300,
)
def run_server():
    subprocess.run(
        ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"],
        check=True,
    )
```

For full documentation on `fal.App` configuration, see [App Lifecycle](/documentation/development/app-lifecycle). For scaling parameter details, see [Scale Your Application](/documentation/deployment/scale-your-application).

## Providing an OpenAPI Spec via Metadata

When using `fal.function` with `exposed_port`, fal does not automatically generate an OpenAPI spec from your code (unlike `fal.App` which derives it from your Pydantic models). To enable the Playground, endpoint listing, and schema validation in the dashboard, pass your OpenAPI spec through the `metadata` parameter.

```python theme={null}
@fal.function(
    image=ContainerImage.from_dockerfile_str(DOCKERFILE),
    machine_type="S",
    exposed_port=8080,
    metadata={
        "openapi": {
            "openapi": "3.0.3",
            "info": {"title": "My Server", "version": "1.0.0"},
            "paths": {
                "/generate": {
                    "post": {
                        "summary": "Generate",
                        "operationId": "generate",
                        "requestBody": {
                            "required": True,
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/GenerateRequest"
                                    }
                                }
                            },
                        },
                        "responses": {
                            "200": {
                                "description": "Success",
                                "content": {
                                    "application/json": {
                                        "schema": {
                                            "$ref": "#/components/schemas/GenerateResponse"
                                        }
                                    }
                                },
                            }
                        },
                    }
                }
            },
            "components": {
                "schemas": {
                    "GenerateRequest": {
                        "type": "object",
                        "required": ["prompt"],
                        "properties": {
                            "prompt": {"type": "string"},
                        },
                    },
                    "GenerateResponse": {
                        "type": "object",
                        "properties": {
                            "result": {"type": "string"},
                        },
                    },
                }
            },
        }
    },
)
def run_server():
    import uvicorn
    from fastapi import FastAPI
    from pydantic import BaseModel

    app = FastAPI()

    class GenerateRequest(BaseModel):
        prompt: str

    class GenerateResponse(BaseModel):
        result: str

    @app.post("/generate")
    async def generate(req: GenerateRequest) -> GenerateResponse:
        return GenerateResponse(result=f"Output for: {req.prompt}")

    uvicorn.run(app, host="0.0.0.0", port=8080)
```

<Note>
  Even if your server is built with FastAPI (which exposes `/openapi.json` automatically), the `metadata` approach is still required for `fal.function` deployments. The platform reads the spec from `metadata` at registration time, not from the running server.
</Note>

## Best Practices

Download model weights to [persistent storage](/documentation/development/use-persistent-storage) (`/data`) in your `setup()` method rather than baking them into the Docker image. This keeps your image small, speeds up container pulls, and allows weights to be cached across runner restarts. The `/data` directory is shared across all runners in your account and persists between deploys.

When building your Dockerfile, install fal-specific packages (`boto3`, `protobuf`, `pydantic`) at the end to avoid version conflicts with your existing dependencies. If your base image already includes these packages, the fal runtime will use the versions in your image.

Tune [keep\_alive](/documentation/deployment/scale-your-application) based on your app's cold start time and traffic pattern. If your model takes minutes to load, a longer keep\_alive avoids paying that cost repeatedly. If your app starts quickly, a shorter value reduces idle billing. See [Optimizing Costs](/documentation/serverless/optimizations/optimizing-costs) for guidance.

## Next Steps

For a complete tutorial that applies this pattern to a real server, see the [ComfyUI deployment example](/examples/image-generation/deploy-comfyui-server). For detailed Dockerfile configuration including build args, multi-stage builds, and private registries, see [Custom Container Images](/documentation/development/use-custom-container-image). To understand how the `/data` persistent storage works and what gets cached, see [Use Persistent Storage](/documentation/development/use-persistent-storage).


# https://fal.ai/docs/documentation/development/migrate-from-modal.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Modal

> A guide for migrating your Modal applications to fal.

If you have been running AI models on Modal, this guide maps Modal concepts to their fal equivalents and shows how to convert your code. The core patterns are similar: both platforms use Python classes with lifecycle hooks and GPU configuration. The main differences are that fal uses HTTP endpoints instead of RPC, and fal manages container builds from a requirements list or Dockerfile rather than chaining image methods.

For a broader overview of deploying existing Docker containers on fal (regardless of where they came from), see [Deploy an Existing Server](/documentation/development/migrate-external-docker-server). If you are comparing fal to other platforms, see [Migrate from Replicate](/documentation/development/migrate-from-replicate) or [Migrate from RunPod](/documentation/development/migrate-from-runpod).

## Concept Mapping

| Modal                                        | fal                                   | Notes                                   |
| -------------------------------------------- | ------------------------------------- | --------------------------------------- |
| `@app.function()`                            | `@fal.function()`                     | Standalone serverless functions         |
| `@app.cls()`                                 | `class MyApp(fal.App)`                | Class-based apps (recommended)          |
| `@modal.method()`                            | `@fal.endpoint("/")`                  | fal uses HTTP endpoints, not RPC        |
| `@modal.enter()`                             | `def setup(self)`                     | Container startup hook                  |
| `@modal.exit()`                              | `def teardown(self)`                  | Container shutdown hook                 |
| `modal.Image.debian_slim().pip_install(...)` | `requirements = [...]`                | Or use `ContainerImage` for Dockerfiles |
| `modal.Image.from_dockerfile(...)`           | `ContainerImage.from_dockerfile(...)` | Custom container support                |
| `gpu="A100"`                                 | `machine_type = "GPU-A100"`           | GPU selection                           |
| `modal.Volume`                               | `/data` persistent storage            | Mounted automatically on all runners    |
| `modal.Secret`                               | `fal secrets set`                     | Secrets exposed as env vars             |
| `modal deploy`                               | `fal deploy`                          | CLI deployment                          |
| `Cls().method.remote(x=123)`                 | `fal_client.subscribe(...)`           | fal uses HTTP + queue, not RPC          |

***

## Migration Path 1: Standalone Functions

If you use `@app.function()` in Modal, the closest fal equivalent is `@fal.function()`.

<Tabs>
  <Tab title="Modal">
    ```python theme={null}
    import modal

    app = modal.App()
    image = modal.Image.debian_slim().pip_install("torch", "transformers")

    @app.function(image=image, gpu="A100")
    def generate(prompt: str):
        from transformers import pipeline
        pipe = pipeline("text-generation", model="gpt2", device="cuda")
        return pipe(prompt)[0]["generated_text"]

    @app.local_entrypoint()
    def main():
        result = generate.remote(prompt="Hello world")
        print(result)
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal

    @fal.function(
        requirements=["torch", "transformers"],
        machine_type="GPU-A100",
    )
    def generate(prompt: str):
        from transformers import pipeline
        pipe = pipeline("text-generation", model="gpt2", device="cuda")
        return pipe(prompt)[0]["generated_text"]
    ```
  </Tab>
</Tabs>

***

## Migration Path 2: Class-Based Apps (Recommended)

If you use `@app.cls()` with `@modal.enter()` and `@modal.method()`, convert to a `fal.App` class.

<Tabs>
  <Tab title="Modal">
    ```python theme={null}
    import modal

    app = modal.App()
    image = (
        modal.Image.debian_slim()
        .pip_install("torch", "diffusers", "transformers", "accelerate")
    )

    @app.cls(image=image, gpu="A100")
    class TextToImage:
        @modal.enter()
        def load_model(self):
            import torch
            from diffusers import StableDiffusionXLPipeline

            self.pipe = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        @modal.method()
        def generate(self, prompt: str):
            image = self.pipe(prompt).images[0]
            return image

        @modal.exit()
        def cleanup(self):
            del self.pipe

    @app.local_entrypoint()
    def main():
        result = TextToImage().generate.remote(prompt="a sunset")
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal
    from fal.toolkit import Image

    class TextToImage(fal.App):
        machine_type = "GPU-A100"
        requirements = ["torch", "diffusers", "transformers", "accelerate"]

        def setup(self):
            import torch
            from diffusers import StableDiffusionXLPipeline

            self.pipe = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        @fal.endpoint("/")
        def generate(self, prompt: str) -> dict:
            image = self.pipe(prompt).images[0]
            return {"image": Image.from_pil(image)}

        def teardown(self):
            del self.pipe
    ```
  </Tab>
</Tabs>

### Deploying

```bash theme={null}
# Modal
modal deploy my_app.py

# fal
fal deploy my_app.py::TextToImage
```

### Calling Your App

```python theme={null}
# Modal
TextToImage().generate.remote(prompt="a sunset")

# fal
import fal_client
result = fal_client.subscribe("your-username/text-to-image", arguments={
    "prompt": "a sunset"
})
```

***

## Key Differences

### HTTP Endpoints vs RPC

Modal uses `.remote()` to invoke functions as Python-to-Python RPC calls. fal uses **HTTP endpoints** that any language or tool can call. Your fal App exposes a REST API automatically.

This means:

* No `.remote()` calls - clients use `fal_client.subscribe()` or raw HTTP
* Your endpoints accept and return JSON (use Pydantic models for validation)
* The same endpoint works from Python, JavaScript, cURL, or any HTTP client

### Queue-Based by Default

fal provides a persistent queue that handles retries, scaling, and load balancing automatically. When callers use `subscribe` or `submit`, requests go through this queue by default. Direct calls via `run` bypass the queue for lower overhead.

### Container Images

Modal chains image methods (`Image.debian_slim().pip_install(...).apt_install(...)`). fal offers two approaches:

* **`requirements` list** (simpler): Just list your pip packages
* **`ContainerImage`** (full control): Bring your own Dockerfile

```python theme={null}
# Modal
image = (
    modal.Image.debian_slim()
    .apt_install("ffmpeg")
    .pip_install("torch", "diffusers")
)

# fal (simple)
class MyApp(fal.App):
    requirements = ["torch", "diffusers"]

# fal (Dockerfile)
from fal.container import ContainerImage

class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        FROM python:3.11
        RUN apt-get update && apt-get install -y ffmpeg
        RUN pip install torch diffusers
    """)
```

### Volumes and Storage

Modal uses named `Volume` objects mounted at specific paths. fal provides `/data` -- a persistent filesystem automatically mounted on every runner, shared across all your apps.

```python theme={null}
# Modal
volume = modal.Volume.from_name("model-cache")

@app.cls(volumes={"/cache": volume})
class MyModel:
    ...

# fal -- /data is always available, no configuration needed
class MyModel(fal.App):
    def setup(self):
        model_path = "/data/models/my-model.pt"
        if os.path.exists(model_path):
            self.model = torch.load(model_path)
```

### Secrets

Modal uses `modal.Secret.from_name(...)` and attaches secrets to functions. fal exposes secrets as environment variables:

```bash theme={null}
# Modal
modal secret create my-secret HF_TOKEN=hf_xxx

# fal
fal secrets set HF_TOKEN=hf_xxx
```

Both make secrets available via `os.environ["HF_TOKEN"]` in your code.

## Next Steps

Once you have migrated your app, the [App Lifecycle](/documentation/development/app-lifecycle) page explains how the full lifecycle works on fal, from code serialization to runner shutdown. For scaling configuration, see [Scale Your Application](/documentation/deployment/scale-your-application). For monitoring your deployed app, see [App Analytics](/documentation/serverless/observability/app-analytics).


# https://fal.ai/docs/documentation/development/migrate-from-replicate.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Replicate

> A guide for migrating your Replicate Cog models to fal.

If you have been running models on Replicate using [Cog](https://github.com/replicate/cog), this guide shows how to convert your Cog model to a `fal.App`. The core idea is similar: both platforms package a model with its dependencies and expose a predict/generate interface. The main differences are that fal uses a Python class instead of a `cog.yaml` + `predict.py` pattern, and fal builds containers from a requirements list or Dockerfile rather than relying on Cog's build system.

For a broader overview of deploying existing Docker containers on fal (regardless of where they came from), see [Deploy an Existing Server](/documentation/development/migrate-external-docker-server). If you are comparing fal to other platforms, see [Migrate from Modal](/documentation/development/migrate-from-modal) or [Migrate from RunPod](/documentation/development/migrate-from-runpod).

## Concept Mapping

| Replicate (Cog)                  | fal                                        | Notes                                           |
| -------------------------------- | ------------------------------------------ | ----------------------------------------------- |
| `cog.yaml`                       | `requirements = [...]` or `ContainerImage` | Environment definition                          |
| `class Predictor(BasePredictor)` | `class MyApp(fal.App)`                     | App class                                       |
| `def setup(self)`                | `def setup(self)`                          | One-time model loading                          |
| `def predict(self, ...)`         | `@fal.endpoint("/")`                       | Request handler                                 |
| `cog.Path` (file output)         | `fal.toolkit.Image` / `fal.toolkit.File`   | Media outputs uploaded to CDN automatically     |
| `Input(...)` type hints          | Pydantic `BaseModel`                       | fal uses standard Pydantic for input validation |
| `cog push`                       | `fal deploy`                               | Single CLI command                              |
| Replicate API client             | `fal_client.subscribe(...)`                | HTTP + queue based                              |
| Webhooks                         | `webhook_url` parameter                    | Both support webhook delivery                   |

***

## Migration Path: Cog Predictor to fal.App

The most common Cog pattern is a `Predictor` class with `setup()` and `predict()` methods. On fal, `setup()` stays the same, and `predict()` becomes an `@fal.endpoint` method with Pydantic input/output models.

<Tabs>
  <Tab title="Replicate (Cog)">
    ```yaml theme={null}
    # cog.yaml
    build:
      python_version: "3.11"
      python_packages:
        - torch==2.1.0
        - diffusers==0.30.0
        - transformers
        - accelerate
      gpu: true
    predict: "predict.py:Predictor"
    ```

    ```python theme={null}
    # predict.py
    from cog import BasePredictor, Input, Path
    import torch
    from diffusers import StableDiffusionXLPipeline

    class Predictor(BasePredictor):
        def setup(self):
            self.pipe = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        def predict(self, prompt: str = Input(description="Text prompt")) -> Path:
            image = self.pipe(prompt).images[0]
            output_path = "/tmp/output.png"
            image.save(output_path)
            return Path(output_path)
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal
    from pydantic import BaseModel, Field
    from fal.toolkit import Image

    class Input(BaseModel):
        prompt: str = Field(description="Text prompt")

    class Output(BaseModel):
        image: Image

    class MyApp(fal.App):
        machine_type = "GPU-A100"
        requirements = ["torch==2.1.0", "diffusers==0.30.0", "transformers", "accelerate"]

        def setup(self):
            import torch
            from diffusers import StableDiffusionXLPipeline

            self.pipe = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        @fal.endpoint("/")
        def predict(self, input: Input) -> Output:
            image = self.pipe(input.prompt).images[0]
            return Output(image=Image.from_pil(image))
    ```
  </Tab>
</Tabs>

Key differences in the fal version:

The `cog.yaml` is replaced by class attributes (`machine_type`, `requirements`). The `cog.Path` output is replaced by `fal.toolkit.Image`, which automatically uploads the image to the [fal CDN](/documentation/model-apis/fal-cdn) and returns a URL. Inputs use standard Pydantic models instead of Cog's `Input()` type hints. Imports happen inside `setup()` so they run on the remote runner, not on your local machine (see [Serialization and Build](/documentation/development/app-lifecycle#serialization-and-build) for why).

## Using Your Existing Cog Dockerfile

If you have a complex `cog.yaml` with system packages, CUDA configuration, or custom build steps, you can extract the Dockerfile that Cog generates and use it directly with fal. Run `cog debug` to output the generated Dockerfile:

```bash theme={null}
cog debug > Dockerfile
```

You will need to make a few modifications to the generated Dockerfile:

1. Remove the `COPY . /src`, `EXPOSE`, and `CMD` lines at the end - fal handles these
2. Remove the Cog wheel installation (`cog-0.0.1.dev-py3-none-any.whl`) since fal does not use the Cog runtime
3. Replace the Cog requirements with your actual pip packages

Then reference the Dockerfile in your fal app:

```python theme={null}
import fal
from fal.container import ContainerImage

class MyApp(fal.App):
    machine_type = "GPU-A100"
    image = ContainerImage.from_dockerfile("Dockerfile")

    def setup(self):
        import torch
        from diffusers import StableDiffusionXLPipeline

        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
        ).to("cuda")

    @fal.endpoint("/")
    def predict(self, input: dict) -> dict:
        image = self.pipe(input["prompt"]).images[0]
        return {"image": image}
```

For most migrations, the `requirements` list approach is simpler and avoids dealing with Cog's generated Dockerfile. Use the Dockerfile approach only when you have system-level dependencies or a specific CUDA version that cannot be expressed through pip packages. See [Custom Container Images](/documentation/development/use-custom-container-image) for the full guide.

<Note>
  `cog debug` is a hidden debugging command with no stability guarantees from the Cog team. The generated Dockerfile format may change between Cog versions.
</Note>

## Deploying and Calling

```bash theme={null}
# Deploy
fal deploy my_app.py::MyApp
```

```python theme={null}
# Call your deployed app
import fal_client

result = fal_client.subscribe("your-username/my-app", arguments={
    "prompt": "a sunset over mountains"
})
print(result["image"]["url"])
```

For the full range of calling patterns including async queue, streaming, and webhooks, see [Calling Your Endpoints](/documentation/development/calling-your-endpoints).

## Next Steps

Once you have migrated your model, the [App Lifecycle](/documentation/development/app-lifecycle) page explains how the full lifecycle works on fal, from code serialization to runner shutdown. For scaling configuration, see [Scale Your Application](/documentation/deployment/scale-your-application). For monitoring your deployed app, see [App Analytics](/documentation/serverless/observability/app-analytics).


# https://fal.ai/docs/documentation/development/migrate-from-runpod.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from RunPod

> A guide for migrating your RunPod Serverless workers to fal.

If you have been running serverless GPU workloads on RunPod, this guide maps RunPod concepts to their fal equivalents and shows how to convert your code. The core ideas are similar: both platforms run your code on GPU machines that scale based on demand. The main difference is that RunPod uses a handler function pattern with explicit Docker builds, while fal uses a class-based `fal.App` with automatic container builds.

For a broader overview of deploying existing Docker containers on fal (regardless of where they came from), see [Deploy an Existing Server](/documentation/development/migrate-external-docker-server). If you are comparing fal to other platforms, see [Migrate from Replicate](/documentation/development/migrate-from-replicate) or [Migrate from Modal](/documentation/development/migrate-from-modal).

## Concept Mapping

| RunPod                                          | fal                                        | Notes                                                                          |
| ----------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------ |
| `handler(job)`                                  | `@fal.endpoint("/")`                       | Request handler function                                                       |
| `runpod.serverless.start({"handler": handler})` | `class MyApp(fal.App)`                     | App entrypoint                                                                 |
| `job["input"]`                                  | Pydantic `Input` model                     | fal validates and types inputs automatically                                   |
| `return result`                                 | `return Output(...)`                       | fal validates outputs with Pydantic                                            |
| `yield result` (streaming)                      | `StreamingResponse` or `@fal.realtime()`   | See [Streaming](/documentation/development/streaming)                          |
| Model loading at module level                   | `def setup(self)`                          | Runs once per runner, not per request                                          |
| `refresh_worker: True`                          | Return HTTP 503                            | Terminates the runner and spins up a fresh one                                 |
| `runpod.serverless.progress_update()`           | `print()` (logs visible via SDK)           | Or use [streaming](/documentation/development/streaming) for real-time updates |
| Dockerfile + Docker Hub                         | `requirements = [...]` or `ContainerImage` | fal builds containers for you, or bring your own                               |
| Docker Hub deployment                           | `fal deploy`                               | Single CLI command                                                             |
| `/run` (async)                                  | `fal_client.submit()`                      | Queue-based async                                                              |
| `/runsync` (sync)                               | `fal_client.subscribe()`                   | Blocks until result                                                            |
| `/stream`                                       | `fal_client.stream()`                      | Progressive output                                                             |
| Max workers                                     | `max_concurrency`                          | Maximum runners to scale to                                                    |
| Min workers                                     | `min_concurrency`                          | Minimum runners kept warm                                                      |
| Idle timeout                                    | `keep_alive`                               | Seconds before idle runner shuts down                                          |
| Concurrency per worker                          | `max_multiplexing`                         | Concurrent requests per runner                                                 |
| Network volumes                                 | `/data` persistent storage                 | Mounted automatically on all runners                                           |
| Environment variables                           | `fal secrets set`                          | Secrets exposed as env vars                                                    |

***

## Migration Path: Handler to fal.App

The most common pattern on RunPod is a handler function that loads a model at module level and processes requests. On fal, this maps to a `fal.App` class where model loading moves into `setup()` and the handler becomes an endpoint method.

<Tabs>
  <Tab title="RunPod">
    ```python theme={null}
    import runpod
    import torch
    from diffusers import StableDiffusionXLPipeline

    model = StableDiffusionXLPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        torch_dtype=torch.float16,
    ).to("cuda")

    def handler(job):
        prompt = job["input"]["prompt"]
        image = model(prompt).images[0]
        image.save("/tmp/output.png")
        return {"image_path": "/tmp/output.png"}

    runpod.serverless.start({"handler": handler})
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal
    from pydantic import BaseModel
    from fal.toolkit import Image

    class Input(BaseModel):
        prompt: str

    class Output(BaseModel):
        image: Image

    class MyApp(fal.App):
        machine_type = "GPU-A100"
        requirements = ["torch", "diffusers"]
        keep_alive = 300
        max_concurrency = 5

        def setup(self):
            import torch
            from diffusers import StableDiffusionXLPipeline

            self.model = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        @fal.endpoint("/")
        def generate(self, input: Input) -> Output:
            image = self.model(input.prompt).images[0]
            return Output(image=Image.from_pil(image))
    ```
  </Tab>
</Tabs>

Key differences in the fal version:

The model loading moves from module-level into `setup()`, which runs once per [runner](/documentation/getting-started/runners-and-caching) rather than once per container build. Inputs are validated through a Pydantic model instead of manually extracting from `job["input"]`. Outputs are also typed, and images are automatically uploaded to the [fal CDN](/documentation/model-apis/fal-cdn) rather than saved to a local path. You do not need to write a Dockerfile or push to Docker Hub since fal builds the container from your `requirements` list.

## Calling Your Deployed App

RunPod exposes `/run` (async), `/runsync` (sync), and `/stream` endpoints. fal provides equivalent patterns through the client SDK.

<Tabs>
  <Tab title="RunPod">
    ```python theme={null}
    import runpod

    runpod.api_key = "your_api_key"
    endpoint = runpod.Endpoint("your_endpoint_id")

    # Sync
    result = endpoint.run_sync({"prompt": "a sunset"})

    # Async
    run = endpoint.run({"prompt": "a sunset"})
    status = run.status()
    result = run.output()
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal_client

    # Sync (subscribe polls automatically)
    result = fal_client.subscribe("your-username/your-app", arguments={
        "prompt": "a sunset"
    })

    # Async
    handler = fal_client.submit("your-username/your-app", arguments={
        "prompt": "a sunset"
    })
    status = handler.status()
    result = handler.get()
    ```
  </Tab>
</Tabs>

For the full range of calling patterns including streaming, real-time WebSockets, and webhooks, see [Calling Your Endpoints](/documentation/development/calling-your-endpoints).

## Deployment Workflow

On RunPod, the deployment unit is a Docker image. Your handler code lives inside the image, and the workflow requires several manual steps: write a Dockerfile that copies your handler and installs dependencies, build the image locally, push it to Docker Hub, then deploy through RunPod's console by pointing it at the image URL.

<Tabs>
  <Tab title="RunPod workflow">
    ```dockerfile theme={null}
    # 1. Write a Dockerfile
    FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
    RUN pip install runpod diffusers transformers
    COPY handler.py /handler.py
    CMD ["python", "/handler.py"]
    ```

    ```bash theme={null}
    # 2. Build locally
    docker build -t myuser/my-model:latest .

    # 3. Push to Docker Hub
    docker push myuser/my-model:latest

    # 4. Deploy via RunPod console (manual step in the UI)
    ```
  </Tab>

  <Tab title="fal workflow">
    ```python theme={null}
    # 1. Write your app (no Dockerfile needed)
    class MyApp(fal.App):
        machine_type = "GPU-A100"
        requirements = ["torch", "diffusers", "transformers"]

        def setup(self):
            ...
    ```

    ```bash theme={null}
    # 2. Deploy (one command, fal builds the container for you)
    fal deploy my_app.py::MyApp
    ```
  </Tab>
</Tabs>

On fal, there is no manual Docker build, no Docker Hub, and no console-based deployment. You run `fal deploy` and fal handles the container build, image storage, and deployment. Your code and your environment definition live in the same Python file.

## Environment and Dependencies

Because fal eliminates the Docker build step for most use cases, you have two options for defining your environment:

**Option 1: pip requirements (recommended).** List your packages in the `requirements` attribute. fal builds the container automatically. This is the simplest migration path since you can copy the `pip install` lines from your RunPod Dockerfile directly into the list.

```python theme={null}
class MyApp(fal.App):
    requirements = ["torch==2.1.0", "diffusers==0.30.0", "transformers"]
```

**Option 2: Custom Docker container.** If you need system packages, a specific CUDA version, or want to reuse your existing RunPod Dockerfile with minimal changes, use [ContainerImage](/documentation/development/use-custom-container-image). You can paste your RunPod Dockerfile almost as-is, just remove the `COPY handler.py` and `CMD` lines since fal handles those.

```python theme={null}
from fal.container import ContainerImage

class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
        RUN apt-get update && apt-get install -y ffmpeg
        RUN pip install diffusers transformers
    """)
```

## Model Storage

RunPod offers three approaches for model weights: Hugging Face cache, baked into the Docker image, or network volumes. fal's equivalent is [persistent storage](/documentation/development/use-persistent-storage) at `/data`, which is mounted on every runner and shared across your account. Models downloaded to `/data` are cached automatically and survive runner restarts, similar to RunPod's network volumes but without explicit volume configuration.

```python theme={null}
def setup(self):
    import os
    os.environ["HF_HOME"] = "/data/.cache/huggingface"

    from diffusers import StableDiffusionXLPipeline
    self.model = StableDiffusionXLPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0"
    ).to("cuda")
```

## Next Steps

Once you have migrated your handler, the [App Lifecycle](/documentation/development/app-lifecycle) page explains how the full lifecycle works on fal, from code serialization to runner shutdown. For scaling configuration, see [Scale Your Application](/documentation/deployment/scale-your-application). For monitoring your deployed app, see [App Analytics](/documentation/serverless/observability/app-analytics).


# https://fal.ai/docs/documentation/development/migrating-to-fal.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating to fal

> Bring your existing models and infrastructure to fal with minimal code changes.

If you are already running AI models on another platform or on your own infrastructure, fal is designed to make migration straightforward. You can bring your existing Docker containers, HTTP servers, or platform-specific code and deploy them on fal's GPU infrastructure with minimal changes. The guides in this section provide step-by-step walkthroughs for common migration paths.

If you are starting a new project rather than migrating, you can skip this section entirely and go to [Defining Your Environment](/documentation/development/container-setup) to set up your app from scratch.

The fastest path is [Migrate a Docker Server](/documentation/development/migrate-external-docker-server), which lets you deploy any existing HTTP server with `@fal.function` and `exposed_port` with no changes to your application code. If you are coming from a specific platform, the [Replicate](/documentation/development/migrate-from-replicate), [Modal](/documentation/development/migrate-from-modal), and [RunPod](/documentation/development/migrate-from-runpod) guides provide side-by-side code comparisons and cover how to map your existing configuration (GPU types, scaling, secrets, storage) to fal equivalents.


# https://fal.ai/docs/documentation/development/multi-app-routing.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-App Routing

> Use a lightweight proxy app to route requests between multiple fal apps based on input characteristics.

As your workloads grow more complex, you may need different GPU types for different inputs, want to A/B test model versions, or orchestrate multi-step pipelines across specialized apps. Multi-app routing lets you deploy a lightweight CPU app as a router that inspects incoming requests and forwards them to the right backend. Each backend runs independently on its own machine type, scaling configuration, and model version.

The pattern is simple: deploy your backend apps normally, then deploy a CPU-only router app that uses [`FAL_KEY`](/documentation/development/environment-variables#authentication) (auto-injected into every runner) to call the backends via the fal client SDK. The router runs on cheap CPU instances and adds minimal latency, while each backend scales independently based on its own traffic. For simpler cases where you just want requests routed to runners that already have the right model loaded, see [Optimize Routing Behavior](/documentation/serverless/optimizations/optimize-routing-behavior) instead.

## When to Use

* **Route by GPU requirements** -- Send small inputs to A100, large inputs to H100
* **Route by model variant** -- Different LoRA adapters, different base models
* **A/B testing** -- Split traffic between model versions
* **Multi-step pipelines** -- Orchestrate a chain of apps (preprocess, generate, postprocess)
* **Fallback routing** -- Try one app, fall back to another on failure
* **Cost optimization** -- Route simple requests to cheaper machines, complex ones to expensive

## How It Works

```mermaid theme={null}
flowchart LR
    Client --> Router["Router App (CPU)"]
    Router -->|small inputs| A["Backend A (A100)"]
    Router -->|large inputs| B["Backend B (H100)"]
    Router -->|fallback| C["Backend C (A6000)"]
```

1. Deploy multiple backend apps, each on a specific machine type
2. Deploy a lightweight CPU router app that accepts all requests
3. The router inspects the input and calls the appropriate backend via `fal_client`
4. `FAL_KEY` is auto-injected into every runner, so the router can call other fal apps without hardcoding credentials

***

## Example: Route by Input Size

Three apps: a CPU router and two GPU backends for different resolutions.

### Backend Apps

```python theme={null}
# backend_standard.py
import fal
from fal.toolkit import Image

class ImageGenStandard(fal.App):
    machine_type = "GPU-A100"

    def setup(self):
        from diffusers import StableDiffusionXLPipeline
        import torch
        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
        ).to("cuda")

    @fal.endpoint("/")
    def generate(self, prompt: str, width: int = 1024, height: int = 1024) -> dict:
        image = self.pipe(prompt, width=width, height=height).images[0]
        return {"image": Image.from_pil(image)}
```

```python theme={null}
# backend_highres.py
import fal
from fal.toolkit import Image

class ImageGenHighRes(fal.App):
    machine_type = "GPU-H100"

    def setup(self):
        from diffusers import StableDiffusionXLPipeline
        import torch
        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
        ).to("cuda")

    @fal.endpoint("/")
    def generate(self, prompt: str, width: int = 2048, height: int = 2048) -> dict:
        image = self.pipe(prompt, width=width, height=height).images[0]
        return {"image": Image.from_pil(image)}
```

Deploy both:

```bash theme={null}
fal deploy backend_standard.py::ImageGenStandard --app-name image-gen-standard
fal deploy backend_highres.py::ImageGenHighRes --app-name image-gen-highres
```

### Router App

```python theme={null}
# router.py
import fal
import fal_client

STANDARD_THRESHOLD = 1024 * 1024  # 1 megapixel

class ImageRouter(fal.App):
    machine_type = "S"  # Lightweight CPU -- just routing, no GPU needed
    requirements = ["fal-client"]

    @fal.endpoint("/")
    def route(self, prompt: str, width: int = 1024, height: int = 1024) -> dict:
        total_pixels = width * height

        if total_pixels <= STANDARD_THRESHOLD:
            app_id = "your-username/image-gen-standard"
        else:
            app_id = "your-username/image-gen-highres"

        result = fal_client.subscribe(app_id, arguments={
            "prompt": prompt,
            "width": width,
            "height": height,
        })

        return result
```

```bash theme={null}
fal deploy router.py::ImageRouter --app-name image-router
```

Users call `image-router` -- it routes to the right backend automatically.

***

## Example: A/B Testing

Split traffic between two model versions:

```python theme={null}
import fal
import fal_client
import random

class ABTestRouter(fal.App):
    machine_type = "S"
    requirements = ["fal-client"]

    @fal.endpoint("/")
    def route(self, prompt: str) -> dict:
        # 80% to stable version, 20% to experimental
        if random.random() < 0.8:
            app_id = "your-username/model-v1"
        else:
            app_id = "your-username/model-v2"

        result = fal_client.subscribe(app_id, arguments={
            "prompt": prompt,
        })

        # Include which version was used in the response
        result["model_version"] = app_id
        return result
```

***

## Example: Multi-Step Pipeline

Chain multiple apps together:

```python theme={null}
import fal
import fal_client

class PipelineRouter(fal.App):
    machine_type = "S"
    requirements = ["fal-client"]

    @fal.endpoint("/")
    def run_pipeline(self, image_url: str) -> dict:
        # Step 1: Upscale
        upscaled = fal_client.subscribe(
            "fal-ai/real-esrgan",
            arguments={"image_url": image_url, "scale": 4}
        )

        # Step 2: Remove background
        result = fal_client.subscribe(
            "fal-ai/birefnet",
            arguments={"image_url": upscaled["image"]["url"]}
        )

        return result
```

***

## Trade-offs

| Consideration  | Detail                                                                                                                           |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **Latency**    | Adds one hop through the CPU router. The router itself is fast (no GPU, no model loading), so overhead is typically under 100ms. |
| **Cost**       | The CPU router is very cheap (`S` machine type). The savings from routing to the right GPU often outweigh the router cost.       |
| **Complexity** | You manage multiple apps instead of one. Use clear naming conventions and environments.                                          |
| **Scaling**    | Each backend scales independently. The router can have high `max_multiplexing` since it's just forwarding requests.              |

<Tip>
  Set `max_multiplexing` high on the router app (e.g., 50+) since it's just making HTTP calls and doesn't need exclusive resources per request.
</Tip>

## Related

<CardGroup cols={2}>
  <Card title="Optimize Routing Behavior" icon="arrow-right" href="/documentation/serverless/optimizations/optimize-routing-behavior">
    Route requests within a single app using runner hints
  </Card>

  <Card title="Environment Variables" icon="arrow-right" href="/documentation/development/environment-variables">
    FAL\_KEY is auto-injected for calling other fal apps
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/development/private-registries.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Private Docker Registries

> How to authenticate with private registries like Docker Hub, Google Artifact Registry, and AWS ECR.

When your base image is hosted on a private registry, you need to provide authentication credentials so fal can pull the image during container builds. This page covers the setup for Docker Hub, Google Artifact Registry, and Amazon ECR, including how to manage tokens securely using fal's [secrets management](/documentation/development/manage-secrets-securely).

These credentials are passed via the `registries` parameter on [ContainerImage](/documentation/development/use-custom-container-image). Each registry uses a different authentication method, so follow the section below that matches your registry provider.

## Dockerhub

```python theme={null}
class MyModel(fal.App):
    image = fal.container.ContainerImage.from_dockerfile_str(
        "FROM myuser/image:tag",
        registries={
            "https://index.docker.io/v1/": {
                "username": "myuser",
                "password": "$DOCKERHUB_TOKEN",  # Use `fal secrets set` to create this secret
            },
        },
    )
```

## Google Artifact Registry

We recommend using a service account and setting a base64-encoded version of the key as a fal secret.

<Steps>
  <Step title="Create a JSON key for a service account.">
    Download the key file to your local machine.
  </Step>

  <Step title="Encode the key in base64.">
    ```shell theme={null}
    cat key.json | base64
    ```
  </Step>

  <Step title="Set the result as a fal secret.">
    ```shell theme={null}
    fal secrets set GOOGLE_AR_JSON_BASE64=<base64-value>
    ```
  </Step>

  <Step title="Use the secret in your code.">
    ```python theme={null}
    class MyModel(fal.App):
        image = fal.container.ContainerImage.from_dockerfile_str(
            "FROM us-central1-docker.pkg.dev/my-project/my-repo/image:tag",
            registries={
                "us-central1-docker.pkg.dev": {
                    "username": "_json_key_base64",
                    "password": "$GOOGLE_AR_JSON_BASE64",
                },
            },
        )
    ```
  </Step>
</Steps>

## Amazon Elastic Container Registry (ECR)

ECR tokens expire every 12 hours. It's best to auto-generate one on the fly using `boto3` and your AWS credentials.

```python theme={null}
import os
import boto3
import base64

def get_ecr_token(region: str) -> str:
    ecr_client = boto3.client(
        'ecr',
        aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
        aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
        region_name=region
    )
    response = ecr_client.get_authorization_token()
    auth_data = response['authorizationData'][0]
    token = auth_data['authorizationToken']
    # Decode from base64, format is "AWS:password"
    decoded_token = base64.b64decode(token).decode('utf-8')
    _, password = decoded_token.split(':', 1)
    return password

class MyModel(fal.App):
    image = fal.container.ContainerImage.from_dockerfile_str(
        "FROM 123456789012.dkr.ecr.us-east-1.amazonaws.com/image:tag",
        registries={
            "123456789012.dkr.ecr.us-east-1.amazonaws.com": {
                "username": "AWS",
                "password": get_ecr_token("us-east-1"),
            },
        },
    )
```


# https://fal.ai/docs/documentation/development/realtime.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Realtime Endpoints

> Build low-latency, bidirectional WebSocket endpoints for interactive applications that require persistent connections and back-to-back requests.

Realtime endpoints use WebSockets for bidirectional communication over a persistent connection. Once a client connects, it can send multiple inputs and receive results without the overhead of establishing new connections for each request. This makes them ideal for interactive applications like real-time image editing, live camera filters, or game-like experiences where latency between requests needs to be minimal.

You define a realtime endpoint using the `@fal.realtime("/realtime")` decorator, which uses fal's binary msgpack protocol for efficient serialization. Callers connect using the [`realtime()` method](/documentation/model-apis/inference/real-time) in the fal client SDKs. For one-way progressive output from a single request (like showing diffusion steps), use [Streaming Endpoints](/documentation/development/streaming) instead -- they use SSE and are simpler when you don't need bidirectional communication.

<Warning>
  WebSocket endpoints are not currently testable on the fal Playground. You can monitor your WebSocket endpoint activity through the **Logs** page in the fal dashboard.
</Warning>

## How Realtime Works

Under a `fal.App`, the `@fal.realtime()` decorator makes your endpoint compatible with [fal's real-time clients](/documentation/model-apis/inference/real-time). It uses fal's binary msgpack protocol for efficient serialization and eliminates connection establishing overhead for repeated requests.

<Info>
  **Important:** The `fal_client.realtime()` method automatically connects to the `/realtime` path on your app. If you use `@fal.realtime()`, you **must** set the path to `/realtime` (e.g., `@fal.realtime("/realtime")`) for the client to connect successfully.
</Info>

For power users who want to build stateful applications with their own real-time protocol, a `@fal.endpoint` can
be initialized with `is_websocket=True` flag and the underlying function will receive the raw WebSocket connection and
can choose to use it however it wants.

## Server-Side Implementation

Here's an example of a fal app with both a regular HTTP endpoint and a WebSocket endpoint:

```python theme={null}
import fal
from pydantic import BaseModel
from fastapi import WebSocket


class Input(BaseModel):
    prompt: str


class Output(BaseModel):
    output: str


class RealtimeApp(fal.App):
    keep_alive = 60

    @fal.endpoint("/")
    def generate(self, input: Input) -> Output:
        return Output(output=input.prompt)

    @fal.realtime("/realtime")
    def generate_rt(self, input: Input) -> Output:
        return Output(output=input.prompt)

    @fal.endpoint("/echo", is_websocket=True)
    async def generate_ws(self, websocket: WebSocket) -> None:
        await websocket.accept()
        msg = await websocket.receive_text()
        for idx in range(3):
            print(f"Sending message {idx}")
            await websocket.send_text(msg + f"-{idx}")
        await websocket.close()
```

## Client-Side Connection

### Connecting to `@fal.realtime()` Endpoints

For endpoints decorated with `@fal.realtime()`, use `fal_client.realtime()` or `fal_client.realtime_async()`. These methods handle serialization automatically using fal's binary protocol:

```python theme={null}
import fal_client

# Connect to a @fal.realtime() endpoint
with fal_client.realtime("your-username/your-app-name") as connection:
    connection.send({"prompt": "Hello, world!"})
    result = connection.recv()
    print(result)
```

```python theme={null}
import asyncio
import fal_client

async def main():
    async with fal_client.realtime_async("your-username/your-app-name") as connection:
        await connection.send({"prompt": "Hello, world!"})
        result = await connection.recv()
        print(result)

asyncio.run(main())
```

### Connecting to Raw WebSocket Endpoints

For endpoints using `is_websocket=True`, use `fal_client.ws_connect()` or `fal_client.ws_connect_async()` for direct WebSocket access:

```python theme={null}
import fal_client

# Connect to a raw WebSocket endpoint
# The path parameter specifies the endpoint path (e.g., "/echo")
with fal_client.ws_connect("your-username/your-app-name", path="/echo") as ws:
    ws.send("Hello, world!")
    for _ in range(3):
        message = ws.recv()
        print(message)
```

```python theme={null}
import asyncio
import fal_client

async def main():
    async with fal_client.ws_connect_async("your-username/your-app-name", path="/echo") as ws:
        await ws.send("Hello, world!")
        for _ in range(3):
            message = await ws.recv()
            print(message)

asyncio.run(main())
```

<Note>
  * For `@fal.realtime()` endpoints: Use `fal_client.realtime()` - serialization is handled automatically.
  * For raw `is_websocket=True` endpoints: Use `fal_client.ws_connect()` with the `path` parameter to specify the endpoint path.
</Note>

## WebRTC Transport

For applications that need direct video/audio streaming (webcam feeds, live game rendering), you can use WebRTC as the transport layer on top of fal's WebSocket infrastructure. WebRTC provides lower latency for media streams compared to sending frames over msgpack.

The pattern uses `@fal.endpoint("/webrtc", is_websocket=True)` to handle WebRTC signaling, while the actual media flows peer-to-peer between the browser and your runner. For a higher-level wrapper that handles the signaling, tracks, and frame batching for you, see the experimental [World Model Accelerator (WMA)](/documentation/development/wma).

<CardGroup cols={2}>
  <Card title="Real-time World Model" icon="globe" href="/examples/video-generation/deploy-realtime-world-model">
    Deploy a live world model with WebRTC video streaming
  </Card>

  <Card title="Real-time Video-to-Video" icon="video" href="/examples/video-generation/deploy-realtime-video-to-video-model">
    Run YOLO detections on a live webcam feed via WebRTC
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Streaming Endpoints" icon="water" href="/documentation/development/streaming">
    Stream progressive results (image previews, video updates) using SSE
  </Card>

  <Card title="Real-time Client Docs" icon="book" href="/documentation/model-apis/inference/real-time">
    Client library documentation for realtime connections
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/development/request-headers.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Request Headers

> Access request headers in your fal App for logging, tracing, and per-request logic.

Every request to your [fal App](/documentation/getting-started/apps-and-execution) passes through the fal gateway before reaching your runner. The gateway injects headers like the request ID and caller identity, and forwards any custom headers the caller included. You can read all of these inside your endpoint handler via `self.current_request.headers.get()`.

Request headers are per-request context, complementing [environment variables](/documentation/development/environment-variables) which are per-runner context. Use headers when you need to identify the specific request or caller (for logging, tracing, or per-user logic), and environment variables for runner-wide information like `FAL_APP_NAME` or `FAL_KEY`.

```python theme={null}
import fal

class MyApp(fal.App):
    machine_type = "GPU-A100"

    @fal.endpoint("/")
    def generate(self, prompt: str) -> dict:
        request_id = self.current_request.headers.get("x-fal-request-id")
        caller_id = self.current_request.headers.get("x-fal-caller-user-id")

        print(f"Request {request_id} from {caller_id}")
        return {"result": "..."}
```

***

## Available Headers

| Header                 | Description                                                                    |
| ---------------------- | ------------------------------------------------------------------------------ |
| `x-fal-request-id`     | Unique identifier for this request. Use for log correlation and debugging.     |
| `x-fal-caller-user-id` | The caller's user ID (hashed for third-party apps). Useful for per-user logic. |
| `x-fal-endpoint`       | The full endpoint path being called (e.g., `your-user/your-app/`).             |

Custom headers passed by the caller are also forwarded to your app. Headers starting with `x-fal-` are reserved for the gateway and cannot be set by callers.

***

## Correlating with External Tools

### Sentry

Attach the request ID to Sentry events so you can find the exact fal request that caused an error:

```python theme={null}
import fal

class MyApp(fal.App):
    machine_type = "GPU-A100"
    requirements = ["sentry-sdk"]

    def setup(self):
        import sentry_sdk
        sentry_sdk.init(dsn="https://your-sentry-dsn")
        self.model = load_model()

    @fal.endpoint("/")
    def generate(self, prompt: str) -> dict:
        import sentry_sdk
        sentry_sdk.set_tag("fal_request_id", self.current_request.headers.get("x-fal-request-id"))
        return {"image": self.model(prompt)}
```

### Structured Logging

Include the request ID in your log output for correlation with fal's built-in [logs](/documentation/development/logging):

```python theme={null}
import fal
import logging

logger = logging.getLogger(__name__)

class MyApp(fal.App):
    machine_type = "GPU-A100"

    @fal.endpoint("/")
    def generate(self, prompt: str) -> dict:
        rid = self.current_request.headers.get("x-fal-request-id")
        logger.info("Processing request", extra={"request_id": rid})

        result = self.model(prompt)

        logger.info("Request complete", extra={"request_id": rid})
        return {"image": result}
```

***

## Custom Headers

Callers can pass custom headers that are forwarded to your app:

```python theme={null}
# Caller passes a custom header
result = fal_client.subscribe("your-user/your-app", arguments={
    "prompt": "a sunset"
}, headers={
    "X-My-Trace-Id": "abc-123",
    "X-My-User-Tier": "premium"
})
```

```python theme={null}
# Your app reads it
@fal.endpoint("/")
def generate(self, prompt: str) -> dict:
    trace_id = self.current_request.headers.get("x-my-trace-id")
    user_tier = self.current_request.headers.get("x-my-user-tier")
    ...
```

<Note>
  Header names are case-insensitive. `X-My-Header` and `x-my-header` both work.
</Note>

## Response Header Size Limit

The total size of all response headers returned by your app is limited to **16 KB**. This includes platform headers injected by fal (like `x-fal-request-id` and `X-Fal-Billable-Units`) and any custom headers your app sets, such as billing units or routing hints from [`provide_hints()`](/documentation/development/advanced/optimize-routing-behavior). If the combined headers exceed 16 KB, the response will fail.

Keep custom header values short. If you use `provide_hints()`, avoid returning large lists of model names or long strings — each hint value contributes to the total header size.

<Note>
  [Platform headers](/documentation/model-apis/common-parameters) like `X-Fal-Request-Timeout`, `X-Fal-No-Retry`, and `X-Fal-Store-IO` are processed by the gateway before reaching your runner. They are not available in `self.current_request.headers`. Only identity headers (`x-fal-request-id`, `x-fal-caller-user-id`, `x-fal-endpoint`) and custom caller headers are forwarded to your app.
</Note>

<Card title="Environment Variables" href="/documentation/development/environment-variables">
  Per-runner context: FAL\_KEY, FAL\_APP\_NAME, FAL\_RUNNER\_STATE, and more
</Card>


# https://fal.ai/docs/documentation/development/streaming.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming Endpoints

> Stream progressive results to clients using Server-Sent Events (SSE) for real-time feedback during long-running operations.

Streaming endpoints let you send progressive results to clients as your model processes a request, rather than waiting for the full result. This is essential for long-running operations where users benefit from seeing incremental progress: image generation previews at each diffusion step, intermediate 3D geometry, or token-by-token LLM output. Callers consume the stream using the [`stream()` method](/documentation/model-apis/inference/streaming) in the fal client SDKs.

Under the hood, streaming uses [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) (SSE), a one-way protocol where the server pushes events to the client over a single HTTP connection. You define a streaming endpoint by returning a FastAPI `StreamingResponse` with SSE-formatted events from an `@fal.endpoint("/stream")` method. For bidirectional communication where clients send multiple inputs over a persistent connection, see [Realtime Endpoints](/documentation/development/realtime) instead.

## Streaming vs Realtime

Streaming and realtime endpoints serve different interaction patterns. Streaming is one-way (server to client) and suited for progressive output from a single request. Realtime is bidirectional (client and server) and suited for interactive applications with back-to-back requests over a persistent WebSocket connection.

| Feature        | Streaming (SSE)              | Realtime (WebSocket)                    |
| -------------- | ---------------------------- | --------------------------------------- |
| **Direction**  | One-way (server to client)   | Bidirectional                           |
| **Connection** | New connection per request   | Persistent, reusable                    |
| **Best for**   | Progressive output, previews | Interactive apps, back-to-back requests |
| **Protocol**   | JSON over SSE                | Binary msgpack                          |

Choose streaming when you want to show generation progress (diffusion steps, [progressive 3D rendering](/examples/video-generation/deploy-3d-progressive-rendering)) or stream LLM tokens, and the client sends a single request per generation. Choose [realtime](/documentation/development/realtime) when users interact continuously, like drawing on a canvas that triggers re-generation on every stroke.

## Example: Streaming Intermediate Steps with SDXL

This example shows how to stream intermediate image previews during Stable Diffusion XL generation. It uses a TinyVAE for fast preview decoding and the pipeline's callback system to capture progress at each step.

```python theme={null}
import fal
import json
import base64
import random
from io import BytesIO
from typing import Any
from queue import Queue

import torch
from pydantic import BaseModel, Field
from fastapi.responses import StreamingResponse


class StreamInput(BaseModel):
    prompt: str = Field(description="The prompt to generate an image from.")
    negative_prompt: str = Field(default="blurry, low quality")
    num_inference_steps: int = Field(default=20, ge=1, le=50)
    width: int = Field(default=1024)
    height: int = Field(default=1024)
    seed: int | None = Field(default=None)


class StreamingSDXLApp(fal.App):
    machine_type = "GPU-A100"

    requirements = [
        "accelerate==1.4.0",
        "diffusers==0.30.3",
        "torch==2.6.0+cu124",
        "transformers==4.47.1",
        "--extra-index-url",
        "https://download.pytorch.org/whl/cu124",
    ]

    def setup(self):
        from diffusers import AutoencoderTiny, StableDiffusionXLPipeline

        # Load the main SDXL pipeline
        self.pipeline = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
            variant="fp16",
        ).to("cuda")

        # TinyVAE for fast preview generation (much faster than full VAE)
        self.tiny_vae = AutoencoderTiny.from_pretrained(
            "madebyollin/taesdxl",
            torch_dtype=torch.float16,
        ).to("cuda")

    @fal.endpoint("/stream")
    def stream_image(self, input: StreamInput) -> StreamingResponse:
        seed = input.seed if input.seed is not None else random.randint(0, 2**32 - 1)
        generator = torch.Generator(device="cuda").manual_seed(seed)

        # Queue to pass events from callback to the streaming generator
        event_queue: Queue[dict[str, Any] | None] = Queue()

        def pipeline_callback(
            pipe: Any,
            step: int,
            timestep: int,
            callback_kwargs: dict[str, Any],
        ) -> dict[str, Any]:
            """Called after each inference step to stream preview."""
            # Only stream every 5 steps to reduce overhead
            if step > 0 and step % 5 != 0:
                return callback_kwargs

            latents = callback_kwargs["latents"]

            # Decode latents to image using TinyVAE (fast!)
            with torch.no_grad():
                image = self.tiny_vae.decode(
                    latents / self.tiny_vae.config.scaling_factor,
                    return_dict=False,
                )[0]
                image = self.pipeline.image_processor.postprocess(
                    image, output_type="pil"
                )[0]

            # Convert to base64 data URI
            buffer = BytesIO()
            image.save(buffer, format="JPEG", quality=70)
            data_uri = f"data:image/jpeg;base64,{base64.b64encode(buffer.getvalue()).decode()}"

            # Stream the image in the format the playground expects
            event_queue.put({
                "image": {
                    "url": data_uri,
                    "content_type": "image/jpeg",
                }
            })

            return callback_kwargs

        def event_stream():
            import threading

            def run_pipeline():
                # Run the pipeline with our callback
                result = self.pipeline(
                    prompt=input.prompt,
                    negative_prompt=input.negative_prompt,
                    width=input.width,
                    height=input.height,
                    num_inference_steps=input.num_inference_steps,
                    generator=generator,
                    callback_on_step_end=pipeline_callback,
                )

                # Get final image
                final_image = result.images[0]
                buffer = BytesIO()
                final_image.save(buffer, format="JPEG", quality=95)
                data_uri = f"data:image/jpeg;base64,{base64.b64encode(buffer.getvalue()).decode()}"

                # Send final result in the same format
                event_queue.put({
                    "image": {
                        "url": data_uri,
                        "content_type": "image/jpeg",
                    }
                })
                event_queue.put(None)  # Signal completion

            # Run pipeline in background thread
            thread = threading.Thread(target=run_pipeline)
            thread.start()

            # Yield events as they come in
            while True:
                event = event_queue.get()
                if event is None:
                    break
                yield f"data: {json.dumps(event)}\n\n"

            thread.join()

        return StreamingResponse(
            event_stream(),
            media_type="text/event-stream",
        )

    @fal.endpoint("/")
    def generate(self, input: StreamInput) -> dict[str, Any]:
        """Standard non-streaming endpoint."""
        seed = input.seed if input.seed is not None else random.randint(0, 2**32 - 1)
        generator = torch.Generator(device="cuda").manual_seed(seed)

        result = self.pipeline(
            prompt=input.prompt,
            negative_prompt=input.negative_prompt,
            width=input.width,
            height=input.height,
            num_inference_steps=input.num_inference_steps,
            generator=generator,
        )

        return {"image": result.images[0], "seed": seed}
```

### Example Details

This example uses `madebyollin/taesdxl`, a TinyVAE that decodes intermediate latents roughly 10x faster than the full VAE. The diffusers `callback_on_step_end` hook captures latents at each denoising step, but the callback only streams every 5 steps to balance responsiveness with overhead. A thread-safe queue passes events from the pipeline thread (which runs inference) to the streaming generator (which yields SSE events to the client).

<Tip>
  **Playground Image Display Format**

  For images to display correctly in the fal playground, you **must** include both `url` and `content_type`:

  ```python theme={null}
  {"image": {"url": "data:image/jpeg;base64,...", "content_type": "image/jpeg"}}
  ```

  The playground uses `content_type` to determine how to render the result. Without it, the result will be displayed as raw JSON instead of an image.

  For multiple images, use an array:

  ```python theme={null}
  {"images": [{"url": "...", "content_type": "image/jpeg"}, ...]}
  ```
</Tip>

## Client-Side Usage

<Note>
  **Endpoint Path Requirement**

  The `fal_client.stream()` (Python) and `fal.stream()` (JavaScript) functions automatically append `/stream` to your endpoint ID. This means your app **must** define a streaming endpoint at `/stream` using `@fal.endpoint("/stream")`.

  For example, calling `fal_client.stream("your-username/your-app-name", ...)` will connect to `https://fal.run/your-username/your-app-name/stream`.
</Note>

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  for event in fal_client.stream(
      "your-username/your-app-name",
      arguments={"prompt": "a beautiful sunset", "num_inference_steps": 20},
  ):
      image_url = event.get("image", {}).get("url")
      if image_url:
          print(f"Received image preview")
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const stream = await fal.stream("your-username/your-app-name", {
    input: {
      prompt: "a beautiful sunset",
      num_inference_steps: 20,
    },
  });

  for await (const event of stream) {
    if (event.image?.url) {
      console.log("Received image preview");
    }
  }

  const finalResult = await stream.done();
  ```
</CodeGroup>

## Key Points

Your streaming endpoint must return a FastAPI `StreamingResponse` with `media_type="text/event-stream"`. Each event is yielded as `f"data: {json.dumps(payload)}\n\n"` (note the double newline, which is part of the SSE spec). For images to display in the Playground, include both `url` and `content_type` in the event payload. Throttle your streaming to avoid sending every intermediate result, and use lower quality or resolution for previews to save bandwidth.

## Next Steps

<CardGroup cols={3}>
  <Card title="Realtime Endpoints" href="/documentation/development/realtime">
    Bidirectional WebSocket communication for interactive apps
  </Card>

  <Card title="3D Progressive Rendering" href="/examples/video-generation/deploy-3d-progressive-rendering">
    Stream voxel data in real-time during 3D diffusion
  </Card>

  <Card title="Distributed Streaming" href="/documentation/serverless/distributed/streaming">
    Stream results from multi-GPU workers
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/development/test-models-and-endpoints.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Test Models and Endpoints

> Test your fal App endpoints programmatically using AppClient, which deploys an ephemeral instance and runs your tests against live infrastructure.

Before [deploying to production](/documentation/deployment/deploy-to-production), you want to verify that your endpoints produce correct outputs, handle edge cases gracefully, and perform within acceptable latency. The `AppClient` in the fal SDK gives you a way to do this programmatically -- it deploys your app to fal's serverless infrastructure in ephemeral mode, runs your tests against the live endpoints (including GPU execution, `setup()`, and the full request pipeline), and cleans up the deployment when testing is complete.

This means your tests run against the real environment your app will use in production, not a mocked local version. If your model loads correctly in `setup()`, processes inputs through your endpoint, and returns valid outputs, you can be confident the deployed version will behave the same way. You can integrate these tests into your CI pipeline to catch regressions before they reach production.

## Testing with AppClient

`AppClient` connects to your app class and exposes its endpoints as callable methods. It handles deployment, connection, and teardown automatically via a context manager.

```python theme={null}
import fal
from pydantic import BaseModel, Field
from fal.toolkit import Image

class ImageModelInput(BaseModel): # ...

class MyApp(fal.App):  # ...
    keep_alive = 300

    def setup(self): # ...

    @fal.endpoint("/")
    def generate_image(self, request: ImageModelInput) -> Image: # ...
```

Now you can write comprehensive tests for this app:

```python theme={null}
def test_myapp():
    with fal.app.AppClient.connect(MyApp) as client:
        result = client.generate_image(prompt="A cat holding a sign that says hello world")
        assert result is not None
        assert hasattr(result, 'url')
```

## Running locally with `fal run --local`

When you want a tighter feedback loop than an ephemeral deployment can give you, `fal run --local` executes your function or app on your own machine instead of provisioning a remote runner. For apps, this starts the FastAPI server on `localhost` so you can hit your endpoints directly:

```bash theme={null}
fal run --local path/to/myfile.py::MyApp
```

The startup logs print the local URL. From another terminal, call your endpoints with any HTTP client:

```bash theme={null}
curl -X POST http://localhost:8080/ \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A cat holding a sign that says hello world"}'
```

This skips the remote machine spin-up entirely, which makes it well suited for quick checks while you're tweaking endpoint code, validating request and response shapes, or stepping through your app with a local debugger.

Because the app runs in your local Python environment, you are responsible for having the right dependencies and hardware available — `setup()` runs on your machine, and there is no GPU unless your machine has one. When you need to verify behavior on the real serverless environment (containers, GPUs, scaling, cold starts), use `AppClient` as shown above instead.


# https://fal.ai/docs/documentation/development/use-custom-container-image.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use a Custom Container Image

> Bring your own Dockerfile to fal for full control over system packages, CUDA versions, and base images.

When the [fal Runtime](/documentation/development/fal-runtime) does not cover your needs, you can bring your own Dockerfile. This gives you full control over system packages, base images, CUDA versions, and non-Python dependencies while still using fal's endpoint system, scaling, and observability. Your Dockerfile is defined inline as a string in your app class, and fal handles the build, caching, and deployment.

If you are migrating an existing Docker-based server rather than building a new app, see [Deploy an Existing Server](/documentation/development/migrate-external-docker-server) which covers the `exposed_port` pattern for zero-code migration. For an overview of when to use a Dockerfile versus pip requirements, see [Environment and Runtime](/documentation/development/container-setup).

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=1000&end=1029&autoplay=1'><img src='/docs/images/video-thumbs/use-custom-container-image.jpg' alt='Custom Container Images - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Basic Usage

Use `ContainerImage.from_dockerfile_str()` to define your Dockerfile inline, or `ContainerImage.from_dockerfile()` to reference a file on disk.

```python theme={null}
import fal
from fal.container import ContainerImage
from fal.toolkit import Image, optimize
from pydantic import BaseModel, Field

dockerfile_str = """
FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
RUN apt-get update && apt-get install -y ffmpeg curl && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir diffusers transformers accelerate
"""

class Input(BaseModel):
    prompt: str = Field(description="The prompt to generate an image from.")

class Output(BaseModel):
    image: Image

class MyApp(fal.App):
    machine_type = "GPU-A100"
    image = ContainerImage.from_dockerfile_str(dockerfile_str)

    def setup(self):
        import torch
        from diffusers import AutoPipelineForText2Image

        self.pipeline = AutoPipelineForText2Image.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
            variant="fp16",
        ).to("cuda")

        self.pipeline.unet = optimize(self.pipeline.unet)
        self.pipeline.vae = optimize(self.pipeline.vae)

    @fal.endpoint("/")
    def generate(self, input: Input) -> Output:
        result = self.pipeline(prompt=input.prompt, num_inference_steps=30)
        return Output(image=Image.from_pil(result.images[0]))
```

<Note>
  For a complete walkthrough deploying a containerized app, see the [custom containers example](/examples/deploy-models-with-custom-containers).
</Note>

## fal Platform Requirements

fal injects a small runtime into your container to manage serialization, file uploads, and endpoint serving. Your Dockerfile must satisfy two requirements:

1. **`curl` must be installed.** fal uses it during runner startup.
2. **`pydantic`, `protobuf`, and `boto3` must be compatible with the fal SDK.** The easiest way to ensure this is to install the `fal` package itself as the last step in your Dockerfile, which brings in the correct versions. Alternatively, install these three packages last so they override any conflicting versions from your other dependencies.

```dockerfile theme={null}
FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime

RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# Install your application dependencies first
RUN pip install --no-cache-dir torch transformers diffusers

# Install fal last to ensure compatible versions of pydantic, protobuf, boto3
RUN pip install --no-cache-dir fal
```

## COPY and Build Context

<Warning>
  **Experimental Feature** - COPY and ADD support for local files is currently experimental.
</Warning>

fal supports standard Docker `COPY` and `ADD` commands to include local files in your container builds. Paths are resolved relative to the current working directory (where you run `fal deploy`), or you can specify a custom `context_dir`.

```python theme={null}
dockerfile_str = """
FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ ./src/
"""

class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str(dockerfile_str)
```

You can customize the build context directory for monorepos or shared code:

```python theme={null}
image = ContainerImage.from_dockerfile_str(
    dockerfile_str,
    context_dir=Path(__file__).parent / "docker_context"
)
```

### Supported COPY Patterns

```dockerfile theme={null}
# Entire directory
COPY . .

# Specific files and directories
COPY requirements.txt .
COPY src/ ./src/

# Glob patterns
COPY *.py /app/
COPY config/*.json /app/config/

# Multiple sources
COPY file1.py file2.py /app/
```

<Note>
  Files uploaded via `app_files` are already in the build context and will not be re-uploaded. fal uses content-based hashing to deduplicate files. The file containing your `fal.App` class is not part of the container image - it is pickled and sent at deploy time, so changes to your app code do not trigger a container rebuild.
</Note>

### .dockerignore

Create a `.dockerignore` file in your project to exclude files from the build context, or define patterns in code:

```python theme={null}
# Inline patterns
image = ContainerImage.from_dockerfile_str(dockerfile_str, dockerignore=[
    ".git", "*.pyc", "__pycache__", ".env", "data/"
])

# Or reference an external file
image = ContainerImage.from_dockerfile_str(dockerfile_str,
    dockerignore_path=".dockerignore"
)

# Or use the add_dockerignore method
image = ContainerImage.from_dockerfile_str(dockerfile_str)
image.add_dockerignore(patterns=[".git", "*.pyc", ".env"])
image.add_dockerignore(path="docker/.dockerignore")
```

If no `.dockerignore` exists, fal uses sensible defaults that exclude common development artifacts.

### Alternative: Upload Large Files to CDN

For very large files or files that change independently from your container, you can upload them to fal's CDN and download them during the build:

```python theme={null}
from fal.toolkit import File

json_url = File.from_path("my-file.json", repository="cdn").url

dockerfile_str = f"""
FROM python:3.11-slim
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
RUN curl '{json_url}' > my-file.json
"""
```

You can also use Docker's `ADD` command to download directly from a URL:

```python theme={null}
req_url = File.from_path("requirements.txt", repository="cdn").url

dockerfile_str = f"""
FROM python:3.11-slim
ADD {req_url} /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt
"""
```

### Cache Behavior

Container images are cached based on Dockerfile content, build secrets, and the content hash of all context files. Changing any local file (except the app file itself) or a secret triggers a rebuild. The app file containing your `fal.App` class is not baked into the image - it is pickled and sent at deploy time, so changes to your app code do not trigger a container rebuild.

To force a rebuild, pass `--no-cache`:

```bash theme={null}
fal deploy --no-cache path/to/my_app.py::MyApp
```

## Build Secrets

Use [BuildKit secret mounts](https://docs.docker.com/build/building/secrets/#secret-mounts) to pass secrets at build time without baking them into image layers. Secret values prefixed with `$` are resolved from your [fal secrets](/documentation/development/manage-secrets-securely).

```python theme={null}
class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        FROM python:3.11
        RUN --mount=type=secret,id=pip_token \\
            pip install --extra-index-url \\
            https://$(cat /run/secrets/pip_token)@pypi.company.com/simple \\
            my-private-package
    """, secrets={"pip_token": "$MY_PIP_TOKEN"})
```

## Build Args

Use `build_args` to pass standard Docker build arguments. Build args are not secret and are visible in image layers.

```python theme={null}
class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        ARG PY_VERSION=3.11
        FROM python:${PY_VERSION}-slim
        ARG EXTRA_INDEX_URL
        RUN pip install --no-cache-dir --extra-index-url ${EXTRA_INDEX_URL} mypkg
    """, build_args={
        "PY_VERSION": "3.11",
        "EXTRA_INDEX_URL": "https://example.com/simple",
    })
```

## Using Private Registries

If your base image is hosted on a private registry (Docker Hub, Google Artifact Registry, or AWS ECR), you provide credentials via the `registries` parameter. See [Private Registries](/documentation/development/private-registries) for step-by-step authentication setup.

## ContainerImage Parameters

Both `ContainerImage.from_dockerfile_str()` and `ContainerImage.from_dockerfile()` accept the following parameters:

| Parameter           | Type              | Default           | Description                                        |
| ------------------- | ----------------- | ----------------- | -------------------------------------------------- |
| `build_args`        | `Dict[str, str]`  | `{}`              | Docker `--build-arg` values                        |
| `secrets`           | `Dict[str, str]`  | `{}`              | BuildKit `--secret` values (not baked into layers) |
| `registries`        | `Dict[str, Dict]` | `{}`              | Private registry credentials                       |
| `context_dir`       | `Path`            | Current directory | Build context directory                            |
| `dockerignore`      | `List[str]`       | Default patterns  | Patterns to exclude from context                   |
| `dockerignore_path` | `Path`            | None              | Path to `.dockerignore` file                       |
| `compression`       | `str`             | `"gzip"`          | Image layer compression (`"gzip"`, `"zstd"`)       |
| `force_compression` | `bool`            | `False`           | Force re-compression of all layers                 |

### build\_args

Docker build arguments passed as `--build-arg` during image build. Use to parameterize your Dockerfile.

```python theme={null}
image = ContainerImage.from_dockerfile_str("""
    ARG CUDA_VERSION=12.1
    FROM nvidia/cuda:${CUDA_VERSION}-runtime-ubuntu22.04
    RUN pip install torch
""", build_args={"CUDA_VERSION": "12.4"})
```

### secrets

Build-time secrets mounted via BuildKit `--secret`. Unlike `build_args`, secrets are not baked into image layers. Use for private package indexes or git tokens. Values prefixed with `$` are resolved from your [fal secrets](/documentation/development/manage-secrets-securely) at build time.

```python theme={null}
image = ContainerImage.from_dockerfile_str("""
    FROM python:3.11
    RUN --mount=type=secret,id=pip_token \\
        pip install --extra-index-url \\
        https://$(cat /run/secrets/pip_token)@pypi.company.com/simple \\
        my-private-package
""", secrets={"pip_token": "$MY_PIP_TOKEN"})
```

### context\_dir

The build context directory. Files from this directory are available via `COPY` in your Dockerfile. Defaults to the current working directory.

```python theme={null}
image = ContainerImage.from_dockerfile("docker/Dockerfile",
    context_dir="./my-project"
)
```

### dockerignore / dockerignore\_path

Inline list of patterns to exclude from the build context, or a path to an external `.dockerignore` file. See the [.dockerignore section](#dockerignore) above for examples.

## Pre-Deploy Checklist

Before deploying, verify:

* All package versions are pinned
* `curl` is installed
* fal-compatible versions of pydantic, protobuf, and boto3 are installed (either via `pip install fal` or by installing them last)
* Container builds successfully with `fal run`

## Next Steps

For production-ready Dockerfile examples and optimization tips, see [Docker Templates and Best Practices](/documentation/development/docker-templates). To optimize container image size and cold start times, see [Optimize Container Images](/documentation/serverless/optimizations/optimize-container-images).


# https://fal.ai/docs/documentation/development/use-kv-store.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use KV Store

> KVStore is a simple key-value storage for sharing state across serverless runners with zero setup required.

KVStore provides a way to share small string values across all your serverless runners. It supports two operations: `get` and `set`. Use it for caching computation results, sharing configuration between runners, or storing small pieces of state that multiple runners need to read. It requires no setup and uses automatic authentication with your fal credentials.

Unlike [persistent storage](/documentation/development/use-persistent-storage) on `/data` (a distributed filesystem for large files like model weights), KVStore is a remote key-value API accessed over HTTP. It is best suited for small, frequently-read values where you need cross-runner consistency. It does not support deletion, expiration, listing keys, or atomic operations, so it is not appropriate for counters, locks, or anything requiring transactional guarantees.

## API Reference

### Initialize KVStore

```python theme={null}
from fal.toolkit.kv import KVStore

kv = KVStore("myapp")  # "myapp" is your namespace
```

Each namespace is isolated - different `db_name` values create separate key-value stores.

### Methods

**`get(key: str) -> Optional[str]`**

Retrieve a value from the store. Returns `None` if the key doesn't exist.

```python theme={null}
value = kv.get("my-key")
if value is None:
    print("Key not found")
```

**`set(key: str, value: str) -> None`**

Store a string value. The value must be a string - use `json.dumps()` for objects.

```python theme={null}
import json

# Store a string
kv.set("my-key", "my-value")

# Store an object as JSON
kv.set("config", json.dumps({"enabled": True, "limit": 100}))
```

## Basic Example

```python theme={null}
import fal
import json
from fal.toolkit.kv import KVStore

class MyApp(fal.App):
    def setup(self):
        self.kv = KVStore("myapp")
    
    @fal.endpoint("/")
    def process(self, input: Input):
        # Check cache
        cache_key = f"result-{input.id}"
        cached = self.kv.get(cache_key)
        
        if cached:
            return json.loads(cached)
        
        # Compute and cache result
        result = self.expensive_operation(input)
        self.kv.set(cache_key, json.dumps(result))
        
        return result
```

## Common Use Cases

### Caching API Responses

Cache external API calls to reduce latency and costs:

```python theme={null}
class MyApp(fal.App):
    def setup(self):
        self.kv = KVStore("api-cache")
    
    @fal.endpoint("/")
    def process(self, input: Input):
        cache_key = f"weather:{input.city}"
        
        # Check cache
        cached = self.kv.get(cache_key)
        if cached:
            return json.loads(cached)
        
        # Fetch from external API
        weather = requests.get(f"https://api.weather.com/{input.city}").json()
        self.kv.set(cache_key, json.dumps(weather))
        
        return weather
```

### Caching Computation Results

Store results of expensive operations to avoid recomputation:

```python theme={null}
class MyApp(fal.App):
    def setup(self):
        self.kv = KVStore("compute-cache")
    
    @fal.endpoint("/")
    def process(self, input: Input):
        cache_key = f"result:{input.video_id}"
        
        cached = self.kv.get(cache_key)
        if cached:
            return json.loads(cached)
        
        # Expensive video processing
        result = self.process_video(input.video_url)
        self.kv.set(cache_key, json.dumps(result))
        
        return result
```

## Limitations

KVStore is deliberately simple. It only supports `get` and `set` on string values. There is no `delete`, no key listing/scanning, no TTL or expiration, and no atomic operations (no increment, no compare-and-swap). Values persist indefinitely until overwritten.

If multiple runners write to the same key simultaneously, the last write wins with no conflict detection. This makes KVStore unsuitable for counters, locks, rate limiting, or anything requiring atomicity. For those use cases, use an external database like Redis or PostgreSQL.

For large files (model weights, datasets), use the [`/data` volume](/documentation/development/use-persistent-storage) instead.


# https://fal.ai/docs/documentation/development/use-persistent-storage.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Persistent Storage

> Store model weights, datasets, and files on the shared /data volume that persists across runners and deployments.

Every fal [runner](/documentation/getting-started/runners-and-caching) has access to a persistent `/data` volume. This is a distributed filesystem that is shared across all your apps and runners, linked to your fal account. Files written to `/data` persist between requests, across runner restarts, and across deployments. Use it to store model weights, datasets, configuration files, and any other data your apps need.

The `/data` volume is the primary mechanism for avoiding repeated downloads during [cold starts](/documentation/serverless/optimizations/optimize-cold-starts). When a new runner starts and calls [setup()](/documentation/development/app-lifecycle), it can load model weights from `/data` instead of downloading them from scratch. Because the volume is backed by a multi-layer cache (local NVME, distributed datacenter cache, and a global object store), subsequent reads are fast even on fresh nodes. For downloading files and model weights to `/data`, see [Downloading Models and Files](/documentation/development/download-model-weights-and-files).

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=923&end=1000&autoplay=1'><img src='/docs/images/video-thumbs/use-persistent-storage.jpg' alt='Files UI - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Using `/data` in Your App

The `/data` directory is automatically mounted on every runner. Files you write there persist until you delete them. A common pattern is to check whether a file already exists before downloading it, so that only the first runner pays the download cost.

```python theme={null}
import fal
from pathlib import Path

DATA_DIR = Path("/data/mnist")

class MyModel(fal.App):
    requirements = ["torch>=2.0.0", "torchvision"]
    machine_type = "GPU"

    def setup(self):
        import torch
        from torchvision import datasets

        already_present = DATA_DIR.exists()
        if already_present:
            print("Test data is already downloaded, skipping download!")

        test_data = datasets.FashionMNIST(
            root=DATA_DIR,
            train=False,
            download=not already_present,
        )
        ...
```

When you invoke this app for the first time, Torch downloads the test dataset to `/data`. Subsequent invocations, even those on new runners after the previous one shut down, skip the download and load directly from the cached files.

<Note>
  For HuggingFace libraries, fal automatically sets `HF_HOME` to `/data/.cache/huggingface`, so all downloaded models from `transformers`, `diffusers`, and `huggingface_hub` are persisted without any extra configuration.
</Note>

Since `/data` is shared across all runners, you should be careful when multiple runners write to the same path simultaneously. The recommended pattern is to write to a temporary file beside the final destination, then use `os.rename` to move it into place. This makes the operation quasi-atomic and prevents other runners from reading an incomplete file.

```python theme={null}
import tempfile, os
from pathlib import Path

WEIGHTS_FILE = Path("/data/weights.safetensors")

class MyModel(fal.App):
    def setup(self):
        if not WEIGHTS_FILE.exists():
            with tempfile.NamedTemporaryFile(delete=False, dir="/data") as temp_file:
                # download the weights to temp file
                ...
                os.rename(temp_file.name, WEIGHTS_FILE)
        ...
```

When loading model weights that span many files (as most `from_pretrained()` calls do), the sequential loading process does not take full advantage of the filesystem's parallel capabilities. You can speed it up significantly by pre-reading all the files in parallel before loading, which forces chunks into the local cache:

```python theme={null}
import subprocess

MODEL_DIR = "/data/models/deepseek-ai"
subprocess.check_call(
    f"find '{MODEL_DIR}' -type f | xargs -P 32 -I {{}} cat {{}} > /dev/null",
    shell=True
)
```

For a dedicated guide on this technique, see [Parallel File Loading](/documentation/serverless/optimizations/parallel-file-loading).

## Uploading Files to `/data`

Outside of a running app, you can upload files to `/data` through the dashboard, CLI, REST API, or a one-off function.

The [Dashboard > Files](https://fal.ai/dashboard/files) page provides a visual interface for dragging and dropping files, uploading from URLs, organizing folders, and managing your stored files.

From the CLI, use `fal files` commands:

```bash theme={null}
fal files list
fal files list models/
fal files upload local-file.bin remote-path/file.bin
```

For direct integration, the Platform APIs provide endpoints for uploading, listing, and downloading files. See the [Platform API Reference](/api-reference/platform-apis/for-serverless) for the full specification.

To upload files programmatically (for example, downloading weights from a URL to `/data` before deploying your app), use a `@fal.function` that writes directly to the filesystem:

```python theme={null}
import fal

@fal.function(machine_type="S")
def upload_weights():
    import urllib.request
    urllib.request.urlretrieve(
        "https://example.com/model-weights.safetensors",
        "/data/models/weights.safetensors"
    )
    print("Weights uploaded to /data")
```

This runs on a fal runner with access to `/data`, so the downloaded file is immediately available to all your apps.

## How It Works

The `/data` volume is mounted at the same path on every runner in your account. It is eventually consistent, meaning that a file written by one runner may take a moment to appear on another runner in a different datacenter, though within the same datacenter propagation is nearly instant.

| Property          | Value                                       |
| ----------------- | ------------------------------------------- |
| **Mount path**    | `/data` on all runners                      |
| **Shared across** | All apps and runners in your account        |
| **Consistency**   | Eventually consistent                       |
| **Max file size** | Up to 50 GB (resumable), \~1 TB (multipart) |
| **Persistence**   | Files persist until you delete them         |

Under the hood, each file is split into 4MB chunks identified by their hash and saved to a global object store. A metadata layer tracks the mapping between file paths and chunks, making operations like renames atomic and fast. The volume features two caching layers: a local cache on the node using RAID 5 NVME drives (10-15 GB/s), and a distributed cache across all servers in the datacenter using a 100 Gbps network (6-8 GB/s). A cache miss at both levels falls through to the backing object store (1.5-8 GB/s). This is why parallel reads are so much faster than sequential ones: each chunk can be fetched from a different cache node simultaneously.

When your app generates output files (images, videos, audio) and returns them through `fal.toolkit.Image` or `fal.toolkit.File`, those are uploaded to fal's CDN and returned as public URLs. CDN files are separate from `/data` storage. To control how long CDN files are retained, see [Media Expiration](/documentation/model-apis/media-expiration). For small key-value data (configuration, cached API responses, session state), fal also provides [KVStore](/documentation/development/use-kv-store) which offers faster access for data up to 25 MB per value.


# https://fal.ai/docs/documentation/development/wma.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# World Model Accelerator (WMA)

> Experimental fal primitive for interactive world models over a peer-to-peer WebRTC stream between your runners and end users.

<Warning>
  WMA is experimental and the public API may change. First-party client libraries for the browser and native platforms are not yet released.
</Warning>

WMA is fal's interface for running interactive world models over a bidirectional WebRTC stream. A runner on fal accepts a WebRTC session, produces video frames, and ships them back to a browser or native client while the session stays open. fal hosts a bridge at `wma.fal.run` that the client first talks to, but the bridge is only used to establish the connection. Once signaling is done, media flows peer-to-peer between the runner and the client.

There are two ways to build a WMA app depending on how much of the transport layer you want to own:

* **`fal.RealtimeApp`** is the high-level abstraction. You handle frames in Python and fal handles the WebRTC plumbing, session lifecycle, and batching helpers.
* **`fal.App` with a `/start-session` endpoint** is the raw path. You pick your own WebRTC library and run the SDP exchange yourself. The WMA bridge POSTs the client's offer to this endpoint and streams the response back, holding the HTTP connection open for the full lifetime of the session.

## Using `fal.RealtimeApp`

`fal.RealtimeApp` is the fastest way to get a world model running. You define an `on_connect` handler, attach a track to the session, and let fal manage the rest.

```python theme={null}
from typing import TypedDict
from fal.wma import RealtimeApp, BatchedFnTrack


class SessionParams(TypedDict, total=False):
    prompt: str


class InfiniteWorlds(RealtimeApp):
    async def on_connect(self, event_handler, session_params: SessionParams):
        @event_handler.on("track")
        def on_track(track):
            if track.kind != "video":
                return

            event_handler.add_track(
                BatchedFnTrack(
                    track,
                    batch_size=4,
                    fn=lambda frames: do_inference(frames, session_params),
                )
            )
```

### `on_connect(event_handler, session_params)`

`on_connect` is called once per incoming session. It gives you two objects:

* `event_handler` registers track and data-channel callbacks, and attaches outbound tracks back to the peer.
* `session_params` is a mutable dict shared with the client for the duration of the session. See [Session parameters](#session-parameters) below.

Register `track` callbacks on `event_handler` to react to the media the client publishes (for example, the browser webcam). Call `event_handler.add_track(...)` to push a track back to the peer.

### `BatchedFnTrack`

`BatchedFnTrack` is a custom track that buffers frames from a source track, groups them by `batch_size`, and runs your inference function on each batch. The function receives the batch and returns a numpy array or a Pillow image per frame, which WMA then encodes back into the outbound track.

```python theme={null}
BatchedFnTrack(
    source_track,        # the inbound track (e.g. the browser webcam)
    batch_size=4,        # number of frames to group before running fn
    fn=run_inference,    # callable over the batched frames
)
```

Use it when your model is cheaper to run in batches, or when you want the inference cadence decoupled from the inbound frame rate.

### Session parameters

`session_params` is a dynamic dict that mutates over the lifetime of a session. When the client sends a payload like `{"prompt": "..."}` over the data channel, the matching key on `session_params` updates in place. Your inference function can read the latest value on every batch without wiring up a separate queue.

Type it with `TypedDict` to document the fields your app consumes:

```python theme={null}
class SessionParams(TypedDict, total=False):
    prompt: str
    guidance_scale: float
```

Any field that is not sent by the client is simply absent, so treat `session_params` as partial and provide defaults at the call site.

## Using a raw `fal.App` with `/start-session`

If you want to use a specific WebRTC library, own your media pipeline, or drop WMA into an existing `fal.App`, skip `fal.RealtimeApp` and expose a `/start-session` endpoint. WMA treats this endpoint as a streaming endpoint: the first SSE event you yield is your SDP answer, and the HTTP response stays open for the entire session. When your peer connection closes or the client drops, the generator exits and everything tears down together.

This ties the session lifetime directly to the HTTP request lifetime. You don't track sessions in a dict, you don't manage heartbeats, and any cleanup you put in a `finally` block runs when the session ends, whether the peer closed cleanly or the client disconnected.

```python theme={null}
import asyncio
import json

import fal
from pydantic import BaseModel
from fastapi.responses import StreamingResponse


class OfferRequest(BaseModel):
    sdp: str
    type: str
    session_id: str


class GrayscaleTrack:
    """Wraps a video track and converts each frame to grayscale."""

    kind = "video"

    def __init__(self, track):
        self._track = track
        self.id = track.id

    async def recv(self):
        import av
        frame = await self._track.recv()
        img = frame.to_ndarray(format="bgr24")
        import numpy as np
        gray = np.mean(img, axis=2, keepdims=True).astype(np.uint8)
        img_gray = np.broadcast_to(gray, img.shape).copy()
        new_frame = av.VideoFrame.from_ndarray(img_gray, format="bgr24")
        new_frame.pts = frame.pts
        new_frame.time_base = frame.time_base
        return new_frame

    def stop(self):
        self._track.stop()


class GrayscaleDemo(fal.App, name="grayscale-demo"):
    requirements = ["aiortc", "numpy"]

    max_multiplexing = 10
    keepalive = 3600
    machine_type = "M"

    @fal.endpoint("/start-session")
    async def start_session(self, request: OfferRequest) -> StreamingResponse:
        from aiortc import RTCPeerConnection, RTCSessionDescription

        pc = RTCPeerConnection()
        dc = pc.createDataChannel("ping")

        @dc.on("message")
        def on_dc_message(message):
            d = json.loads(message)
            if d.get("type") == "ping":
                dc.send(json.dumps({"type": "pong", "client_ts": d["ts"]}))

        @pc.on("track")
        def on_track(track):
            if track.kind == "video":
                pc.addTrack(GrayscaleTrack(track))

        await pc.setRemoteDescription(
            RTCSessionDescription(sdp=request.sdp, type=request.type)
        )
        answer = await pc.createAnswer()
        await pc.setLocalDescription(answer)

        closed = asyncio.Event()

        @pc.on("connectionstatechange")
        def _on_state_change():
            if pc.connectionState in ("closed", "failed", "disconnected"):
                closed.set()

        async def event_stream():
            try:
                # First event: hand the SDP answer back to the client.
                yield "data: " + json.dumps({
                    "sdp": pc.localDescription.sdp,
                    "type": pc.localDescription.type,
                    "session_id": request.session_id,
                }) + "\n\n"

                # Hold the request open while the peer connection is alive.
                # Emit an SSE comment every 15s so intermediaries don't
                # time the connection out.
                while not closed.is_set():
                    try:
                        await asyncio.wait_for(closed.wait(), timeout=15)
                    except asyncio.TimeoutError:
                        yield ": keepalive\n\n"
            finally:
                await pc.close()

        return StreamingResponse(event_stream(), media_type="text/event-stream")
```

This path is for power users. You get full control over the ICE/SDP handshake, transceivers, codecs, and any custom data-channel protocol. The `PeerConnection` stays alive in the generator's local scope, so it is not garbage-collected while the stream is active. Put any teardown logic in the `finally` block so it runs whether the session ends naturally or the client drops mid-stream.

## Clients

First-party WMA client libraries for the browser and native platforms are not yet released. Until they ship, you can talk to the bridge directly from any WebRTC-capable client. The bridge lives at `wma.fal.run` and exposes two endpoints.

### `POST /session`

Creates a new WebRTC session. Send the SDP offer from your local `RTCPeerConnection` along with the `app_id` to route to. The bridge forwards the offer to a runner, collects the SDP answer, and returns it as JSON.

Wait for ICE gathering to finish before sending the offer. The bridge does not support trickle ICE, so the offer must contain all ICE candidates.

Request headers:

* `Authorization: Key <your-fal-key>`
* `Content-Type: application/json`

Request body:

```json theme={null}
{
  "app_id": "your-username/your-app",
  "sdp": "<offer SDP from RTCPeerConnection.createOffer()>",
  "type": "offer"
}
```

Response body:

```json theme={null}
{
  "session_id": "<uuid>",
  "sdp": "<answer SDP>",
  "type": "answer"
}
```

Apply the returned SDP as the remote description on your `RTCPeerConnection` and let ICE negotiate. Once the connection is established, media flows peer-to-peer between your client and the runner.

### `POST /session/heartbeat`

Keeps the session alive. The bridge expects a heartbeat at regular intervals. If heartbeats stop arriving, the bridge tears the session down: the runner's `/start-session` generator exits and its `finally` block runs.

Request headers:

* `Authorization: Key <your-fal-key>`
* `Content-Type: application/json`

Request body:

```json theme={null}
{
  "session_id": "<session_id from /session>"
}
```

Send heartbeats every 5 seconds. To end a session, stop sending heartbeats and close the peer connection.

### Reconnection

WMA sessions are not resumable. If the peer connection drops (ICE failure, network change, runner restart), start over: close the old `RTCPeerConnection`, stop any heartbeat timers, build a new peer connection, generate a fresh offer, and call `/session` again. Each call to `/session` spins up a new session on the runner.

### Browser example

The snippet below shows the full client flow in a browser. It connects the camera to a WMA app, receives the processed video back, and keeps the session alive with heartbeats.

```javascript theme={null}
const FAL_KEY = "your-fal-key";
const APP_ID = "your-username/your-app";
const WMA_URL = "https://wma.fal.run";

// 1. Create a peer connection and add the camera.
const pc = new RTCPeerConnection({
  iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
});

const stream = await navigator.mediaDevices.getUserMedia({ video: true });
stream.getTracks().forEach((track) => pc.addTrack(track, stream));

// Receive the processed video from the server.
pc.ontrack = (ev) => {
  remoteVideo.srcObject = ev.streams[0] ?? new MediaStream([ev.track]);
};

// The server may open a data channel for application-level messages
// (e.g. ping/pong latency probes or session parameter updates).
pc.ondatachannel = (ev) => {
  const dc = ev.channel;
  dc.onmessage = (msg) => {
    const data = JSON.parse(msg.data);
    // handle messages from the server
  };
};

// 2. Create the offer and wait for ICE candidates to be gathered.
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

await new Promise((resolve) => {
  if (pc.iceGatheringState === "complete") return resolve();
  const timeout = setTimeout(resolve, 5000);
  pc.onicegatheringstatechange = () => {
    if (pc.iceGatheringState === "complete") {
      clearTimeout(timeout);
      resolve();
    }
  };
});

// 3. Send the offer to the WMA bridge and apply the answer.
const resp = await fetch(WMA_URL + "/session", {
  method: "POST",
  headers: {
    "Authorization": "Key " + FAL_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    app_id: APP_ID,
    sdp: pc.localDescription.sdp,
    type: pc.localDescription.type,
  }),
});

const { session_id, sdp, type } = await resp.json();
await pc.setRemoteDescription(new RTCSessionDescription({ sdp, type }));

// 4. Keep the session alive with heartbeats.
const heartbeat = setInterval(() =>
  fetch(WMA_URL + "/session/heartbeat", {
    method: "POST",
    headers: {
      "Authorization": "Key " + FAL_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ session_id }),
  }),
  5000
);

// 5. Clean up when the connection ends.
function cleanup() {
  clearInterval(heartbeat);
  pc.close();
  stream.getTracks().forEach((t) => t.stop());
}

pc.onconnectionstatechange = () => {
  if (pc.connectionState === "failed" || pc.connectionState === "closed") {
    cleanup();
  }
};
```

## Related

<CardGroup cols={2}>
  <Card title="Deploy a Real-time World Model" icon="globe" href="/examples/video-generation/deploy-realtime-world-model">
    End-to-end example of a live world model running over WebRTC.
  </Card>

  <Card title="Realtime Endpoints" icon="bolt" href="/documentation/development/realtime">
    Lower-level realtime primitives built on fal's WebSocket infrastructure.
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/development/working-with-files.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with Files

> Download input files and return generated outputs from your fal App using the toolkit's file types and download utilities.

Most AI models consume files as input and produce files as output. A video upscaler takes a video URL and returns an enhanced video. An image generator takes a text prompt and returns images. Your [fal App](/documentation/getting-started/apps-and-execution) needs a way to download files that users provide, process them, and return the results as publicly accessible URLs. The `fal.toolkit` provides a set of file types and download utilities that handle all of this.

The download utilities (`download_file`, `download_model_weights`) handle the input side: they download remote files to a local path on your runner, with built-in caching and streaming for large files. The file types (`File`, `Image`, `Video`, `Audio`) handle the output side: you create them from raw bytes, PIL images, or local files, and they automatically upload to [fal's CDN](/documentation/model-apis/fal-cdn) and return a public URL. Together, these cover the complete file I/O lifecycle for a request. For defining input and output schemas that the [Playground](/documentation/model-apis/playground) renders correctly, see [Handle Inputs and Outputs](/documentation/development/handle-inputs-and-outputs).

## Downloading Input Files

Users provide file inputs as URLs. The `download_file` function downloads them to a local path on your runner for processing. It handles large files efficiently by streaming in 64 MB chunks, and it writes to a temporary file first then renames atomically so you never end up with a partial file if the download fails.

```python theme={null}
from fal.toolkit import download_file

class MyModel(fal.App):
    machine_type = "GPU-A100"

    @fal.endpoint("/")
    def process(self, video_url: str) -> dict:
        local_path = download_file(video_url, target_dir="/tmp/inputs")
        result = self.model.process(str(local_path))
        return {"output": result}
```

If `target_dir` is a relative path, it resolves relative to `/data` ([persistent storage](/documentation/development/use-persistent-storage)). So `download_file(url, target_dir="models/")` saves to `/data/models/`. The function also handles `data:` URIs automatically, decoding base64-encoded inline content without making a network request.

### Caching

`download_file` checks if the local file already exists and compares its size to the remote file's `Content-Length` header. If they match, it returns the existing path without re-downloading. This makes repeated calls with the same URL essentially free.

```python theme={null}
path = download_file(url, target_dir="/data/inputs")

path = download_file(url, target_dir="/data/inputs")

path = download_file(url, target_dir="/data/inputs", force=True)
```

<Note>
  Caching uses file size comparison, not content hashing. If a remote file changes but stays the same size, the cached version is returned. Use `force=True` if you need to guarantee freshness.
</Note>

### Authenticated Downloads

If the file is hosted behind authentication (e.g., a private S3 bucket or a gated model on Hugging Face), pass custom headers via `request_headers`:

```python theme={null}
path = download_file(
    "https://private-storage.example.com/model.bin",
    target_dir="/data/models",
    request_headers={"Authorization": "Bearer your-token"},
)
```

### File Size Limits

Set `filesize_limit` (in MB) to reject files that are too large before downloading:

```python theme={null}
path = download_file(url, target_dir="/tmp", filesize_limit=500)
```

### Downloading Model Weights

For the common pattern of downloading model weights to persistent storage, `download_model_weights` is a convenience wrapper around `download_file`. It stores files in `/data/.fal/model_weights/` using a hash of the URL as the directory name, so repeated calls with the same URL are cached automatically.

```python theme={null}
from fal.toolkit import download_model_weights

class MyModel(fal.App):
    def setup(self):
        weights_path = download_model_weights("https://huggingface.co/org/model/resolve/main/weights.bin")
        self.model = load_from_weights(weights_path)
```

For more details on downloading and caching large model files, see [Download Model Weights](/documentation/development/download-model-weights-and-files).

***

## Returning Files from Endpoints

When your model generates a file, wrap it in one of the toolkit's file types before returning it. The type handles uploading to fal's CDN and returning a public URL in the response.

```python theme={null}
import fal
from fal.toolkit import Image

class MyModel(fal.App):
    machine_type = "GPU-A100"

    def setup(self):
        self.pipe = load_model()

    @fal.endpoint("/")
    def generate(self, prompt: str) -> dict:
        pil_image = self.pipe(prompt).images[0]
        return {"image": Image.from_pil(pil_image)}
```

The returned object has a `.url` field containing the public CDN URL (e.g., `https://v3.fal.media/files/...`). These URLs are publicly accessible and subject to your [media expiration settings](/documentation/model-apis/media-expiration).

### File Types and Methods

All file types extend `File` and inherit its methods. `Image` adds `width`, `height`, and PIL conversion. `Video` and `Audio` add no extra fields but tell the Playground to render the appropriate media player.

| Type             | Class Methods                                                                             | Extra Fields                                          |
| ---------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `File`           | `from_path(path)`, `from_bytes(data, content_type=, file_name=)`                          | `url`, `content_type`, `file_name`, `file_size`       |
| `Image`          | `from_pil(pil_image, format=)`, `from_bytes(data, format, size=)`, inherits `from_path()` | `width`, `height`                                     |
| `Video`          | Inherits `from_path()`, `from_bytes()`                                                    | (none beyond File)                                    |
| `Audio`          | Inherits `from_path()`, `from_bytes()`                                                    | (none beyond File)                                    |
| `CompressedFile` | Inherits `from_path()`, `from_bytes()`                                                    | Supports `__iter__()` and `glob()` for ZIP extraction |

Every file type also provides instance methods: `as_bytes()` returns the file content as bytes, and `save(path)` writes it to a local path. `Image` additionally provides `to_pil()` to convert back to a PIL Image.

### Supported Formats

`File`, `Video`, and `Audio` accept any file format. There is no validation or allowlist at the SDK level. You can pass any URL or bytes regardless of content type. The `content_type` field is metadata that gets stored alongside the file but does not restrict what you can upload.

`Image` is the only type with a defined format list. When using `Image.from_pil()` or `Image.from_bytes()`, the `format` parameter accepts `"png"`, `"jpeg"`, `"jpg"`, `"webp"`, or `"gif"`. When using `Image.from_path()` (inherited from `File`), there is no format restriction.

The Playground renders previews based on the type you use (`Image` shows an image viewer, `Video` shows a video player, `Audio` shows an audio player), but playback depends on browser support. For maximum compatibility, use widely supported formats like MP4 (H.264) for video and WAV or MP3 for audio.

### Creating Files

The most common patterns for creating file objects:

```python theme={null}
from fal.toolkit import File, Image, Video, Audio

image = Image.from_pil(pil_image)
image = Image.from_pil(pil_image, format="webp")
image = Image.from_bytes(raw_bytes, format="png")
image = Image.from_path("/tmp/output.png")

video = Video.from_path("/tmp/output.mp4")
audio = Audio.from_path("/tmp/output.wav")
audio = Audio.from_bytes(raw_bytes, content_type="audio/wav", file_name="output.wav")

generic = File.from_path("/tmp/result.obj")
generic = File.from_bytes(data, content_type="application/octet-stream", file_name="model.glb")
```

### The Type System and Playground

Using `Image`, `Video`, or `Audio` in your Pydantic output schema tells the Playground to render the appropriate preview. `Image` shows an image viewer, `Video` shows a video player, and `Audio` shows an audio player. If you use the base `File` type, the Playground renders a download link instead.

```python theme={null}
from fal.toolkit import Image, Video, Audio

class Output(BaseModel):
    image: Image
    video: Video
    audio: Audio
```

For richer input schemas with file URL types that validate correctly, see the `FileInput` and `ImageInput` union types in [Handle Inputs and Outputs](/documentation/development/handle-inputs-and-outputs).

### Compressed Files

`CompressedFile` extends `File` with ZIP extraction support. When you iterate over a `CompressedFile` or call `glob()`, it automatically downloads and extracts the archive to a temporary directory.

```python theme={null}
from fal.toolkit import CompressedFile

class MyApp(fal.App):
    @fal.endpoint("/")
    def process(self, archive_url: str) -> dict:
        archive = CompressedFile(url=archive_url)
        png_files = list(archive.glob("*.png"))
        return {"file_count": len(png_files)}
```

The extracted directory is cleaned up automatically when the `CompressedFile` object is garbage collected.

***

## CDN vs /data Storage

Your app works with two storage systems that serve different purposes. Understanding when to use each prevents common mistakes like storing temporary outputs in persistent storage or losing generated files after a runner shuts down.

The [fal CDN](/documentation/model-apis/fal-cdn) is for generated outputs that you return to users. When you call `Image.from_pil()` or `File.from_path()`, the file is uploaded to the CDN and a public URL is returned. These URLs are accessible to anyone without authentication, and they expire according to your [media expiration settings](/documentation/model-apis/media-expiration). Each upload produces a unique URL with no shared namespace.

The `/data` directory is [persistent storage](/documentation/development/use-persistent-storage) mounted as a local filesystem on every runner. It is shared across all runners and all apps in your account. Use it for model weights, datasets, cached preprocessed files, and anything that should persist across requests and runner restarts. Files on `/data` are not URL-accessible and remain until you delete them.

For per-request temporary files that don't need to persist, use `/tmp`. It is local to each runner and cleared when the runner shuts down.

|                 | CDN                                                                          | /data                             | /tmp                       |
| --------------- | ---------------------------------------------------------------------------- | --------------------------------- | -------------------------- |
| **Use for**     | Generated outputs returned to users                                          | Model weights, datasets, caches   | Per-request scratch files  |
| **Persistence** | Subject to [expiration settings](/documentation/model-apis/media-expiration) | Permanent until deleted           | Cleared on runner shutdown |
| **Shared**      | No (each upload is unique)                                                   | Yes (across all runners and apps) | No (per-runner)            |
| **Access**      | Public URL, no auth                                                          | Local filesystem only             | Local filesystem only      |

<CardGroup cols={2}>
  <Card title="fal CDN" href="/documentation/model-apis/fal-cdn">
    Uploading files from client code before calling a model
  </Card>

  <Card title="Persistent Storage" href="/documentation/development/use-persistent-storage">
    Managing persistent files on /data
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Documentation

> Learn how to build and deploy AI applications with fal

<div id="docs-hero-page">
  <div className="fal-hero-section">
    <div className="fal-hero-text">
      <h1 className="fal-hero-title">
        Build with fal
      </h1>

      <p className="fal-hero-subtitle">The generative media platform powering the world's top AI apps.</p>

      <p className="fal-hero-body">
        Call <strong>1,000+ optimized models</strong> through a unified API, or deploy your own on the same infrastructure. Image, video, audio, music, speech, 3D, and real-time streaming. Built to scale to billions of requests.
      </p>

      <button type="button" className="fal-hero-search" onClick={() => document.getElementById('search-bar-entry')?.click()}>
        <svg className="fal-hero-search-icon" viewBox="0 0 20 20" fill="currentColor">
          <path fillRule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clipRule="evenodd" />
        </svg>

        <span className="fal-hero-search-text">Search or ask...</span>
      </button>

      <div className="fal-stats-row">
        <div className="fal-stat-item">
          <div className="fal-stat-value">99.99%+</div>
          <div className="fal-stat-label">Uptime</div>
        </div>

        <div className="fal-stat-item">
          <div className="fal-stat-value">Billions+</div>
          <div className="fal-stat-label">Requests/day</div>
        </div>

        <div className="fal-stat-item">
          <div className="fal-stat-value">1,000+</div>
          <div className="fal-stat-label">Endpoints</div>
        </div>
      </div>
    </div>

    <div className="fal-hero-image">
      <img src="https://mintcdn.com/fal-d8505a2e/QFO2a4qD7yLWEJFa/images/Hero_image_light.png?fit=max&auto=format&n=QFO2a4qD7yLWEJFa&q=85&s=be84ce69a57abe69927c7453e497768f" alt="Build with fal" className="fal-hero-img-light" width="2140" height="1552" data-path="images/Hero_image_light.png" />

      <img src="https://mintcdn.com/fal-d8505a2e/QFO2a4qD7yLWEJFa/images/Hero_image_dark.png?fit=max&auto=format&n=QFO2a4qD7yLWEJFa&q=85&s=c818dcf171b90cd6b31c46254c72e333" alt="Build with fal" className="fal-hero-img-dark" width="2140" height="1552" data-path="images/Hero_image_dark.png" />
    </div>
  </div>

  <CardGroup cols={3}>
    <Card title="Model APIs" icon="cube" href="/documentation/model-apis/overview" className="fal-feature-card">
      **Call 1,000+ models with one API.** Image, video, audio, and multimodal generation. Optimized and production-ready.
    </Card>

    <Card title="Serverless" icon="rocket" href="/documentation/serverless" className="fal-feature-card">
      **Deploy your own models.** Same infrastructure, same autoscaling, same reliability. From zero to thousands of GPUs.
    </Card>

    <Card title="Compute" icon="microchip" href="/documentation/compute" className="fal-feature-card">
      **Dedicated GPU instances.** Full SSH access for training, fine-tuning, and persistent workloads.
    </Card>
  </CardGroup>

  <Card title="Platform APIs" icon="layer-group" href="/api-reference/platform-apis">
    REST APIs for model metadata, pricing, usage tracking, logs, files, and metrics
  </Card>

  ## Start with a Model API Call

  Most users start here. Pick a model from the [Marketplace](https://fal.ai/models), get an [API key](https://fal.ai/dashboard/keys), and make a request. Three lines of code, no infrastructure to manage.

  <CodeGroup>
    ```python Python theme={null}
    import fal_client

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

    ```javascript JavaScript theme={null}
    import { fal } from "@fal-ai/client";

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

    ```bash cURL theme={null}
    curl -X POST https://queue.fal.run/fal-ai/nano-banana-2 \
      -H "Authorization: Key $FAL_KEY" \
      -H "Content-Type: application/json" \
      -d '{"prompt": "a sunset over mountains"}'
    ```
  </CodeGroup>

  Every model supports [synchronous and async queue](/documentation/model-apis/inference) calls out of the box. Many also support [streaming](/documentation/model-apis/inference/streaming) and [real-time WebSocket](/documentation/model-apis/inference/real-time) connections. You can compare models side-by-side in the [Sandbox](https://fal.ai/sandbox) before committing to one.

  <Card title="Model APIs Quickstart" icon="arrow-right" href="/documentation/model-apis/overview">
    Browse models, see pricing, and start generating
  </Card>

  ***

  ## Deploy Your Own Models

  For teams that need to run custom models, proprietary pipelines, or fine-tuned variants, [fal Serverless](/documentation/serverless) lets you deploy on the same engine that powers the Marketplace. fal has been running this infrastructure for over 3 years, and every model on the platform goes through the same lifecycle below.

  <Steps>
    <Step title="Develop">
      A [fal.App](/documentation/development/app-setup) is a Python class where your `setup()` method runs once per [runner](/documentation/deployment/runners) to load model weights and initialize resources. Your [`@fal.endpoint`](/documentation/development/handle-inputs-and-outputs) methods then serve incoming [requests](/documentation/deployment/requests) using the initialized state. You declare hardware needs and [environment](/documentation/development/container-setup) alongside your code, so infrastructure is versioned with your app.

      ```python theme={null}
      import fal

      class MyModel(fal.App):
          machine_type = "GPU-H100"
          
          def setup(self):
              self.model = load_my_model()
          
          @fal.endpoint("/")
          def generate(self, prompt: str):
              return self.model(prompt)
      ```
    </Step>

    <Step title="Test">
      [`fal run`](/documentation/development/getting-started/quick-start) spins up a cloud GPU [runner](/documentation/deployment/runners) and gives you a temporary URL so you can test on the same hardware you'll use in production. It also generates a [playground UI](/documentation/model-apis/playground) automatically. For CI, [`AppClient`](/documentation/development/test-models-and-endpoints) lets you run tests against ephemeral deployments.

      ```bash theme={null}
      fal run my_app.py
      ```
    </Step>

    <Step title="Deploy">
      [`fal deploy`](/documentation/deployment/deploy-to-production) creates a persistent, authenticated endpoint with autoscaling and built-in [retries](/documentation/serverless/reliability/retries). Every deploy creates a new revision for instant [rollbacks](/documentation/deployment/rollbacks). For staging and production separation, fal supports [multiple environments](/documentation/deployment/manage-environments) per app.

      ```bash theme={null}
      fal deploy my_app.py
      ```
    </Step>

    <Step title="Observe">
      The [dashboard](https://fal.ai/dashboard) gives you real-time logs, request-level [analytics](/documentation/serverless/observability/app-analytics), and [error tracking](/documentation/serverless/observability/error-analytics) out of the box. Trace individual requests, spot latency regressions, and monitor runner utilization. For external stacks, fal supports [Prometheus metrics](/documentation/serverless/observability/exporting-metrics) and [log drains](/documentation/serverless/observability/log-drains) to Datadog, Splunk, and Elasticsearch.
    </Step>

    <Step title="Scale">
      fal scales [runners](/documentation/deployment/runners) from zero to thousands of GPUs based on demand, with a multi-layer [caching](/documentation/deployment/caching) system that reduces cold starts over time. [Scaling parameters](/documentation/deployment/scale-your-application) let you control the tradeoff: `min_concurrency` keeps runners warm, `max_concurrency` caps spend, and `concurrency_buffer` pre-warms ahead of spikes. See [optimizing cold starts](/documentation/serverless/optimizations/optimize-cold-starts) and [machine types](/documentation/deployment/machine-types) for latency-sensitive workloads.

      ```python theme={null}
      class MyModel(fal.App):
          min_concurrency = 2
          max_concurrency = 100
          concurrency_buffer = 3
      ```
    </Step>

    <Step title="Distribute">
      Endpoints start as private. You can deploy in `public` mode for open access, or [`shared` mode](/documentation/deployment/deploy-to-production) where callers pay for their own usage. To list on the [Marketplace](https://fal.ai/models) for broader distribution and revenue, see [publishing to the marketplace](/documentation/serverless/publishing-to-marketplace).

      ```python theme={null}
      class MyModel(fal.App):
          app_auth = "shared"
      ```
    </Step>
  </Steps>

  <Card title="Serverless Quickstart" icon="arrow-right" href="/documentation/development/getting-started/quick-start">
    Deploy your first model in minutes
  </Card>

  ***

  ## Train Your Own Models

  For training runs, fine-tuning, and workloads that need sustained GPU access, [fal Compute](/documentation/compute) gives you dedicated instances with full SSH control. No cold starts, no autoscaling, just raw GPU power billed at a fixed hourly rate.

  <CardGroup cols={2}>
    <Card title="H100 SXM" icon="microchip">
      Single-GPU instances for development, fine-tuning, and single-GPU training
    </Card>

    <Card title="8x H100 SXM" icon="server">
      Multi-GPU instances connected over InfiniBand for distributed training
    </Card>
  </CardGroup>

  |              | Compute                           | Serverless                         |
  | :----------- | :-------------------------------- | :--------------------------------- |
  | **Best for** | Training, fine-tuning, batch jobs | API endpoints, on-demand inference |
  | **Billing**  | Per-hour, fixed rate              | Per-second of execution            |
  | **Scaling**  | Manual                            | Automatic                          |
  | **Access**   | Full SSH                          | Managed runners                    |

  <Card title="Compute Quickstart" icon="arrow-right" href="/documentation/compute/quickstart">
    Provision your first GPU instance in minutes
  </Card>
</div>


# https://fal.ai/docs/documentation/model-apis/common-parameters.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform Headers

> HTTP headers that control request behavior across all inference methods on fal.

When you call a model or your own deployed app on fal, you can pass platform-level HTTP headers that control how the request is handled. These headers are separate from the model's input arguments (like `prompt` or `image_size`) and from SDK method parameters (like `start_timeout` or `client_timeout`). They apply at the infrastructure level -- controlling retries, payload storage, media expiration, and routing.

Some of these headers have dedicated SDK parameters that set them automatically. For example, passing `start_timeout=30` in the SDK sets `X-Fal-Request-Timeout: 30` under the hood. Others, like `X-Fal-Store-IO`, can only be set via the `headers` dict. This page documents all platform headers in one place. For headers that have SDK parameters, the corresponding method pages are linked.

***

## X-Fal-Request-Timeout (`start_timeout`)

Server-side **time-to-start** deadline in seconds. Despite the header name, this does not limit total request time. The clock starts when the request is submitted and covers queue wait, runner acquisition, and failed retry attempts. Once a runner successfully begins processing, the timeout stops and inference can run as long as it needs. If the deadline is reached before any runner starts processing, the server returns `504 Gateway Timeout` with `X-Fal-Request-Timeout-Type: user`. To limit total client-side wait time (including processing), use `client_timeout` on [`subscribe()`](/documentation/model-apis/inference/queue#client_timeout-subscribe-only) instead.

|                   |                                                                                                                                                                                                                                                  |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Header**        | `X-Fal-Request-Timeout`                                                                                                                                                                                                                          |
| **Default**       | No timeout                                                                                                                                                                                                                                       |
| **Minimum**       | > 0.1 seconds                                                                                                                                                                                                                                    |
| **SDK parameter** | `start_timeout` on [`submit()`](/documentation/model-apis/inference/queue#start-timeout), [`subscribe()`](/documentation/model-apis/inference/queue#start-timeout), and [`run()`](/documentation/model-apis/inference/synchronous#start-timeout) |

***

## X-Fal-Runner-Hint (`hint`)

Routing hint that tells fal to try to route the request to a specific runner. Useful for session affinity -- for example, keeping requests pinned to a runner that already has a LoRA adapter or conversation state loaded in memory. If the hinted runner is unavailable, fal routes to any available runner.

|                   |                                                                                                                                                                                                              |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Header**        | `X-Fal-Runner-Hint`                                                                                                                                                                                          |
| **Default**       | Automatic routing                                                                                                                                                                                            |
| **SDK parameter** | `hint` on [`submit()`](/documentation/model-apis/inference/queue#hint), [`subscribe()`](/documentation/model-apis/inference/queue#hint), and [`run()`](/documentation/model-apis/inference/synchronous#hint) |

***

## X-Fal-Queue-Priority (`priority`)

Queue priority for the request. Priority applies to the per-endpoint queue -- every request to the same endpoint shares one queue, regardless of who sent it. A low-priority request sits behind all normal-priority requests. This means setting `"low"` on a shared model API deprioritizes your request relative to all other users of that model.

|                   |                                                                                                                                                        |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Header**        | `X-Fal-Queue-Priority`                                                                                                                                 |
| **Default**       | `"normal"`                                                                                                                                             |
| **Values**        | `"normal"`, `"low"`                                                                                                                                    |
| **SDK parameter** | `priority` on [`submit()`](/documentation/model-apis/inference/queue#priority) and [`subscribe()`](/documentation/model-apis/inference/queue#priority) |

***

## X-Fal-Object-Lifecycle-Preference

Control how long generated files (images, videos, audio) are stored on fal's CDN.

|             |                                                    |
| ----------- | -------------------------------------------------- |
| **Header**  | `X-Fal-Object-Lifecycle-Preference`                |
| **Default** | Your account setting (forever if not configured)   |
| **Format**  | JSON: `{"expiration_duration_seconds": <seconds>}` |

<CodeGroup>
  ```python Python theme={null}
  import json

  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      headers={
          "X-Fal-Object-Lifecycle-Preference": json.dumps({
              "expiration_duration_seconds": 3600
          })
      }
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    headers: {
      "X-Fal-Object-Lifecycle-Preference": JSON.stringify({
        expiration_duration_seconds: 3600
      })
    }
  });
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/nano-banana-2" \
    -H "Authorization: Key $FAL_KEY" \
    -H 'X-Fal-Object-Lifecycle-Preference: {"expiration_duration_seconds": 3600}' \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset"}'
  ```
</CodeGroup>

<Card title="Data Retention & Storage" icon="arrow-right" href="/documentation/model-apis/media-expiration">
  Full guide to media expiration, payload retention, and the delete API
</Card>

***

## X-Fal-Store-IO

Prevent fal from storing request payloads (JSON inputs and outputs). Payloads are stored for 30 days by default and power the request history in your dashboard.

|             |                            |
| ----------- | -------------------------- |
| **Header**  | `X-Fal-Store-IO`           |
| **Default** | `"1"` (stored for 30 days) |
| **Values**  | `"0"` to disable storage   |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      headers={"X-Fal-Store-IO": "0"}
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    headers: { "X-Fal-Store-IO": "0" }
  });
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/nano-banana-2" \
    -H "Authorization: Key $FAL_KEY" \
    -H "X-Fal-Store-IO: 0" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset"}'
  ```
</CodeGroup>

<Note>
  This only prevents storage of the JSON payloads. CDN files generated during processing are still accessible (subject to [media expiration](/documentation/model-apis/media-expiration) settings).
</Note>

***

## X-Fal-No-Retry

Disable automatic retries for this request. By default, queue-based requests are retried for up to 10 total attempts on server errors (503, 504, connection errors).

|             |                                     |
| ----------- | ----------------------------------- |
| **Header**  | `X-Fal-No-Retry`                    |
| **Default** | Retries enabled                     |
| **Values**  | `"1"`, `"true"`, `"yes"` to disable |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      headers={"X-Fal-No-Retry": "1"}
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    headers: { "X-Fal-No-Retry": "1" }
  });
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/nano-banana-2" \
    -H "Authorization: Key $FAL_KEY" \
    -H "X-Fal-No-Retry: 1" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset"}'
  ```
</CodeGroup>

<Card title="Reliability & Retries" icon="arrow-right" href="/documentation/model-apis/inference/reliability">
  Learn more about automatic retries, fallbacks, and error handling
</Card>

***

## x-app-fal-disable-fallback

Disable automatic model fallbacks for this request. By default, fal may reroute requests to equivalent alternative endpoints if the primary is unavailable.

|             |                              |
| ----------- | ---------------------------- |
| **Header**  | `x-app-fal-disable-fallback` |
| **Default** | Fallbacks enabled            |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      headers={"x-app-fal-disable-fallback": "true"}
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    headers: { "x-app-fal-disable-fallback": "true" }
  });
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/nano-banana-2" \
    -H "Authorization: Key $FAL_KEY" \
    -H "x-app-fal-disable-fallback: true" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset"}'
  ```
</CodeGroup>

<Card title="Reliability & Retries" icon="arrow-right" href="/documentation/model-apis/inference/reliability">
  Learn more about model fallbacks
</Card>

***

## fal\_max\_queue\_length

Reject the request with `429` if the endpoint's queue already has more than this many requests waiting (across all callers). Useful for latency-sensitive applications that prefer to fail fast rather than wait in a long queue.

|                 |                        |
| --------------- | ---------------------- |
| **Query param** | `fal_max_queue_length` |
| **Default**     | No limit               |
| **Type**        | Integer                |

<Note>
  This parameter is passed as a query parameter on the URL, not as a header. The SDKs do not currently expose it as a named parameter; use the raw URL approach or pass it via `headers`.
</Note>

```bash cURL theme={null}
curl -X POST "https://queue.fal.run/fal-ai/nano-banana-2?fal_max_queue_length=10" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "a sunset"}'
```

***

## Response Headers

These headers are returned by fal in the response. They are informational; you don't set them.

<Warning>
  The total size of all response headers is limited to **16 KB**. This includes both platform headers (listed below) and any custom headers set by the app. If the combined headers exceed 16 KB, the response will fail. This is most relevant when apps set large custom headers — for example, verbose routing hints via [`provide_hints()`](/documentation/development/advanced/optimize-routing-behavior).
</Warning>

| Header                       | Description                                                                                                                                                                                                 |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `x-fal-request-id`           | Unique identifier for the request. Use this when contacting [support](/documentation/model-apis/support) or correlating logs.                                                                               |
| `X-Fal-Billable-Units`       | Billing units charged for this request. See [Pricing](/documentation/model-apis/pricing) for how units map to cost.                                                                                         |
| `X-Fal-Served-From`          | Internal identifier of the runner that served the request.                                                                                                                                                  |
| `X-Fal-Request-Timeout-Type` | Set to `user` when your [`start_timeout`](#x-fal-request-timeout-start_timeout) deadline triggered the 504. See [Timeouts and Retries](/documentation/serverless/reliability/retries#timeouts-and-retries). |
| `X-Fal-Error-Type`           | Error category on failure responses (e.g., `request_timeout`, `startup_timeout`, `runner_disconnected`). See [Request Error Types](/documentation/model-apis/request-errors).                               |
| `x-fal-runner-hints`         | Routing hints returned by the runner for sticky session routing. See [Optimize Routing Behavior](/documentation/serverless/optimizations/optimize-routing-behavior).                                        |

<Card title="Common Model Arguments" icon="arrow-right" href="/documentation/model-apis/model-arguments">
  Common input parameters like seed, image\_size, and safety checker that appear across many models
</Card>


# https://fal.ai/docs/documentation/model-apis/concurrency-limits.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Concurrency Limits

> Understand and manage how many requests you can run simultaneously on fal.

Concurrency limits control how many requests your account can process at the same time. Every fal account has a global concurrency limit that determines how many requests can be in the [`IN_PROGRESS`](/documentation/model-apis/inference/queue#request-lifecycle) state simultaneously. When you reach your limit, additional requests wait in the [queue](/documentation/model-apis/inference/queue) and are dispatched as soon as a slot frees up. Requests are never rejected due to concurrency limits.

Your concurrency limit is determined by your credit purchase history and scales automatically as you buy more credits. The limit applies at the platform level across all endpoints you call, though fal can also set per-endpoint limits on specific high-demand models. Understanding how these limits work helps you plan capacity for production workloads and avoid unexpected throttling. If you are deploying your own apps on [Serverless](/documentation/serverless), note that concurrency limits do not apply when you call your own endpoints.

## How It Works

When you submit a request, the platform tracks it against your concurrency limit only while a [runner](/documentation/deployment/runners) is actively processing it (the `IN_PROGRESS` state). Requests in the `IN_QUEUE` state do not count toward your limit. This means you can submit as many requests as you want to the queue, but only a limited number will be dispatched to runners at any given time.

The enforcement mechanism depends on how you call the model. For [queue-based requests](/documentation/model-apis/inference) (`subscribe` or `submit`), the platform checks your concurrency before dispatching a queued request to a runner. If you are at capacity, the request stays in the queue and is retried with exponential backoff until a slot opens. There is no maximum retry count for concurrency-related requeues, so your request will eventually be processed regardless of how long it needs to wait. For direct requests (`run`), the gateway checks concurrency at request time and the [fal client](/documentation/model-apis/inference/client-setup) handles retries automatically.

<Note>
  Requests are never dropped due to concurrency limits. For queue-based requests, they wait in the queue and are dispatched when capacity is available. For direct requests, the SDK retries automatically. The only scenario where a request can be dropped while waiting is if you set a [`start_timeout`](/documentation/model-apis/inference/queue#start_timeout) and the deadline expires before a slot opens.
</Note>

## Default Limits

Every new account starts with a concurrency limit of **2** concurrent requests. As you purchase credits, the platform automatically increases your limit based on the total amount of paid invoices from the last four weeks. Self-serve limits scale up to **40** concurrent requests. The adjustment happens when a credit purchase invoice is paid, so the change typically takes effect within a few minutes of purchasing credits.

You can view your current limit and spending tier on the [Concurrency page](https://fal.ai/dashboard/usage-billing/concurrency) in the dashboard.

## Viewing Your Limit

You can view your current concurrency limit, real-time request count, and a 30-day usage history chart on the [Concurrency page](https://fal.ai/dashboard/usage-billing/concurrency) in your dashboard. This page also shows your peak concurrent usage, which is helpful for determining whether you need to upgrade.

## Increasing Your Limit

The most direct way to increase your limit is to purchase credits. You can do this from the [Concurrency page](https://fal.ai/dashboard/usage-billing/concurrency) in your dashboard. Once the payment is processed, your limit is updated automatically based on the thresholds above.

For limits above 40 concurrent requests, or for custom per-endpoint allocations, [contact the sales team](https://fal.ai/enterprise#contact-sales). Enterprise plans can be configured with higher global limits or dedicated per-endpoint limits tailored to your workload.

## Per-Endpoint Limits

In addition to the global account limit, fal may apply additional concurrency limits on certain high-demand models to ensure fair access across all users. If you are experiencing throttling on a specific model and believe you need a higher allocation, [contact sales](https://fal.ai/enterprise#contact-sales).

## Concurrency and the fal Client

Both `fal_client.run()` and `fal_client.subscribe()` handle concurrency limits automatically. The fal client includes built-in retry logic for `429` responses, retrying with exponential backoff up to 10 times. You do not need to implement manual retry logic when using the SDK.

The key difference is how the retry happens. With `subscribe()` (or `submit()`), the retry is handled server-side by the [queue](/documentation/model-apis/inference/queue), which requeues the request with no maximum retry count. With `run()`, the retry is handled client-side by the SDK, which retries the HTTP request up to 10 times. For production workloads, `subscribe()` is the recommended approach because it provides more durable retry behavior.

```python theme={null}
import fal_client

# Recommended: queue-based call handles concurrency limits server-side
result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
    "prompt": "a sunset over mountains"
})
```

If you are making raw HTTP requests without the SDK, a `429` response with the `concurrent_requests_limit` type indicates you have hit your concurrency limit. The response includes an `X-Fal-needs-retry: 1` header. You should retry with exponential backoff:

```bash theme={null}
curl -X POST "https://fal.run/fal-ai/flux/schnell" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "a sunset over mountains"}'

# On 429 with type "concurrent_requests_limit":
# Retry with exponential backoff (1s, 2s, 4s, 8s...)
```

<CardGroup cols={2}>
  <Card title="Reliability & Retries" icon="arrow-right" href="/documentation/model-apis/inference/reliability">
    Learn more about automatic retries and error handling
  </Card>

  <Card title="Error Reference" icon="arrow-right" href="/documentation/model-apis/errors">
    Full list of error types and how to handle them
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/model-apis/errors.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Errors

> Validation and content errors returned by models when inputs don't meet requirements.

When a model rejects your input due to validation failures, content policy violations, or format issues, it returns a structured error response with typed error objects. These errors tell you exactly what went wrong with your input and how to fix it. For infrastructure-level errors (timeouts, runner failures), see [Request Errors](/documentation/model-apis/request-errors).

<Warning>
  Some APIs are still being migrated to this error structure. Not all endpoints strictly follow the format documented below yet.
</Warning>

## Error Response

When an API request fails due to client-side input issues (like validation errors) or server-side problems, the API returns a structured error response. This response includes a standard HTTP status code, specific headers, and a JSON body detailing the errors.

### Error Response Structure

The error response consists of:

1. **HTTP Status Code:** Indicates the general category of the error (e.g., `500` for internal errors, `504` for timeouts).
2. **Headers:** Includes required headers like `X-Fal-Retryable`.
3. **JSON Body:** Contains a `detail` field which is an array of `Error` objects.

### Error Object Structure

The `detail` field is an array where each object represents a specific error.

| Property | Description                                                                                                                                                                                                                                                                                                                                    |
| :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loc`    | **\[REQUIRED]** An array indicating the location of the error (e.g., `["body", "field_name"]` for input validation, `["body"]` for general errors). The first item in the loc list will be the field where the error occurred, and if the field is a sub-model, subsequent items will be present to indicate the nested location of the error. |
| `msg`    | **\[REQUIRED]** A human-readable description of the error. **Client code should not parse and rely on the msg field.**                                                                                                                                                                                                                         |
| `type`   | **\[REQUIRED]** A unique, **machine-readable** string identifying the error category (e.g., `image_too_large`). Use this for conditional logic.                                                                                                                                                                                                |
| `url`    | **\[REQUIRED]** A link to documentation about this specific error `type` (e.g., [https://docs.fal.ai/errors/#image\_too\_large\`](https://docs.fal.ai/errors/#image_too_large`)). Primarily for developers.                                                                                                                                    |
| `ctx`    | **\[OPTIONAL]** An object with additional structured, **machine-readable** context for the error `type` (e.g., `{"max_height": 1024, "max_width": 1024}` for `image_too_large`).                                                                                                                                                               |
| `input`  | **\[OPTIONAL]** The input that caused the error.                                                                                                                                                                                                                                                                                               |

### Guidance

* **For Machine Processing:** Rely on the `type` field for conditional logic. Use `ctx` for specific error details if available. Check the `X-Fal-Retryable` header for retry decisions.
* **For Human Display:** Use the `msg` field to show error messages to end-users. **Client code should not parse and rely on the msg field.**
* **For Documentation:** Use the `url` field to link to further documentation about the specific error. This is primarily intended for developers to get more detailed information about error handling and resolution.

## Error Types

This document details the specific error types returned by the API, following the structure defined in the error specification. Each error type has a unique `type` string, a human-readable `msg`, and potentially a `ctx` object with more context.

##### `internal_server_error`

This error indicates an unexpected issue occurred on the server that prevented the request from being fulfilled.

* **Status Code:** 500
* **Retryable:** Can be `true` or `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body"],
    "msg": "Internal server error",
    "type": "internal_server_error",
    "url": "https://docs.fal.ai/errors/#internal_server_error",
    "input": { "prompt": "a cat" }
  }
]
```

##### `generation_timeout`

This error occurs when the requested operation took longer than the allowed time limit to complete.

* **Status Code:** 504
* **Retryable:** Can be `true` or `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body"],
    "msg": "Generation timeout",
    "type": "generation_timeout",
    "url": "https://docs.fal.ai/errors/#generation_timeout",
    "input": { "prompt": "a very complex scene taking too long" }
  }
]
```

##### `downstream_service_error`

This error signifies a problem when communicating with an external service required to fulfill the request.

* **Status Code:** 400
* **Retryable:** Can be `true` or `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body"],
    "msg": "Downstream service error",
    "type": "downstream_service_error",
    "url": "https://docs.fal.ai/errors/#downstream_service_error",
    "input": { "some_input": "value" }
  }
]
```

##### `downstream_service_unavailable`

This error indicates that a required third-party service (**including partner APIs**) is currently unavailable, preventing the request from being fulfilled.

* **Status Code:** 500
* **Retryable:** Can be `true` or `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body"],
    "msg": "Downstream service unavailable",
    "type": "downstream_service_unavailable",
    "url": "https://docs.fal.ai/errors/#downstream_service_unavailable",
    "input": { "prompt": "a cat" }
  }
]
```

##### `content_policy_violation`

This error indicates that the provided input content (e.g., text prompt, uploaded image) could not be processed because it was flagged by automated safety systems as potentially violating usage policies or responsible AI guidelines.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):** None

These filters are in place to ensure safe, ethical, and legal use of the platform. **The content may have been flagged by either fal's filter or one of our partners'. Sensitivity levels can vary between partner APIs.**

Violations may include, but are not limited to:

* Content depicting NSFW content, promoting illegal acts or hate speech.
* Severely harmful content, such as depictions of extreme violence, gore, or content promoting self-harm.
* Content intended to promote misinformation, deception, harassment, or discrimination.
* Generation of content that infringes on third-party intellectual property rights.
* Content that perpetuates harmful stereotypes.

```json theme={null}
[
  {
    "loc": ["body", "prompt"],
    "msg": "The content could not be processed because it contained material flagged by a content checker.",
    "type": "content_policy_violation",
    "url": "https://docs.fal.ai/errors/#content_policy_violation",
    "input": "a prompt containing forbidden content"
  }
]
```

##### `no_media_generated`

This error indicates that the generation completed successfully but the model did not produce any media output for the given input. This can happen when the model is unable to generate a valid result from the provided prompt or parameters.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body"],
    "msg": "The model did not generate the expected output for this prompt.",
    "type": "no_media_generated",
    "url": "https://docs.fal.ai/errors/#no_media_generated",
    "input": { "prompt": "a cat in a garden" }
  }
]
```

##### `image_too_small`

This error indicates that the provided image dimensions are smaller than the required minimum.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `min_height`: The minimum required height in pixels.
  * `min_width`: The minimum required width in pixels.

```json theme={null}
[
  {
    "loc": ["body", "image_url"],
    "msg": "Image too small",
    "type": "image_too_small",
    "url": "https://docs.fal.ai/errors/#image_too_small",
    "ctx": {
      "min_height": 512,
      "min_width": 512
    },
    "input": "https://example.com/image_100x100.jpg"
  }
]
```

##### `image_too_large`

This error indicates that the provided image dimensions exceed the maximum allowed limits.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `max_height`: The maximum allowed height in pixels.
  * `max_width`: The maximum allowed width in pixels.

```json theme={null}
[
  {
    "loc": ["body", "input_image"],
    "msg": "Image too large",
    "type": "image_too_large",
    "url": "https://docs.fal.ai/errors/#image_too_large",
    "ctx": {
      "max_height": 1024,
      "max_width": 1024
    },
    "input": "https://example.com/image_2000x2000.jpg"
  }
]
```

##### `image_load_error`

This error occurs when the server failed to load or process the provided image, possibly due to corruption or an unsupported format.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body", "control_image"],
    "msg": "Image load error",
    "type": "image_load_error",
    "url": "https://docs.fal.ai/errors/#image_load_error",
    "input": "https://example.com/corrupted_image.webp"
  }
]
```

##### `file_download_error`

This error indicates that the server failed to download a file specified by a URL in the input.
Make sure the URL is publicly accessible and that the file is not behind a login or authentication wall.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body", "video_url"],
    "msg": "File download error",
    "type": "file_download_error",
    "url": "https://docs.fal.ai/errors/#file_download_error",
    "input": "https://private-server.com/file.mp4"
  }
]
```

##### `face_detection_error`

This error is raised when the system could not detect a face in the provided image, and face detection was required for the operation.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body", "face_image"],
    "msg": "Could not detect face in the image",
    "type": "face_detection_error",
    "url": "https://docs.fal.ai/errors/#face_detection_error",
    "input": "https://example.com/landscape_no_face.jpg"
  }
]
```

##### `file_too_large`

This error indicates that the provided file exceeds the maximum allowed size.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `max_size`: The maximum allowed file size in bytes.

```json theme={null}
[
  {
    "loc": ["body", "upload_file"],
    "msg": "File too large",
    "type": "file_too_large",
    "url": "https://docs.fal.ai/errors/#file_too_large",
    "ctx": {
      "max_size": 10485760 // 10MB
    },
    "input": "https://example.com/large_video.mp4"
  }
]
```

##### `greater_than`

This error occurs when a numeric input value is not strictly greater than the specified threshold.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `gt`: The value the input must be greater than.

```json theme={null}
[
  {
    "loc": ["body", "num_inference_steps"],
    "msg": "Input should be greater than 0",
    "type": "greater_than",
    "url": "https://docs.fal.ai/errors/#greater_than",
    "ctx": {
      "gt": 0
    },
    "input": 0
  }
]
```

##### `greater_than_equal`

This error occurs when a numeric input value is less than the specified threshold.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `ge`: The value the input must be greater than or equal to.

```json theme={null}
[
  {
    "loc": ["body", "strength"],
    "msg": "Input should be greater than or equal to 0",
    "type": "greater_than_equal",
    "url": "https://docs.fal.ai/errors/#greater_than_equal",
    "ctx": {
      "ge": 0
    },
    "input": -0.5
  }
]
```

##### `less_than`

This error occurs when a numeric input value is not strictly less than the specified threshold.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `lt`: The value the input must be less than.

```json theme={null}
[
  {
    "loc": ["body", "negative_prompt_weight"],
    "msg": "Input should be less than 1",
    "type": "less_than",
    "url": "https://docs.fal.ai/errors/#less_than",
    "ctx": {
      "lt": 1.0
    },
    "input": 1.0
  }
]
```

##### `less_than_equal`

This error occurs when a numeric input value is greater than the specified threshold.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `le`: The value the input must be less than or equal to.

```json theme={null}
[
  {
    "loc": ["body", "guidance_scale"],
    "msg": "Input should be less than or equal to 20",
    "type": "less_than_equal",
    "url": "https://docs.fal.ai/errors/#less_than_equal",
    "ctx": {
      "le": 20
    },
    "input": 21
  }
]
```

##### `multiple_of`

This error indicates that a numeric input value is not a multiple of the required factor.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `multiple_of`: The factor the input must be a multiple of.

```json theme={null}
[
  {
    "loc": ["body", "width"],
    "msg": "Input should be a multiple of 8",
    "type": "multiple_of",
    "url": "https://docs.fal.ai/errors/#multiple_of",
    "ctx": {
      "multiple_of": 8
    },
    "input": 513
  }
]
```

##### `sequence_too_short`

This error occurs when a sequence (like a list or string) has fewer items/characters than the required minimum length.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `min_length`: The minimum required length of the sequence.

```json theme={null}
[
  {
    "loc": ["body", "prompts"],
    "msg": "Sequence should have at least 1 items",
    "type": "sequence_too_short",
    "url": "https://docs.fal.ai/errors/#sequence_too_short",
    "ctx": {
      "min_length": 1
    },
    "input": []
  }
]
```

##### `sequence_too_long`

This error occurs when a sequence (like a list or string) has more items/characters than the allowed maximum length.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `max_length`: The maximum allowed length of the sequence.

```json theme={null}
[
  {
    "loc": ["body", "controlnet_images"],
    "msg": "Sequence should have at most 4 items",
    "type": "sequence_too_long",
    "url": "https://docs.fal.ai/errors/#sequence_too_long",
    "ctx": {
      "max_length": 4
    },
    "input": ["img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg", "img5.jpg"]
  }
]
```

##### `one_of`

This error indicates that the input value provided for a field is not among the set of allowed values.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `expected`: A list containing the allowed values.

```json theme={null}
[
  {
    "loc": ["body", "scheduler"],
    "msg": "Input should be 'EulerA' or 'DPM++'",
    "type": "one_of",
    "url": "https://docs.fal.ai/errors/#one_of",
    "ctx": {
      "expected": ["EulerA", "DPM++"]
    },
    "input": "InvalidScheduler"
  }
]
```

##### `feature_not_supported`

This error is raised when the combination of input parameters requests a feature or mode that is not supported by the endpoint.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):** None

```json theme={null}
[
  {
    "loc": ["body", "advanced_feature"],
    "msg": "Feature not supported",
    "type": "feature_not_supported",
    "url": "https://docs.fal.ai/errors/#feature_not_supported",
    "input": true
  }
]
```

##### `invalid_archive`

This error occurs when the provided archive file (e.g., .zip, .tar) cannot be read or processed, likely due to corruption or an unsupported format.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `supported_extensions`: A list of supported archive file extensions.

```json theme={null}
[
  {
    "loc": ["body", "training_data"],
    "msg": "Could not read or process the provided archive. Ensure it's a valid, non-corrupted archive.",
    "type": "invalid_archive",
    "url": "https://docs.fal.ai/errors/#invalid_archive",
    "ctx": {
      "supported_extensions": [".zip", ".tar.gz"]
    },
    "input": "https://example.com/corrupted_archive.rar"
  }
]
```

##### `archive_file_count_below_minimum`

This error indicates that the provided archive contains fewer files matching the required criteria (e.g., specific extensions) than the minimum required count.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `min_count`: The minimum number of required files.
  * `provided_count`: The number of matching files found in the archive.
  * `supported_extensions`: The file extensions that were counted. (e.g., extensions like `.jpg`, `.png` when used for image archives or `.mp4` when used for video archives).

```json theme={null}
[
  {
    "loc": ["body", "image_archive"],
    "msg": "Too few files in the archive. Expected at least 10 files with extensions .jpg, .png, found 8. Add more matching files to the archive.",
    "type": "archive_file_count_below_minimum",
    "url": "https://docs.fal.ai/errors/#archive_file_count_below_minimum",
    "ctx": {
      "min_count": 10,
      "provided_count": 8,
      "supported_extensions": [".jpg", ".png"]
    },
    "input": "https://example.com/images_few.zip"
  }
]
```

##### `archive_file_count_exceeds_maximum`

This error indicates that the provided archive contains more files matching the required criteria (e.g., specific extensions) than the maximum allowed count.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `max_count`: The maximum number of allowed files.
  * `provided_count`: The number of matching files found in the archive.
  * `supported_extensions`: The file extensions that were counted. (e.g., extensions like `.jpg`, `.png` when used for image archives or `.mp4` when used for video archives).

```json theme={null}
[
  {
    "loc": ["body", "image_archive"],
    "msg": "Too many files in the archive. Maximum is 100 files with extensions .jpg, .png, found 150. Remove 50 matching files from the archive.",
    "type": "archive_file_count_exceeds_maximum",
    "url": "https://docs.fal.ai/errors/#archive_file_count_exceeds_maximum",
    "ctx": {
      "max_count": 100,
      "provided_count": 150,
      "supported_extensions": [".jpg", ".png"]
    },
    "input": "https://example.com/images_many.zip"
  }
]
```

##### `audio_duration_too_long`

This error indicates that the provided audio file exceeds the maximum allowed duration.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `max_duration`: The maximum allowed duration in seconds.
  * `provided_duration`: The duration of the provided audio file in seconds.

```json theme={null}
[
  {
    "loc": ["body", "audio_file"],
    "msg": "Audio duration exceeds the maximum allowed. Maximum is 60 seconds, provided is 90 seconds.",
    "type": "audio_duration_too_long",
    "url": "https://docs.fal.ai/errors/#audio_duration_too_long",
    "ctx": {
      "max_duration": 60,
      "provided_duration": 90
    },
    "input": "https://example.com/long_audio.mp3"
  }
]
```

##### `audio_duration_too_short`

This error indicates that the provided audio file is shorter than the minimum required duration.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `min_duration`: The minimum required duration in seconds.
  * `provided_duration`: The duration of the provided audio file in seconds.

```json theme={null}
[
  {
    "loc": ["body", "audio_file"],
    "msg": "Audio duration is too short. Minimum is 5 seconds, provided is 2 seconds.",
    "type": "audio_duration_too_short",
    "url": "https://docs.fal.ai/errors/#audio_duration_too_short",
    "ctx": {
      "min_duration": 5,
      "provided_duration": 2
    },
    "input": "https://example.com/short_audio.mp3"
  }
]
```

##### `unsupported_audio_format`

This error indicates that the audio file format is not supported by the endpoint.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `supported_formats`: A list of supported audio file extensions.

```json theme={null}
[
  {
    "loc": ["body", "audio_file"],
    "msg": "Unsupported audio format. Supported formats are .mp3, .wav, .ogg.",
    "type": "unsupported_audio_format",
    "url": "https://docs.fal.ai/errors/#unsupported_audio_format",
    "ctx": {
      "supported_formats": [".mp3", ".wav", ".ogg"]
    },
    "input": "https://example.com/audio.midi"
  }
]
```

##### `unsupported_image_format`

This error indicates that the image file format is not supported by the endpoint.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `supported_formats`: A list of supported image file extensions.

```json theme={null}
[
  {
    "loc": ["body", "image"],
    "msg": "Unsupported image format. Supported formats are .jpg, .jpeg, .png, .webp.",
    "type": "unsupported_image_format",
    "url": "https://docs.fal.ai/errors/#unsupported_image_format",
    "ctx": {
      "supported_formats": [".jpg", ".jpeg", ".png", ".webp"]
    },
    "input": "https://example.com/image.tiff"
  }
]
```

##### `unsupported_video_format`

This error indicates that the video file format is not supported by the endpoint.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `supported_formats`: A list of supported video file extensions.

```json theme={null}
[
  {
    "loc": ["body", "video_file"],
    "msg": "Unsupported video format. Supported formats are .mp4, .mov, .webm.",
    "type": "unsupported_video_format",
    "url": "https://docs.fal.ai/errors/#unsupported_video_format",
    "ctx": {
      "supported_formats": [".mp4", ".mov", ".webm"]
    },
    "input": "https://example.com/video.avi"
  }
]
```

##### `video_duration_too_long`

This error indicates that the provided video file exceeds the maximum allowed duration.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `max_duration`: The maximum allowed duration in seconds.
  * `provided_duration`: The duration of the provided video file in seconds.

```json theme={null}
[
  {
    "loc": ["body", "video_file"],
    "msg": "Video duration exceeds the maximum allowed. Maximum is 60 seconds, provided is 120 seconds.",
    "type": "video_duration_too_long",
    "url": "https://docs.fal.ai/errors/#video_duration_too_long",
    "ctx": {
      "max_duration": 60,
      "provided_duration": 120
    },
    "input": "https://example.com/long_video.mp4"
  }
]
```

##### `video_duration_too_short`

This error indicates that the provided video file is shorter than the minimum required duration.

* **Status Code:** 422
* **Retryable:** `false`.
* **Context (`ctx`):**
  * `min_duration`: The minimum required duration in seconds.
  * `provided_duration`: The duration of the provided video file in seconds.

```json theme={null}
[
  {
    "loc": ["body", "video_file"],
    "msg": "Video duration is too short. Minimum is 3 seconds, provided is 1 seconds.",
    "type": "video_duration_too_short",
    "url": "https://docs.fal.ai/errors/#video_duration_too_short",
    "ctx": {
      "min_duration": 3,
      "provided_duration": 1
    },
    "input": "https://example.com/short_video.mp4"
  }
]
```

## Request Error Types

In addition to model-level validation errors, the platform returns structured error responses for infrastructure-level failures such as timeouts, runner issues, and connection errors. These errors occur before or during request processing, rather than from the model itself.

### Request Error Response Structure

Request errors return a JSON body with the following fields:

| Property     | Description                                                                 |
| :----------- | :-------------------------------------------------------------------------- |
| `detail`     | A human-readable description of the error.                                  |
| `error_type` | A machine-readable string identifying the error category (see table below). |

The response also includes an `X-Fal-Error-Type` header with the same value as `error_type`.

```json theme={null}
{
  "detail": "Request timed out",
  "error_type": "request_timeout"
}
```

<Note>
  This error format is different from [model-level errors](#error-types), which return a `detail` array of error objects. Request errors return a flat object with `detail` as a string.
</Note>

### Request Error Type Reference

| Error Type                   | Description                                                                                                              | Typical Status Code |
| :--------------------------- | :----------------------------------------------------------------------------------------------------------------------- | :------------------ |
| `request_timeout`            | The request exceeded the allowed processing time.                                                                        | 504                 |
| `startup_timeout`            | The runner did not start within the allowed time (see [Start Timeout](/model-apis/model-endpoints/queue#start-timeout)). | 504                 |
| `runner_scheduling_failure`  | No runner could be allocated to handle the request.                                                                      | 503                 |
| `runner_connection_timeout`  | The connection to the runner timed out.                                                                                  | 503                 |
| `runner_disconnected`        | The runner disconnected unexpectedly during processing.                                                                  | 503                 |
| `runner_connection_refused`  | The runner refused the connection.                                                                                       | 503                 |
| `runner_connection_error`    | A general connection error occurred with the runner.                                                                     | 503                 |
| `runner_incomplete_response` | The runner sent an incomplete response payload.                                                                          | 502                 |
| `runner_server_error`        | The runner encountered an internal server error.                                                                         | 500                 |
| `client_disconnected`        | The client closed the connection before the response was sent.                                                           | 499                 |
| `client_cancelled`           | The request was cancelled by the client.                                                                                 | 499                 |
| `bad_request`                | The request was malformed (e.g., invalid timeout header).                                                                | 400                 |
| `internal_error`             | An unexpected internal error occurred.                                                                                   | 500                 |

### Guidance

* **For retry logic:** Use `error_type` to decide whether to retry. Runner and timeout errors (e.g., `runner_connection_timeout`, `startup_timeout`) are typically transient and worth retrying. Client errors (`client_disconnected`, `bad_request`) should not be retried. See also [Automatic Retries](/model-apis/model-endpoints/reliability#automatic-retries).
* **For monitoring:** The `error_type` is also available in [queue status responses](/model-apis/model-endpoints/queue#status-types) for failed requests, making it useful for tracking failure patterns.


# https://fal.ai/docs/documentation/model-apis/fal-cdn.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# fal CDN

> Upload files to fal's CDN to use as inputs when calling models.

Models on fal accept file inputs as **URLs**, and model outputs (generated images, videos, audio) are also returned as CDN URLs. If you have a local file you want to pass to a model, upload it to fal's CDN first to get a URL, then pass that URL as input. Some models also accept **data URIs** (`data:image/png;base64,...`) for inline file content, but URLs are the universal format that works with every model.

The CDN is the recommended approach for file inputs. You upload once, get a persistent URL, and reuse it across as many [inference](/documentation/model-apis/inference) requests as you need. The SDK automatically handles reliability by falling back between multiple upload endpoints if one is unavailable. If you already host files on S3, GCS, or your own server, you can skip the upload and pass those URLs directly.

## Uploading Files

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  # Upload a local file
  url = fal_client.upload_file("path/to/image.png")
  print(url)  # https://v3.fal.media/files/rabbit/YYbm6L.png

  # Upload raw bytes
  url = fal_client.upload(image_bytes, "image/png")
  ```

  ```python Python (async) theme={null}
  import fal_client

  # Upload a local file
  url = await fal_client.upload_file_async("path/to/image.png")
  print(url)  # https://v3.fal.media/files/rabbit/YYbm6L.png

  # Upload raw bytes
  url = await fal_client.upload_async(image_bytes, "image/png")
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const file = new File(["..."], "image.png", { type: "image/png" });
  const url = await fal.storage.upload(file);
  console.log(url);  // https://v3.fal.media/files/rabbit/YYbm6L.png
  ```
</CodeGroup>

Then pass the URL to any model:

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/flux/dev", arguments={
      "prompt": "a cat wearing sunglasses",
      "image_url": url  # CDN URL from upload
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/flux/dev", {
    input: {
      prompt: "a cat wearing sunglasses",
      image_url: url  // CDN URL from upload
    }
  });
  ```
</CodeGroup>

## Using Your Own Storage

You don't have to use fal's CDN. If you already have files hosted elsewhere, pass those URLs directly. The model's runner downloads the file from that URL during processing, so the URL must be accessible without additional authentication headers.

**Presigned URLs** from S3, GCS, or R2 work because the auth credentials are embedded in the URL itself:

```python theme={null}
result = fal_client.subscribe("fal-ai/flux/dev", arguments={
    "prompt": "enhance this image",
    "image_url": "https://your-bucket.s3.amazonaws.com/image.png?X-Amz-Signature=..."
})
```

**Public URLs** from any web server also work, as long as they return the file directly without requiring cookies or auth headers.

**Private URLs** that require `Authorization` headers or other credentials will not work as model inputs when calling Model APIs. If your files are behind authentication, download them first and upload to fal's CDN, or generate a presigned URL with a short expiry. If you are building your own [fal App](/documentation/development/app-setup), you can download authenticated files inside your endpoint using [`download_file` with `request_headers`](/documentation/development/working-with-files).

## Data URIs

Models also accept base64-encoded data URIs:

```python theme={null}
result = fal_client.subscribe("fal-ai/flux/dev", arguments={
    "image_url": "data:image/png;base64,iVBORw0KGgo..."
})
```

<Warning>
  Data URIs embed the entire file in the request payload. This inflates the request size significantly, slows down transmission, and is not recommended for files larger than a few KB. Use CDN uploads or external URLs instead.
</Warning>

## Upload Details

| Property           | Value                                                                                                                                                                           |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **CDN URL format** | `https://v3.fal.media/files/{path}`                                                                                                                                             |
| **Large files**    | Automatically uses multipart upload for large files (10 MB chunks). Python SDK: threshold 100 MB, up to 10 parallel chunks. JavaScript SDK: threshold 90 MB, sequential chunks. |
| **Retries**        | Automatic retry up to 10 attempts on transient errors                                                                                                                           |
| **Fallback**       | If the primary endpoint (`v3.fal.media`) is unavailable, the SDK automatically falls back to `fal.media`, then to the REST API                                                  |
| **Auth**           | Handled automatically by the SDK using your `FAL_KEY`                                                                                                                           |
| **Access**         | CDN URLs are publicly accessible. No auth needed to download. Anyone with the URL can access the file.                                                                          |

There are no file type restrictions at the upload level. The SDK handles large files automatically using multipart uploads with chunked transfer. Individual models may enforce their own size and format limits when processing inputs. Check the model's API page for specifics.

## Uploading PIL Images

If you're working with PIL/Pillow images in Python:

```python theme={null}
from PIL import Image
import fal_client

image = Image.open("photo.jpg")
url = fal_client.upload_image(image)
```

This converts the image to JPEG, uploads it, and returns the CDN URL.

## Media Expiration

CDN file retention is configurable. You can set expiration per-request using the `X-Fal-Object-Lifecycle-Preference` header, or configure retention at the account level.

<Card title="Data Retention and Storage" icon="arrow-right" href="/documentation/model-apis/media-expiration">
  Configure how long CDN files are retained
</Card>

## Building a Serverless App?

If you're building a fal App and need to handle files inside your endpoint code (returning images, downloading inputs), see the server-side guide:

<Card title="Working with Files" icon="arrow-right" href="/documentation/development/working-with-files">
  Server-side file handling: download\_file, File.from\_path, Image.from\_pil
</Card>


# https://fal.ai/docs/documentation/model-apis/faq.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# FAQ

Common questions about using fal. If you can't find the answer here, join our [Discord community](https://discord.gg/fal-ai) or [contact support](mailto:support@fal.ai).

<AccordionGroup>
  <Accordion title="Is there a rate limit?">
    Yes. Every account has a [concurrency limit](/documentation/model-apis/concurrency-limits) that controls how many requests can be processed at the same time. New accounts start at 2 concurrent requests. As you purchase credits, the limit increases automatically up to 40. Requests that exceed your limit are queued and processed as slots free up. For higher limits, [contact sales](https://fal.ai/enterprise#contact-sales).
  </Accordion>

  <Accordion title="Do you charge for failed requests?">
    Server errors (HTTP 500+) are never charged. If a runner fails to process your request due to an infrastructure issue, you pay nothing. Client-side errors like invalid inputs (HTTP 422) may still be charged if a runner spent GPU time processing the request before the error was detected.
  </Accordion>

  <Accordion title="Do my credits expire?">
    Purchased credits expire 365 days from the date of purchase. Free credits and coupons have variable expiration depending on the specific grant, ranging from 1 week to 1 year. Check the [billing dashboard](https://fal.ai/dashboard/billing) for your current credit balance and expiration dates.
  </Accordion>

  <Accordion title="Do I pay for cold starts?">
    No. For Model API endpoints, you are billed only for inference time. Cold start time, including container pull and model loading, is not charged.
  </Accordion>

  <Accordion title="What happens when my credits run out?">
    When your credit balance drops below your account's lock threshold, your account is locked and API requests will be rejected. Add credits from the [billing dashboard](https://fal.ai/dashboard/billing) to unlock your account. Enterprise customers on invoice-based billing are not subject to automatic locking.
  </Accordion>

  <Accordion title="How long are generated files stored?">
    Generated media files (images, videos, audio) are stored on the [fal CDN](/documentation/model-apis/fal-cdn) and available for at least 7 days by default. You can control the retention period per request using the `X-Fal-Object-Lifecycle-Preference` header. See [Data Retention](/documentation/model-apis/media-expiration) for details. Download and store any files you need to keep long-term.
  </Accordion>

  <Accordion title="Are generated file URLs public?">
    Yes. Media URLs returned by fal (`https://v3.fal.media/...`) are publicly accessible. Anyone with the URL can access the file until it expires. If you need private storage, download the files to your own infrastructure.
  </Accordion>

  <Accordion title="Can I use generated files for commercial purposes?">
    Each model has its own license. Most models on fal are available for commercial use and are marked with a `Commercial use` badge on the model page. Models marked `Research only` are restricted to non-commercial use. Check the model's page for its specific license.
  </Accordion>

  <Accordion title="Can I call fal from the browser?">
    Yes, but you should not expose your API key in client-side code. Set up a [server-side proxy](/documentation/model-apis/inference/proxy-setup) that forwards requests to fal from your backend, keeping your key secure.
  </Accordion>

  <Accordion title="Can I deploy my own models?">
    Yes. [fal Serverless](/documentation/serverless) lets you deploy your own models and applications on fal's GPU infrastructure. You can use any Python framework, bring your own Docker image, and scale automatically. See the [quickstart](/documentation/development/getting-started/quick-start) to get started.
  </Accordion>

  <Accordion title="Why was my request rejected with a content policy violation?">
    fal applies content filters on certain models. If your request triggers a `content_policy_violation` error, the input was flagged by automated safety systems. This is a non-retryable 422 error. See the [error reference](/documentation/model-apis/errors) for details on this and other error types.
  </Accordion>

  <Accordion title="What is the Partner API?">
    Models marked `Partner API` are hosted by fal's partners. Percentage discounts do not apply to partner API models, and their availability is managed by the partner.
  </Accordion>

  <Accordion title="Can I switch to invoice-based billing?">
    Yes. Invoice-based billing is available for higher-volume customers. [Contact sales](https://fal.ai/enterprise#contact-sales) with details about your expected usage.
  </Accordion>

  <Accordion title="Do you offer volume discounts?">
    Yes. [Contact sales](https://fal.ai/enterprise#contact-sales) with information about your expected volume to discuss custom pricing.
  </Accordion>

  <Accordion title="When logging in with GitHub, I never receive the one-time code">
    The one-time code is sent to the primary email on your GitHub account. If you no longer monitor that email, check [GitHub's documentation](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/changing-your-primary-email-address) to find or update it.
  </Accordion>
</AccordionGroup>


# https://fal.ai/docs/documentation/model-apis/inference/client-setup.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Client Setup

> Install and configure the fal client library

The fal client is the easiest way to call models on fal. It handles [authentication](/documentation/model-apis/authentication), retries, and provides a clean API for all [inference methods](/documentation/model-apis/inference). Official clients are available for Python, JavaScript/TypeScript, Swift, Java, Kotlin, and Dart, and they all expose the same core methods (`subscribe`, `submit`, `run`, `stream`).

How you configure the client depends on where your code runs. In a server-side environment like a Python script, a Node.js backend, or a serverless function, you set your `FAL_KEY` as an environment variable and the client picks it up automatically. In a client-side environment like a React app running in the browser, you cannot use the API key directly because browser source code is visible to anyone. Instead, the fal client routes requests through a lightweight [proxy](/documentation/model-apis/inference/proxy-setup) on your server, which attaches the key before forwarding to fal. Both approaches are covered in the [Configuration](#configuration) section below.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @fal-ai/client
  ```

  ```bash yarn theme={null}
  yarn add @fal-ai/client
  ```

  ```bash pnpm theme={null}
  pnpm add @fal-ai/client
  ```

  ```bash bun theme={null}
  bun add @fal-ai/client
  ```

  ```bash pip theme={null}
  pip install fal-client
  ```

  ```bash Flutter theme={null}
  flutter pub add fal_client
  ```

  ```swift Swift Package theme={null}
  .package(url: "https://github.com/fal-ai/fal-swift.git", from: "0.5.6")
  ```

  ```groovy Gradle (Java) theme={null}
  implementation 'ai.fal.client:fal-client:0.7.1'
  ```

  ```xml Maven (Java) theme={null}
  <dependency>
      <groupId>ai.fal.client</groupId>
      <artifactId>fal-client</artifactId>
      <version>0.7.1</version>
  </dependency>
  ```

  ```groovy Gradle (Kotlin) theme={null}
  implementation 'ai.fal.client:fal-client-kotlin:0.7.1'
  ```

  ```xml Maven (Kotlin) theme={null}
  <dependency>
      <groupId>ai.fal.client</groupId>
      <artifactId>fal-client-kotlin</artifactId>
      <version>0.7.1</version>
  </dependency>
  ```
</CodeGroup>

<Note>
  **Java Async Support** -- If your code relies on asynchronous operations via `CompletableFuture` or `Future`, use the `ai.fal.client:fal-client-async` artifact instead.
</Note>

***

## Configuration

### Server-side (Python, Node.js)

The simplest path. Set your API key as an environment variable and the client picks it up automatically:

```bash theme={null}
export FAL_KEY="your-api-key-here"
```

No additional configuration is needed. The client reads `FAL_KEY` from the environment on import:

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  result = fal_client.run("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset"
  })
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.run("fal-ai/flux/schnell", {
    input: { prompt: "a sunset" }
  });
  ```
</CodeGroup>

In some environments (serverless functions, containers) you may not have access to shell environment variables. In those cases you can set credentials explicitly in code:

<CodeGroup>
  ```python Python theme={null}
  import os
  os.environ["FAL_KEY"] = "your-api-key-here"

  import fal_client
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  fal.config({
    credentials: "your-api-key-here"
  });
  ```
</CodeGroup>

### Client-side (Browser, React, Next.js)

When building web apps, your API key cannot live in browser code because browser source is visible to anyone. Instead, the fal client routes requests through a lightweight proxy on your server that attaches the key before forwarding to fal. Your API key stays on the server, and all client methods (`subscribe`, `submit`, `run`, `stream`) work transparently through the proxy.

The setup has two parts: create a proxy route on your server and point the client at it. Here is the quickest path using Next.js:

```bash theme={null}
npm install @fal-ai/server-proxy
```

Create `app/api/fal/proxy/route.ts` (App Router):

```typescript theme={null}
import { createRouteHandler } from "@fal-ai/server-proxy/nextjs";

export const { GET, POST, PUT } = createRouteHandler();
```

Then configure the client in your frontend code:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  proxyUrl: "/api/fal/proxy"
});

const result = await fal.subscribe("fal-ai/flux/schnell", {
  input: { prompt: "a sunset" }
});
```

Make sure `FAL_KEY` is set as an environment variable on your server. The proxy reads it from the environment, just like the server-side setup above.

<Card title="Proxy Setup" icon="arrow-right" href="/documentation/model-apis/inference/proxy-setup">
  Pages Router, Vercel, Express, custom frameworks, and how the proxy works under the hood
</Card>

***

## Making Your First Call

Once configured, you can call any model:

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
      "prompt": "a futuristic cityscape at sunset",
      "image_size": "landscape_16_9"
  })

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

  ```python Python (async) theme={null}
  import asyncio
  import fal_client

  async def main():
      result = await fal_client.subscribe_async(
          "fal-ai/flux/schnell",
          arguments={
              "prompt": "a futuristic cityscape at sunset",
              "image_size": "landscape_16_9"
          },
      )
      print(result["images"][0]["url"])

  asyncio.run(main())
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/flux/schnell", {
    input: {
      prompt: "a futuristic cityscape at sunset",
      image_size: "landscape_16_9"
    }
  });

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

  ```swift Swift theme={null}
  import FalClient

  let result = try await fal.subscribe(
      to: "fal-ai/flux/schnell",
      input: [
          "prompt": "a futuristic cityscape at sunset",
          "image_size": "landscape_16_9"
      ],
      includeLogs: true
  ) { update in
      if case let .inProgress(logs) = update {
          print(logs)
      }
  }
  ```

  ```java Java theme={null}
  import ai.fal.client.*;
  import ai.fal.client.queue.*;

  var fal = FalClient.withEnvCredentials();

  var result = fal.subscribe("fal-ai/flux/schnell",
      SubscribeOptions.<JsonObject>builder()
          .input(Map.of(
              "prompt", "a futuristic cityscape at sunset",
              "image_size", "landscape_16_9"
          ))
          .logs(true)
          .resultType(JsonObject.class)
          .build()
  );
  ```

  ```kotlin Kotlin theme={null}
  import ai.fal.client.kt

  val fal = createFalClient()

  val result = fal.subscribe("fal-ai/flux/schnell",
      mapOf(
          "prompt" to "a futuristic cityscape at sunset",
          "image_size" to "landscape_16_9"
      ),
      options = SubscribeOptions(logs = true)
  ) { update ->
      if (update is QueueStatus.InProgress) {
          println(update.logs)
      }
  }
  ```

  ```dart Dart (Flutter) theme={null}
  import 'package:fal_client/fal_client.dart';

  final fal = FalClient.withCredentials("FAL_KEY");

  final output = await fal.subscribe("fal-ai/flux/schnell",
    input: {
      "prompt": "a futuristic cityscape at sunset",
      "image_size": "landscape_16_9"
    },
    logs: true,
    onQueueUpdate: (update) { print(update); }
  );

  print(output.data);
  ```
</CodeGroup>

***

## Client Methods

| Method        | How it works                              | Uses Queue |
| ------------- | ----------------------------------------- | ---------- |
| `run()`       | Direct synchronous call                   | No         |
| `subscribe()` | Blocks until result, polls automatically  | Yes        |
| `submit()`    | Returns immediately, poll or use webhooks | Yes        |
| `stream()`    | Progressive output via SSE                | No         |
| `realtime()`  | WebSocket connection                      | No         |

Every method in the Python SDK has an async counterpart with an `_async` suffix (e.g., `subscribe_async`, `submit_async`, `run_async`, `stream_async`, `realtime_async`). Use these when working with `asyncio`.

***

## API References and Support

<CardGroup cols={3}>
  <Card title="JavaScript / TypeScript" icon="js" href="https://fal-ai.github.io/fal-js/reference">
    API docs and [GitHub repo](https://github.com/fal-ai/fal-js)
  </Card>

  <Card title="Python" icon="python" href="https://fal-ai.github.io/fal/client">
    API docs and [GitHub repo](https://github.com/fal-ai/fal)
  </Card>

  <Card title="Swift (iOS)" icon="swift" href="https://swiftpackageindex.com/fal-ai/fal-swift/documentation/falclient">
    API docs and [GitHub repo](https://github.com/fal-ai/fal-swift)
  </Card>

  <Card title="Java / Kotlin" icon="java" href="https://fal-ai.github.io/fal-java/fal-client/index.html">
    API docs and [GitHub repo](https://github.com/fal-ai/fal-java)
  </Card>

  <Card title="Dart (Flutter)" icon="flutter" href="https://pub.dev/documentation/fal_client/latest">
    API docs and [GitHub repo](https://github.com/fal-ai/fal-dart)
  </Card>

  <Card title="Community" icon="discord" href="https://discord.gg/fal-ai">
    Get help on Discord
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/model-apis/inference/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Inference Methods

> Learn the different ways to call models on fal

Every model on fal can be called through the same set of inference methods, whether it is a pre-trained model from the [gallery](https://fal.ai/models) or your own app running on [Serverless](/documentation/serverless). This page walks through each method, explains when to reach for it, and links to the deeper reference pages. Before calling any model you will need an [API key](/documentation/model-apis/authentication) and the [fal client](/documentation/model-apis/inference/client-setup) installed in your project.

fal provides five calling patterns that cover the spectrum from quick prototyping to high-throughput production pipelines. All of them benefit from fal's autoscaling infrastructure, where [runners](/documentation/deployment/runners) spin up on demand to handle your requests. The key decision is whether you need the [queue](/documentation/model-apis/inference/queue) (recommended for reliability), a direct call (simplest path), [streaming](/documentation/model-apis/inference/streaming) (progressive output), or a [real-time WebSocket](/documentation/model-apis/inference/real-time) connection (lowest latency). Each method is covered below with a code example and guidance on when it is the right fit.

<Tip>
  These calling patterns work identically for your own deployed serverless apps. Use your app's endpoint ID (e.g., `your-username/your-app-name`) instead of a model ID. See [Calling Your Endpoints](/documentation/development/calling-your-endpoints) for serverless-specific examples.
</Tip>

| Method            | How it works                                   |
| ----------------- | ---------------------------------------------- |
| **`run()`**       | Direct HTTP call, no queue                     |
| **`subscribe()`** | Queue-based, blocks until result               |
| **`submit()`**    | Queue-based, returns immediately (recommended) |
| **`stream()`**    | Progressive output via SSE                     |
| **`realtime()`**  | WebSocket, persistent connection               |

***

## Direct (`run`)

The simplest way to call a model. Sends a direct HTTP request to `fal.run` and returns the result. No queue, no retries, no polling.

```python theme={null}
import fal_client

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

Use `run` for quick scripts, prototyping, or any model with fast response times where you want the lowest overhead. Because there is no queue involved, the call goes straight to a runner and returns the response directly. The tradeoff is that direct calls do not retry on failure. If the runner returns an error or times out, you get the error immediately.

<Warning>
  For production use, prefer `subscribe` or `submit` so you get automatic retries and request durability through the [queue](/documentation/model-apis/inference/queue).
</Warning>

<Card title="Learn more" icon="arrow-right" href="/documentation/model-apis/inference/synchronous">
  Direct and queue-backed synchronous calls
</Card>

***

## Subscribe (Queue-backed synchronous)

Like `run`, but uses the queue under the hood. Submits a request, polls automatically, and blocks until the result is ready. You get automatic retries and reliability with a simple interface.

```python theme={null}
import fal_client

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

`subscribe` is a good choice when you want the simplicity of a blocking call combined with queue-backed reliability. It handles polling for you, so the code looks almost identical to `run`, but your request is durable and will be retried if a runner fails. Reach for it in simple integrations, backend scripts, or anywhere you do not need to manage the request lifecycle yourself.

<Card title="Learn more" icon="arrow-right" href="/documentation/model-apis/inference/synchronous">
  Direct and queue-backed synchronous calls
</Card>

***

## Asynchronous (`submit`)

The recommended approach for production. Submit a request to the [queue](/documentation/model-apis/inference/queue) and return immediately, then poll for status or receive results via [webhook](/documentation/model-apis/inference/webhooks).

**Polling:**

```python theme={null}
import time
import fal_client

handler = fal_client.submit("fal-ai/nano-banana-2", arguments={
    "prompt": "a sunset over mountains"
})

while True:
    status = handler.status(with_logs=True)

    if isinstance(status, fal_client.Queued):
        print(f"In queue, position: {status.position}")
    elif isinstance(status, fal_client.InProgress):
        for log in status.logs or []:
            print(log["message"])
    elif isinstance(status, fal_client.Completed):
        print(f"Done in {status.metrics.get('inference_time', '?')}s")
        break

    time.sleep(0.5)

result = handler.get()
print(result["images"][0]["url"])
```

### Status types

The `handler.status()` method returns one of three types. Pass `with_logs=True` to include runner logs.

| Type         | Fields                                  | Meaning                                                                           |
| ------------ | --------------------------------------- | --------------------------------------------------------------------------------- |
| `Queued`     | `position` (int)                        | Waiting in queue. `position` is how many requests are ahead.                      |
| `InProgress` | `logs` (list or None)                   | A runner is processing the request. `logs` contains messages if `with_logs=True`. |
| `Completed`  | `logs` (list or None), `metrics` (dict) | Result is ready. `metrics` includes `inference_time` in seconds.                  |

In JavaScript, the equivalent types are `InQueueQueueStatus`, `InProgressQueueStatus`, and `CompletedQueueStatus`. See the full [Python SDK reference](/api-reference/client-libraries/python/fal_client#status) and [JavaScript SDK reference](/api-reference/client-libraries/javascript/types.common) for details.

**Webhook (no polling needed):**

```python theme={null}
import fal_client

handler = fal_client.submit("fal-ai/nano-banana-2",
    arguments={"prompt": "a sunset over mountains"},
    webhook_url="https://your-server.com/api/webhook"
)
```

Async inference is the recommended path for production because it works reliably at any scale. You can submit many requests in parallel and process them as they complete, use webhooks to build event-driven architectures without polling, and get full visibility into queue position and runner logs. The queue handles retries and request persistence automatically through the [reliability layer](/documentation/model-apis/inference/reliability).

<Card title="Learn Async Inference" icon="arrow-right" href="/documentation/model-apis/inference/queue">
  The recommended way to call models at scale
</Card>

***

## Streaming (`stream`)

For models that produce output progressively. Each event arrives as it is generated, so you can display partial results without waiting for the full response. This is useful for showing image generation previews or streaming LLM tokens.

```python theme={null}
import fal_client

for event in fal_client.stream("fal-ai/flux-kontext-lora", arguments={
    "prompt": "a sunset over mountains"
}):
    print(event)
```

<Note>
  The `stream()` method connects to the `/stream` path on the model endpoint. Not all models support streaming. Check the model's API documentation for availability.
</Note>

<Card title="Learn Streaming" icon="arrow-right" href="/documentation/model-apis/inference/streaming">
  Receive output as it's generated
</Card>

***

## Real-time (`realtime`)

For interactive applications that need the lowest possible latency. Opens a persistent WebSocket connection to a warm runner, enabling back-to-back requests without reconnection overhead. Only available for models with an explicit real-time endpoint.

```python theme={null}
import fal_client

with fal_client.realtime("fal-ai/fast-sdxl") as connection:
    connection.send({
        "prompt": "a sunset over mountains",
        "num_inference_steps": 2
    })
    result = connection.recv()
    print(result)
```

<Card title="Learn Real-time" icon="arrow-right" href="/documentation/model-apis/inference/real-time">
  WebSocket connections for interactive apps
</Card>

***

## Getting Started

Before calling any model, install and configure the fal client for your language. If you are building a browser-based app, you will also need a server-side proxy to keep your API key out of client-side code.

<CardGroup cols={2}>
  <Card title="Client Setup" icon="code" href="/documentation/model-apis/inference/client-setup">
    Install and configure the fal client
  </Card>

  <Card title="Proxy Setup" icon="shield" href="/documentation/model-apis/inference/proxy-setup">
    Keep your API key secure in client-side apps
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/model-apis/inference/proxy-setup.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Proxy Setup

> Keep your API key secure in client-side applications

When the fal client runs in a browser, it cannot use your API key directly because browser source code is visible to anyone. Instead, it sends requests to a proxy endpoint on your server, which attaches the key and forwards the request to fal. The [Client Setup](/documentation/model-apis/inference/client-setup#client-side-browser-react-next-js) page covers the quickest path using Next.js App Router. This page goes deeper with alternative frameworks, deployment platforms, and the underlying proxy protocol.

The proxy sits between the browser and fal's API. When the fal client makes a request, it sends it to your proxy URL (e.g., `/api/fal/proxy`) with the real fal endpoint in an `x-fal-target-url` header. Your proxy reads that header, adds your `FAL_KEY` via the `Authorization` header, forwards the request to fal, and pipes the response back to the browser. This means your key never leaves the server.

## Next.js App Router

Create `app/api/fal/proxy/route.ts`:

```typescript theme={null}
import { createRouteHandler } from "@fal-ai/server-proxy/nextjs";

export const { GET, POST, PUT } = createRouteHandler();
```

## Next.js Pages Router

If you are using the Pages Router instead of App Router, create `pages/api/fal/proxy/[...path].ts`:

```typescript theme={null}
import { createPageRouterHandler } from "@fal-ai/server-proxy/nextjs";

export default createPageRouterHandler();
```

The client configuration is the same for both routers:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  proxyUrl: "/api/fal/proxy"
});
```

<CardGroup cols={2}>
  <Card title="Full Next.js Example" icon="arrow-right" href="/examples/integrations/nextjs">
    Complete walkthrough with working code
  </Card>

  <Card title="Vercel Integration" icon="arrow-right" href="/examples/integrations/vercel">
    Deploy AI apps on Vercel with fal
  </Card>
</CardGroup>

## Proxy Configuration

Both `createRouteHandler()` and `createPageRouterHandler()` accept a `ProxyConfig` object to control security and access.

```typescript theme={null}
import { createRouteHandler } from "@fal-ai/server-proxy/nextjs";

export const { GET, POST, PUT } = createRouteHandler({
  allowedEndpoints: ["fal-ai/flux/**", "fal-ai/fast-sdxl"],
  allowUnauthorizedRequests: false,
});
```

| Option                      | Type                             | Default                              | Description                                                                                                                          |
| --------------------------- | -------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `allowedUrlPatterns`        | `string[]`                       | `["fal.run/**", "queue.fal.run/**"]` | Glob patterns for allowed target URLs (without scheme). Add patterns like `"fal.ai/**"` if needed.                                   |
| `allowedEndpoints`          | `string[]`                       | `[]` (all allowed)                   | Glob patterns for allowed POST endpoints (path without leading slash, e.g. `"fal-ai/flux/**"`). An empty array allows all endpoints. |
| `allowUnauthorizedRequests` | `boolean`                        | `true`                               | Whether to allow requests without authentication. Set to `false` in production and provide `isAuthenticated`.                        |
| `isAuthenticated`           | `(behavior) => Promise<boolean>` | Checks for `Authorization` header    | Custom function to determine if the incoming request is authenticated.                                                               |
| `resolveFalAuth`            | `(behavior) => Promise<string>`  | Uses `FAL_KEY` env var               | Custom function to resolve the fal API authorization value.                                                                          |

<Warning>
  The default configuration allows all endpoints and unauthenticated requests for backwards compatibility. For production, set `allowedEndpoints` to restrict which models can be called through your proxy and `allowUnauthorizedRequests: false` to require authentication.
</Warning>

<Note>
  The old `handler` and `route` exports from `@fal-ai/server-proxy/nextjs` are deprecated. Migrate to `createPageRouterHandler()` and `createRouteHandler()` respectively.
</Note>

## Vercel

If you are deploying to Vercel, the Next.js proxy setup works out of the box. Set your `FAL_KEY` as an environment variable in your Vercel project settings (Settings > Environment Variables) and the proxy route will read it automatically. No additional configuration is needed beyond what is described in [Client Setup](/documentation/model-apis/inference/client-setup#client-side-browser-react-next-js).

## Custom Proxy (Express, Flask, etc.)

If you are not using Next.js, you can implement the proxy with any framework. The proxy endpoint needs to:

1. Accept all HTTP methods (GET, POST, PUT, DELETE)
2. Read the target URL from the `x-fal-target-url` header
3. Add your API key via the `Authorization` header
4. Forward the request to fal and return the response

```javascript Express.js theme={null}
const express = require("express");
const fetch = require("node-fetch");

const app = express();
app.use(express.raw({ type: "*/*", limit: "50mb" }));

app.all("/api/fal/proxy/*", async (req, res) => {
  const targetUrl = req.headers["x-fal-target-url"];
  
  if (!targetUrl) {
    return res.status(400).json({ error: "Missing target URL" });
  }

  const response = await fetch(targetUrl, {
    method: req.method,
    headers: {
      ...req.headers,
      "Authorization": `Key ${process.env.FAL_KEY}`,
      "host": new URL(targetUrl).host
    },
    body: req.method !== "GET" ? req.body : undefined
  });

  res.status(response.status);
  response.headers.forEach((value, key) => res.setHeader(key, value));
  response.body.pipe(res);
});
```

Then configure the client in your frontend code to point at your proxy:

```javascript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  proxyUrl: "/api/fal/proxy"
});
```

<Tip>
  The proxy URL should be relative to your application root. The client automatically constructs the full URL based on the current origin.
</Tip>


# https://fal.ai/docs/documentation/model-apis/inference/queue.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Asynchronous Inference

> The recommended way to call models on fal

Asynchronous inference is the recommended way to call models on fal. You submit a request to a persistent [queue](/documentation/model-apis/inference/reliability), then retrieve results later by polling for status or receiving them via [webhook](/documentation/model-apis/inference/webhooks). If you prefer a simpler blocking call that handles polling for you automatically, use [subscribe](/documentation/model-apis/inference/synchronous) instead.

The async approach gives you full control over the request lifecycle. You can submit many requests in parallel and process them as they complete, get real-time visibility into queue position and [runner](/documentation/deployment/runners) logs, and rely on [automatic retries](/documentation/serverless/reliability/retries) when failures occur. All of this works identically whether you are calling a pre-trained model from the gallery or your own app deployed on [Serverless](/documentation/serverless). This page covers the full queue API: submitting requests, checking status, streaming updates, retrieving results, cancelling, and configuring webhooks.

***

## How the Queue Works

When you submit a request to `queue.fal.run`, it enters a persistent, durable queue. The request moves through three states before completion:

### Request Lifecycle

| Status        | SDK Type (Python / JS)                     | What is happening                                                      |
| ------------- | ------------------------------------------ | ---------------------------------------------------------------------- |
| `IN_QUEUE`    | `Queued(position)` / `"IN_QUEUE"`          | Request is received and stored. Waiting for an available runner.       |
| `IN_PROGRESS` | `InProgress(logs)` / `"IN_PROGRESS"`       | fal's dispatcher has routed the request to a runner.                   |
| `COMPLETED`   | `Completed(logs, metrics)` / `"COMPLETED"` | Result is stored and available for retrieval, or sent to your webhook. |

See the [Python SDK reference](/api-reference/client-libraries/python/fal_client#status) or [JavaScript SDK reference](/api-reference/client-libraries/javascript/types.common) for the full type definitions.

### Key Guarantees

Requests in the queue are never dropped. If no runners are available, your request waits while fal [scales up new runners](/documentation/deployment/scale-your-application) automatically. There is no queue size limit. If a runner fails during processing (503, 504, or a connection error), the request is automatically re-queued and [retried](/documentation/model-apis/inference/reliability) up to 10 times. As demand grows, runners scale up to match. When demand drops, they scale back down, so you only pay for compute you use.

***

## Submit a Request

Use `submit` to send a request to the queue and return immediately. In Python, `submit()` returns a `SyncRequestHandle` object with methods for status, result, and cancel (`submit_async()` returns an `AsyncRequestHandle`). In JavaScript, `submit()` returns an object with the `request_id`, and you use separate `fal.queue.*` functions. In the REST API, the response includes URLs for each operation.

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  handler = fal_client.submit("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset over mountains"
  })

  print(handler.request_id)
  ```

  ```python Python (async) theme={null}
  import asyncio
  import fal_client

  async def main():
      handler = await fal_client.submit_async("fal-ai/flux/schnell", arguments={
          "prompt": "a sunset over mountains"
      })
      print(handler.request_id)

  asyncio.run(main())
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const { request_id } = await fal.queue.submit("fal-ai/flux/schnell", {
    input: { prompt: "a sunset over mountains" },
  });

  console.log(request_id);
  ```

  ```bash cURL theme={null}
  curl -X POST https://queue.fal.run/fal-ai/flux/schnell \
    -H "Authorization: Key $FAL_KEY" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset over mountains"}'
  ```
</CodeGroup>

The submit response includes the `request_id` and convenience URLs for tracking the request:

```json theme={null}
{
  "request_id": "764cabcf-b745-4b3e-ae38-1200304cf45b",
  "response_url": "https://queue.fal.run/fal-ai/flux/schnell/requests/764cabcf.../response",
  "status_url": "https://queue.fal.run/fal-ai/flux/schnell/requests/764cabcf.../status",
  "cancel_url": "https://queue.fal.run/fal-ai/flux/schnell/requests/764cabcf.../cancel",
  "queue_position": 0
}
```

Store the `request_id` if you need to check status or retrieve results later, even from a different process.

***

## Check Status

Poll for the current state of the request. Pass `with_logs=True` (Python) or `logs: true` (JS) or `?logs=1` (REST) to include runner log output.

<CodeGroup>
  ```python Python theme={null}
  status = handler.status(with_logs=True)
  if isinstance(status, fal_client.Queued):
      print(f"Position: {status.position}")
  elif isinstance(status, fal_client.InProgress):
      for log in status.logs:
          print(log["message"])
  ```

  ```python Python (async) theme={null}
  status = await handler.status(with_logs=True)
  if isinstance(status, fal_client.Queued):
      print(f"Position: {status.position}")
  elif isinstance(status, fal_client.InProgress):
      for log in status.logs:
          print(log["message"])
  ```

  ```javascript JavaScript theme={null}
  const status = await fal.queue.status("fal-ai/flux/schnell", {
    requestId: request_id,
    logs: true,
  });
  if (status.status === "IN_QUEUE") {
    console.log(`Position: ${status.queue_position}`);
  } else if (status.status === "IN_PROGRESS") {
    status.logs?.forEach(log => console.log(log.message));
  }
  ```

  ```bash cURL theme={null}
  curl "https://queue.fal.run/fal-ai/flux/schnell/requests/{request_id}/status?logs=1" \
    -H "Authorization: Key $FAL_KEY"
  ```
</CodeGroup>

The response shape depends on the current status:

**IN\_QUEUE** -- waiting for an available runner:

```json theme={null}
{
  "status": "IN_QUEUE",
  "request_id": "764cabcf-...",
  "queue_position": 2,
  "response_url": "https://queue.fal.run/.../response"
}
```

**IN\_PROGRESS** -- a runner is processing the request:

```json theme={null}
{
  "status": "IN_PROGRESS",
  "request_id": "764cabcf-...",
  "response_url": "https://queue.fal.run/.../response",
  "logs": [
    {"message": "Loading model weights...", "timestamp": "2026-02-17T10:30:01.123Z"},
    {"message": "Generating image...", "timestamp": "2026-02-17T10:30:02.456Z"}
  ]
}
```

**COMPLETED** -- the result is ready to retrieve:

```json theme={null}
{
  "status": "COMPLETED",
  "request_id": "764cabcf-...",
  "response_url": "https://queue.fal.run/.../response",
  "logs": [
    {"message": "Done.", "timestamp": "2026-02-17T10:30:05.789Z"}
  ],
  "metrics": {"inference_time": 3.42}
}
```

| Field                    | Description                                                                                                                                                                |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `queue_position`         | Number of requests ahead of yours (only when `IN_QUEUE`)                                                                                                                   |
| `logs`                   | Array of log messages from the runner (when logs are enabled)                                                                                                              |
| `metrics.inference_time` | Seconds the runner spent processing (only when `COMPLETED`)                                                                                                                |
| `error`                  | A human-readable error message, present only if the request failed (only when `COMPLETED`)                                                                                 |
| `error_type`             | A machine-readable error type string, present only if the request failed. See [Request Error Types](/documentation/model-apis/request-errors) for the full list of values. |

***

## Stream Status Updates

Instead of polling manually, you can stream status updates continuously until the request completes. In Python, `iter_events()` polls and yields each status. In JavaScript, `streamStatus()` opens an SSE connection.

<CodeGroup>
  ```python Python theme={null}
  for event in handler.iter_events(with_logs=True):
      if isinstance(event, fal_client.InProgress):
          for log in event.logs:
              print(log["message"])

  result = handler.get()
  ```

  ```python Python (async) theme={null}
  async for event in handler.iter_events(with_logs=True):
      if isinstance(event, fal_client.InProgress):
          for log in event.logs:
              print(log["message"])

  result = await handler.get()
  ```

  ```javascript JavaScript theme={null}
  const stream = await fal.queue.streamStatus("fal-ai/flux/schnell", {
    requestId: request_id,
    logs: true,
  });

  for await (const status of stream) {
    if (status.status === "IN_PROGRESS") {
      status.logs?.forEach(log => console.log(log.message));
    } else if (status.status === "COMPLETED") {
      console.log(`Done in ${status.metrics?.inference_time}s`);
    }
  }
  ```

  ```bash cURL theme={null}
  curl "https://queue.fal.run/fal-ai/flux/schnell/requests/{request_id}/status/stream?logs=1" \
    -H "Authorization: Key $FAL_KEY"
  ```
</CodeGroup>

The REST streaming endpoint returns `text/event-stream` with SSE events. Each event is a JSON status object in the same format as the polling endpoint. The connection stays open until the status reaches `COMPLETED`.

***

## Get the Result

Retrieve the final output once the request is complete. In Python, `get()` polls internally until `Completed` then fetches the response. In JavaScript, call `fal.queue.result()` after the status is `COMPLETED`.

<CodeGroup>
  ```python Python theme={null}
  result = handler.get()
  print(result["images"][0]["url"])
  ```

  ```python Python (async) theme={null}
  result = await handler.get()
  print(result["images"][0]["url"])
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.queue.result("fal-ai/flux/schnell", {
    requestId: request_id,
  });
  console.log(result.data.images[0].url);
  ```

  ```bash cURL theme={null}
  curl https://queue.fal.run/fal-ai/flux/schnell/requests/{request_id} \
    -H "Authorization: Key $FAL_KEY"
  ```
</CodeGroup>

The result structure is **model-specific**. For example, an image model returns:

```json theme={null}
{
  "images": [
    {
      "url": "https://v3.fal.media/files/rabbit/abc123.png",
      "width": 1024,
      "height": 1024,
      "content_type": "image/png"
    }
  ],
  "prompt": "a sunset over mountains",
  "seed": 42,
  "has_nsfw_concepts": [false]
}
```

Video generation models return a `video` object, and audio/speech models return an `audio_url` or `audio` object. Check the model's API page (e.g., [FLUX.1 schnell API](https://fal.ai/models/fal-ai/flux/schnell/api)) for the exact output schema.

<Note>
  All media URLs in responses (`https://v3.fal.media/...`) are publicly accessible and subject to your [media expiration settings](/documentation/model-apis/media-expiration). Download files you need to keep before they expire.
</Note>

***

## Cancel a Request

Cancel a request. What happens depends on the request's state:

* **Still in the queue (IN\_QUEUE):** The request is removed immediately and is never processed.
* **Already being processed (IN\_PROGRESS):** fal sends a cancellation signal to the runner. The request may still complete if the app does not handle cancellation. Whether the running code actually stops depends on whether the app has implemented a cancel endpoint.

If you are deploying your own serverless app and want in-progress requests to stop cleanly when cancelled, see [Handle Cancellations](/documentation/development/handle-cancellations) for how to implement a cancel endpoint.

<CodeGroup>
  ```python Python theme={null}
  handler.cancel()
  ```

  ```python Python (async) theme={null}
  await handler.cancel()
  ```

  ```javascript JavaScript theme={null}
  await fal.queue.cancel("fal-ai/flux/schnell", {
    requestId: request_id,
  });
  ```

  ```bash cURL theme={null}
  curl -X PUT https://queue.fal.run/fal-ai/flux/schnell/requests/{request_id}/cancel \
    -H "Authorization: Key $FAL_KEY"
  ```
</CodeGroup>

The response includes both an HTTP status code and a JSON body:

| HTTP Status       | JSON Body                              | Meaning                                                                           |
| ----------------- | -------------------------------------- | --------------------------------------------------------------------------------- |
| `202 Accepted`    | `{"status": "CANCELLATION_REQUESTED"}` | Cancel accepted. The request may still complete if it was already mid-processing. |
| `400 Bad Request` | `{"status": "ALREADY_COMPLETED"}`      | The request already finished before the cancel arrived.                           |
| `404 Not Found`   | `{"status": "NOT_FOUND"}`              | No request exists with that ID.                                                   |

When using the SDK, `handler.cancel()` succeeds silently on `202` and raises an exception on `400` or `404`.

***

## Webhooks

Instead of polling, configure fal to POST results directly to your server when a request completes.

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  handler = fal_client.submit("fal-ai/flux/schnell",
      arguments={"prompt": "a sunset over mountains"},
      webhook_url="https://your-server.com/webhook",
  )

  print(f"Request submitted: {handler.request_id}")
  ```

  ```python Python (async) theme={null}
  import fal_client

  handler = await fal_client.submit_async("fal-ai/flux/schnell",
      arguments={"prompt": "a sunset over mountains"},
      webhook_url="https://your-server.com/webhook",
  )

  print(f"Request submitted: {handler.request_id}")
  ```

  ```javascript JavaScript theme={null}
  const { request_id } = await fal.queue.submit("fal-ai/flux/schnell", {
    input: { prompt: "a sunset over mountains" },
    webhookUrl: "https://your-server.com/webhook",
  });
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/flux/schnell?fal_webhook=https://your-server.com/webhook" \
    -H "Authorization: Key $FAL_KEY" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset over mountains"}'
  ```
</CodeGroup>

When complete, fal sends a POST to your webhook URL:

```json theme={null}
{
  "request_id": "abc123",
  "gateway_request_id": "abc123",
  "status": "OK",
  "payload": {
    "images": [
      {"url": "https://fal.media/files/...", "width": 1024, "height": 1024}
    ]
  }
}
```

The webhook `status` is `"OK"` for successful responses (HTTP 200) or `"ERROR"` for failures -- this is different from the queue status values (`IN_QUEUE`, `IN_PROGRESS`, `COMPLETED`). Return 200 quickly to acknowledge the webhook. fal may retry failed deliveries, so use `request_id` for idempotency. See [Webhooks](/documentation/model-apis/inference/webhooks) for full details on payload format, retries, and signature verification.

***

## `submit()` Parameters

### `path`

Endpoint path appended to the model ID. Most models expose a single root endpoint, so you can leave this empty. Use it when a model or your own app defines additional endpoints at sub-paths.

<CodeGroup>
  ```python Python theme={null}
  handler = fal_client.submit("fal-ai/nano-banana-2", arguments={...}, path="/custom-endpoint")
  ```

  ```javascript JavaScript theme={null}
  const { request_id } = await fal.queue.submit("fal-ai/nano-banana-2/custom-endpoint", {
    input: {...},
  });
  ```
</CodeGroup>

In JavaScript, append the path directly to the endpoint string.

### `start_timeout`

Server-side deadline in seconds, sent as the `X-Fal-Request-Timeout` header. This sets an absolute wall-clock deadline, computed once when the request is submitted. The server checks this deadline before processing begins. If the deadline has passed, the server returns a 504 without processing the request.

If a runner picks up the request but **fails** (e.g., returns 503 or crashes), the request goes back to the queue for a retry. Because the deadline is a fixed timestamp, all elapsed time -- including time spent on the failed attempt -- counts against the same original deadline. If the deadline is reached before any runner successfully starts processing, the server returns `504 Gateway Timeout` with the header `X-Fal-Request-Timeout-Type: user` and no further retries occur.

<Note>
  This timeout does not limit how long inference takes. Once a runner starts processing, the deadline is not enforced and the request runs to completion. This is different from `request_timeout`, which limits each individual processing attempt and actively kills the runner if exceeded. The maximum inference time is controlled by the app's `request_timeout` setting (default 3600s), which is configured by the app developer, not the caller. If you need a total client-side deadline that includes processing time, use [`client_timeout`](#client_timeout-subscribe-only) on `subscribe()`.
</Note>

For a full comparison of timeout mechanisms, see [Timeouts and Retries](/documentation/serverless/reliability/retries#timeouts-and-retries).

<CodeGroup>
  ```python Python theme={null}
  handler = fal_client.submit("fal-ai/nano-banana-2", arguments={...}, start_timeout=30)
  ```

  ```javascript JavaScript theme={null}
  const { request_id } = await fal.queue.submit("fal-ai/nano-banana-2", {
    input: {...},
    startTimeout: 30,
  });
  ```
</CodeGroup>

### `hint`

Routing hint sent as the `X-Fal-Runner-Hint` header. When you pass a hint string, fal tries to route the request to the same runner that handled a previous request with the same hint. This is useful for session affinity -- for example, keeping requests pinned to a runner that already has a specific model or adapter loaded in memory. For serverless apps that serve multiple models, your app can implement `provide_hints()` on the server side to tell fal what each runner is specialized for. See [Optimize Routing Behavior](/documentation/serverless/optimizations/optimize-routing-behavior) for the full pattern.

<CodeGroup>
  ```python Python theme={null}
  handler = fal_client.submit("fal-ai/nano-banana-2", arguments={...}, hint="user-session-abc")
  ```

  ```javascript JavaScript theme={null}
  const { request_id } = await fal.queue.submit("fal-ai/nano-banana-2", {
    input: {...},
    hint: "user-session-abc",
  });
  ```
</CodeGroup>

### `priority`

Queue priority for the request, sent as the `X-Fal-Queue-Priority` header. Accepts `"normal"` (default) or `"low"`.

Priority applies to the **per-endpoint queue** -- every request to the same endpoint shares one queue, regardless of who sent it. A low-priority request sits behind all normal-priority requests in that queue and is only processed once no normal requests are waiting. This means setting `priority="low"` on a shared model API (like `fal-ai/flux/dev`) deprioritizes your request relative to **all other users** of that model.

Low priority is most useful for your own deployed serverless apps where you control all traffic. For example, you might submit user-facing requests at normal priority and background batch jobs at low priority so interactive requests are always served first.

<CodeGroup>
  ```python Python theme={null}
  handler = fal_client.submit("your-username/your-app", arguments={...}, priority="low")
  ```

  ```javascript JavaScript theme={null}
  const { request_id } = await fal.queue.submit("your-username/your-app", {
    input: {...},
    priority: "low",
  });
  ```
</CodeGroup>

### `webhook_url`

URL where fal sends a POST request with the result when processing completes. When set, you don't need to poll for status -- the result arrives at your server automatically. The webhook payload includes the `request_id`, `status`, and the full model output. See [Webhooks](/documentation/model-apis/inference/webhooks) for payload format, retries, and signature verification.

<CodeGroup>
  ```python Python theme={null}
  handler = fal_client.submit(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      webhook_url="https://your-server.com/api/fal/webhook",
  )
  ```

  ```javascript JavaScript theme={null}
  const { request_id } = await fal.queue.submit("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    webhookUrl: "https://your-server.com/api/fal/webhook",
  });
  ```
</CodeGroup>

### `headers`

Additional HTTP headers passed with the request. Use this to set [platform-level headers](/documentation/model-apis/common-parameters) like `X-Fal-Store-IO` (disable payload storage), `X-Fal-No-Retry` (disable retries), or `X-Fal-Object-Lifecycle-Preference` (control media expiration).

<CodeGroup>
  ```python Python theme={null}
  handler = fal_client.submit("fal-ai/nano-banana-2", arguments={...}, headers={"X-Fal-No-Retry": "1"})
  ```

  ```javascript JavaScript theme={null}
  const { request_id } = await fal.queue.submit("fal-ai/nano-banana-2", {
    input: {...},
    headers: { "X-Fal-No-Retry": "1" },
  });
  ```
</CodeGroup>

***

## `subscribe()` Parameters

`subscribe()` accepts all of the `submit()` parameters above (`path`, `start_timeout`, `hint`, `priority`, `headers`), plus the following. In JavaScript, `fal.subscribe()` supports `priority`, `headers`, and `webhookUrl` as named options; for `hint`, use [`fal.queue.submit()`](#hint) directly.

### `client_timeout` / `timeout`

Client-side deadline that limits the total time the client waits for the result, including queue wait and processing. When exceeded, the client stops polling and raises an error. The request may still be processing on the server. In Python the parameter is called `client_timeout` and accepts seconds. In JavaScript the parameter is called `timeout` and accepts milliseconds.

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe(
      "fal-ai/flux/dev",
      arguments={"prompt": "a cat"},
      client_timeout=60,  # client gives up after 60 seconds
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/flux/dev", {
    input: { prompt: "a cat" },
    timeout: 60000,  // client gives up after 60000 milliseconds
  });
  ```
</CodeGroup>

**Interaction with `start_timeout` (Python):** If you set `client_timeout` without setting `start_timeout`, the SDK automatically sets `start_timeout = client_timeout` so the server also respects your deadline. If you explicitly set `start_timeout` to a value larger than `client_timeout`, the SDK emits a warning because the server-side timeout would never be reached before the client gives up.

| Timeout                                    | Enforced by   | Scope                                                                       | Affects server                     | Use when                                                   |
| ------------------------------------------ | ------------- | --------------------------------------------------------------------------- | ---------------------------------- | ---------------------------------------------------------- |
| `start_timeout` / `X-Fal-Request-Timeout`  | Server        | Absolute deadline across entire lifecycle (enforced before processing only) | Yes (returns 504, stops retries)   | You want the server to cancel the request before it starts |
| `client_timeout` (Python) / `timeout` (JS) | Client        | Total wall-clock time including processing                                  | No (request may continue)          | You want a local deadline without affecting the server     |
| `request_timeout`                          | App developer | Per-attempt processing limit (resets on each retry)                         | Yes (kills runner, triggers retry) | Set by the app to cap individual inference time            |

***

## Disabling Retries

By default, fal [automatically retries](/documentation/serverless/reliability/retries) queue requests that fail due to server errors, timeouts, or rate limits. If you need to disable retries for a specific request, pass the `X-Fal-No-Retry` header when submitting:

```bash theme={null}
curl -X POST "https://queue.fal.run/fal-ai/flux/dev" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Fal-No-Retry: 1" \
  -d '{"prompt": "a cat"}'
```

When this header is set to `1`, `true`, or `yes`, fal will not retry the request even if it fails due to a retryable error.


# https://fal.ai/docs/documentation/model-apis/inference/real-time.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Real-Time Inference

> WebSocket-based inference for ultra-low latency applications

Real-time inference uses WebSockets for persistent connections, enabling sub-100ms image generation. This is ideal for interactive applications like real-time creativity tools and camera-based inputs.

Unlike [queue-based inference](/documentation/model-apis/inference), real-time connections bypass the queue entirely and route inputs directly to a runner. This eliminates queue wait time, and because the WebSocket maintains a persistent connection, the runner stays warm for all subsequent messages after the initial connection. The first connection may still incur a cold start if no runner is already available. Only models with an explicit real-time endpoint are supported.

<Warning>
  Only models that explicitly support real-time inference can be used with the realtime client. Standard queue-based models do not have a realtime endpoint.
</Warning>

## Supported Models

<CardGroup cols={2}>
  <Card title="fast-lcm-diffusion" href="https://fal.ai/models/fal-ai/fast-lcm-diffusion">
    SDXL with Latent Consistency Models
  </Card>

  <Card title="fast-turbo-diffusion" href="https://fal.ai/models/fal-ai/fast-turbo-diffusion">
    Optimized SDXL Turbo
  </Card>
</CardGroup>

***

## Quick Start

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const connection = fal.realtime.connect("fal-ai/fast-lcm-diffusion", {
    onResult: (result) => {
      console.log(result);
    },
    onError: (error) => {
      console.error(error);
    },
  });

  connection.send({
    prompt: "a sunset over mountains",
    sync_mode: true,
    image_url: "data:image/png;base64,..."
  });
  ```

  ```python Python theme={null}
  import fal_client

  with fal_client.realtime("fal-ai/fast-lcm-diffusion") as connection:
      connection.send({
          "prompt": "a sunset over mountains",
          "sync_mode": True,
          "image_url": "data:image/png;base64,..."
      })
      result = connection.recv()
      print(result)
  ```

  ```python Python (async) theme={null}
  import asyncio
  import fal_client

  async def realtime():
      async with fal_client.realtime_async("fal-ai/fast-lcm-diffusion") as connection:
          await connection.send({
              "prompt": "a sunset over mountains",
              "sync_mode": True,
              "image_url": "data:image/png;base64,..."
          })
          result = await connection.recv()
          print(result)

  asyncio.run(realtime())
  ```
</CodeGroup>

***

## Performance Tips

For the fastest inference:

* Use **512x512** input dimensions (fastest)
* Provide images as base64 encoded data URLs
* Set `sync_mode: true` to receive base64 encoded responses
* 768x768 and 1024x1024 also work well, but 512x512 is optimal

***

## Keeping API Keys Secure

WebSocket connections from browsers cannot safely embed API keys. There are two approaches for client-side authentication: a proxy URL or a token provider.

### Proxy URL

The simplest approach. Point the client at a server-side proxy that adds your API key:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  fal.config({
    proxyUrl: "/api/fal/proxy",
  });

  const connection = fal.realtime.connect("fal-ai/fast-lcm-diffusion", {
    connectionKey: "realtime-demo",
    throttleInterval: 128,
    onResult(result) {
      // handle result
    },
  });
  ```

  ```swift Swift theme={null}
  import FalClient

  let fal = FalClient.withProxy("http://localhost:3333/api/fal/proxy")

  let connection = try fal.realtime.connect(
      to: "fal-ai/fast-lcm-diffusion",
      connectionKey: "realtime-demo",
      throttleInterval: .milliseconds(128)
  ) { result in
      // handle result
  }
  ```
</CodeGroup>

<Card title="Proxy Setup" icon="shield" href="/documentation/model-apis/inference/proxy-setup">
  Learn how to set up a server-side proxy
</Card>

### Token Provider

For more control, use a `tokenProvider` function that fetches short-lived JWT tokens from your backend. This is useful when you need per-user authentication or want to restrict which apps a token can access.

<Warning>
  **Protect your token endpoint with authentication.** The endpoint that generates fal tokens should verify that the request comes from an authenticated user in your application. Without proper authentication, anyone could use your endpoint to generate tokens and consume your fal credits.
</Warning>

**Client-side example:**

```typescript theme={null}
import { fal, type TokenProvider } from "@fal-ai/client";

// app includes the full endpoint path, e.g. "fal-ai/fast-lcm-diffusion/realtime"
const myTokenProvider: TokenProvider = async (app) => {
  const response = await fetch(`/api/fal/token?app=${encodeURIComponent(app)}`);
  const { token } = await response.json();
  return token;
};

const connection = fal.realtime.connect("fal-ai/fast-lcm-diffusion", {
  tokenProvider: myTokenProvider,
  tokenExpirationSeconds: 120, // match the duration from your backend
  onResult: (result) => {
    console.log(result);
  },
});

connection.send({
  prompt: "a cat",
  sync_mode: true,
});
```

Pass `tokenExpirationSeconds` to enable automatic token refresh before expiry. Set it to the same value as the `duration` in your backend's token request. If omitted, auto-refresh is disabled and your `tokenProvider` is called once at connection time.

**Next.js API Route example (`app/api/fal/token/route.ts`):**

```typescript theme={null}
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
  // IMPORTANT: Add your own authentication logic here
  // const session = await getServerSession();
  // if (!session) {
  //   return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  // }

  const { searchParams } = new URL(request.url);
  const app = searchParams.get("app");

  if (!app) {
    return NextResponse.json({ error: "Missing app parameter" }, { status: 400 });
  }

  const response = await fetch("https://rest.fal.ai/tokens/realtime", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Key ${process.env.FAL_KEY}`,
    },
    // app includes the full path (e.g. "fal-ai/fast-lcm-diffusion/realtime")
    body: JSON.stringify({
      allowed_apps: [app],
      duration: 120,
    }),
  });

  const data = await response.json();
  return NextResponse.json({ token: data.token });
}
```

<Note>
  The `tokenProvider` also works for streaming with `connectionMode: "client"`:

  ```typescript theme={null}
  const stream = await fal.stream("fal-ai/flux/dev", {
    connectionMode: "client",
    tokenProvider: myTokenProvider,
    input: { prompt: "a cat" },
  });
  ```
</Note>

***

## Differences from Queue-Based Inference

Real-time WebSocket connections bypass the queue and connect directly to a runner. Several request parameters that work with queue-based inference do not apply:

| Parameter         | Behavior with Real-Time                                        |
| ----------------- | -------------------------------------------------------------- |
| `start_timeout`   | No effect. There is no queue wait                              |
| `priority`        | No effect. No queue ordering                                   |
| `webhook_url`     | Not supported. Results stream back over the WebSocket          |
| Automatic retries | Not available. Failed messages return errors on the connection |
| `X-Fal-No-Retry`  | No effect. No retry mechanism to disable                       |

## Custom WebSocket Path

By default, the realtime client connects to the `/realtime` path on the app (e.g., `wss://fal.run/fal-ai/my-app/realtime`). If your app exposes a realtime endpoint at a different path, use the `path` option:

```typescript theme={null}
const connection = fal.realtime.connect("fal-ai/my-app", {
  path: "/my-custom-ws",
  onResult: (result) => console.log(result),
});
```

In Python, pass the `path` parameter to `realtime()`:

```python theme={null}
connection = fal_client.realtime("fal-ai/my-app", path="/my-custom-ws", on_result=handle_result)
```

***

## Realtime vs Streaming

Both realtime and [streaming](/documentation/model-apis/inference/streaming) give you faster feedback than polling, but they serve different use cases.

| Feature        | Realtime (WebSocket)                    | Streaming (SSE)                   |
| -------------- | --------------------------------------- | --------------------------------- |
| **Direction**  | Bidirectional (client and server)       | One-way (server to client)        |
| **Connection** | Persistent, reusable                    | New connection per request        |
| **Latency**    | Lower (connection reuse)                | Higher (new connection each time) |
| **Best for**   | Interactive apps, back-to-back requests | Progressive output, previews      |
| **Protocol**   | Binary msgpack (default, customizable)  | JSON over SSE                     |

Use realtime when clients send multiple requests in quick succession over a persistent connection, like interactive image editing or camera-based inputs. Use streaming when you want to show progressive output from a single request, like image generation previews or LLM tokens.

## Protocol Details

The realtime client uses [msgpack](https://msgpack.org/) for binary serialization by default across all SDKs, which is more efficient than JSON for transmitting image data. In Python, `realtime()` and `realtime_async()` provide a `RealtimeConnection` with `send()` and `recv()` methods. In JavaScript, `fal.realtime.connect()` uses callback-based `onResult` and `onError` handlers.

In the JavaScript client, you can customize the message encoding by passing `encodeMessage` and `decodeMessage` options. For example, to use JSON instead of msgpack:

```typescript theme={null}
const connection = fal.realtime.connect("fal-ai/my-app", {
  encodeMessage: (input) => JSON.stringify(input),
  decodeMessage: (data) => JSON.parse(data),
  onResult: (result) => console.log(result),
});
```

## Video Tutorial

Build a Real-Time AI Image App with WebSockets, Next.js, and fal.ai:

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/freyCo3pcz4?si=OFfGsi0xwJVe__Yt&autoplay=1'><img src='/docs/images/video-thumbs/realtime.jpg' alt='YouTube video player'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>


# https://fal.ai/docs/documentation/model-apis/inference/reliability.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Reliability

> How fal ensures high reliability for your API requests through queueing, automatic retries, and model fallbacks.

fal is designed for production workloads and includes several built-in mechanisms to ensure your requests succeed.

The platform applies three layers of protection automatically: a [queue](/documentation/model-apis/inference) that absorbs traffic spikes, retries that recover from transient failures, and model fallbacks that reroute around unhealthy endpoints. All three are enabled by default and require no configuration.

## Queue-Based Processing

The [queue system](/model-apis/model-endpoints/queue) handles traffic surges gracefully and provides request tracking. When you submit a request, it enters a managed queue that ensures reliable processing even during peak demand.

## Automatic Retries

When using the [queue](/model-apis/model-endpoints/queue), fal automatically retries requests that fail due to:

* **Server errors (503)**: The model endpoint was temporarily unavailable
* **Timeouts (504)**: The request took too long due to transient issues
* **Connection errors**: Network issues between fal infrastructure
* **Rate limits (429)**: Request waits and retries automatically when you temporarily exceed your [concurrent request limit](/model-apis/faq#is-there-a-rate-limit)

Requests are retried up to 10 times with intelligent backoff.

<Tip>
  **Limit retry duration:** Use [start timeout](/model-apis/model-endpoints/queue#start-timeout) to cap the total time a request can spend waiting (including retries). Once the timeout is reached, no further retries occur.
</Tip>

<Tip>
  **No charge for server errors**: Failed requests that return 5xx status codes are not billed.
</Tip>

<Note>
  Automatic retries only apply to queue-based requests. Direct synchronous requests return errors immediately without retry.
</Note>

For per-request control over retries and timeouts, see the Queue page -- including [disabling retries](/model-apis/model-endpoints/queue#disabling-retries) with the `X-Fal-No-Retry` header, setting a [start timeout](/model-apis/model-endpoints/queue#start-timeout) with `X-Fal-Request-Timeout`, and using [client timeout](/model-apis/model-endpoints/queue#client-timeout) to set a client-side deadline.

| Timeout                                         | Enforced by | Effect on retries                                 |
| ----------------------------------------------- | ----------- | ------------------------------------------------- |
| `start_timeout` / `X-Fal-Request-Timeout`       | Server      | Stops retries when total elapsed time is exceeded |
| `client_timeout` (Python SDK, `subscribe` only) | Client      | Client stops polling; server and retries continue |

## Model Fallbacks

For supported models, fal might automatically reroute requests to equivalent alternative endpoints if the primary endpoint is temporarily unavailable. This only occurs after fal retries the request up to five times; if those retries fail, the request is routed to a fallback endpoint. This mechanism improves overall reliability and reduces the likelihood of failed requests.

Fallbacks are enabled by default for all accounts. If you need to disable fallbacks for your account, please let your account team know. If you want to disable it per request, you can pass the `x-app-fal-disable-fallback` header. For any questions, contact our sales team.


# https://fal.ai/docs/documentation/model-apis/inference/streaming.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming Inference

> Get progressive output as it's generated

Streaming allows you to receive output progressively as the model generates it. Instead of waiting for the full result, you process each chunk as it arrives. This is useful for LLMs that produce tokens incrementally, models that generate intermediate previews, or any situation where you want to show progress to the user.

Under the hood, `stream()` sends a direct HTTP request to `fal.run` using [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) (SSE). The SDK wraps the SSE connection into an iterator, so each event arrives as a parsed object. Streaming does not use the [queue](/documentation/model-apis/inference/queue), so there are no automatic retries.

<Note>
  Streaming is only supported by models that have a `/stream` endpoint. Check the model's API page to confirm support before using `stream()`.
</Note>

## Using `stream()`

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  for event in fal_client.stream("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset over mountains"
  }):
      print(event)
  ```

  ```python Python (async) theme={null}
  import asyncio
  import fal_client

  async def main():
      async for event in fal_client.stream_async("fal-ai/flux/schnell", arguments={
          "prompt": "a sunset over mountains"
      }):
          print(event)

  asyncio.run(main())
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const stream = await fal.stream("fal-ai/flux/schnell", {
    input: { prompt: "a sunset over mountains" }
  });

  for await (const event of stream) {
    console.log(event);
  }
  ```

  ```bash cURL theme={null}
  curl -N -X POST "https://fal.run/fal-ai/flux/schnell/stream" \
    -H "Authorization: Key $FAL_KEY" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset over mountains"}'
  ```
</CodeGroup>

Each event is a dictionary/object whose shape depends on the model. The REST API returns SSE-formatted events (each line prefixed with `data: `). The SDKs parse these automatically into objects. A model might stream progress updates followed by the final result:

```json theme={null}
{"progress": 0.25, "message": "Generating..."}
{"progress": 0.50, "message": "Generating..."}
{"progress": 0.75, "message": "Generating..."}
{"images": [{"url": "https://v3.fal.media/files/..."}], "seed": 42}
```

## `stream()` Parameters

### `path`

Endpoint path appended to the model ID. Defaults to `"/stream"` for streaming endpoints. See [`path` reference](/documentation/model-apis/inference/queue#path).

### `timeout`

Client-side HTTP timeout in seconds -- how long the client waits for the SSE connection. See [`timeout` reference](/documentation/model-apis/inference/synchronous#timeout).

<Note>
  `stream()` does not support `hint`, `priority`, `start_timeout`, `client_timeout`, or `headers` because it bypasses the queue and sends a direct HTTP request. There are no retries. If you need queue-backed reliability, use [`submit()`](/documentation/model-apis/inference/queue) and poll for status with `with_logs=True` to track progress.
</Note>

## When to Use Streaming

Streaming is best for LLMs, chat models, showing real-time progress to users, and reducing perceived latency in interactive applications. It is not needed for models that return a single result with no intermediate output, or backend-to-backend integrations where you just need the final response. In those cases, [`run()`](/documentation/model-apis/inference/synchronous) or [`subscribe()`](/documentation/model-apis/inference/synchronous) is simpler.


# https://fal.ai/docs/documentation/model-apis/inference/synchronous.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Synchronous Inference

> A convenience wrapper for simple blocking calls

There are two ways to make a simple blocking call to a model on fal. `run` sends a direct HTTP request to `fal.run` and returns the result immediately, with no queue involved. `subscribe` uses the [queue](/documentation/model-apis/inference/queue) under the hood but handles polling automatically, so it feels just as simple while giving you automatic retries and reliability.

Both are good starting points for scripts, prototyping, and any situation where you just want the output without managing the request lifecycle yourself. Use `run` when you want the fastest possible path with no overhead, and `subscribe` when you want queue-backed reliability. For production workloads that need parallel processing or [webhooks](/documentation/model-apis/inference/webhooks), use [async inference](/documentation/model-apis/inference/queue) instead.

## Using `run` (Direct)

`run` sends a direct HTTP request to `fal.run`. There is no queue and no status polling. The response comes back in the same HTTP connection. The SDK retries on transient HTTP errors (like 502/503/504), but there are no server-side queue retries.

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  result = fal_client.run("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset over mountains"
  })

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

  ```python Python (async) theme={null}
  import asyncio
  import fal_client

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

  asyncio.run(main())
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.run("fal-ai/flux/schnell", {
    input: { prompt: "a sunset over mountains" }
  });

  console.log(result.data.images[0].url);
  ```
</CodeGroup>

## Using `subscribe` (Queue-backed)

`subscribe` submits to the queue and polls until the result is ready. You get automatic retries, timeout handling, and scaling, with the same simple blocking interface as `run`.

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset over mountains"
  })

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

  ```python Python (async) theme={null}
  import asyncio
  import fal_client

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

  asyncio.run(main())
  ```

  ```javascript JavaScript theme={null}
  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);
  ```
</CodeGroup>

## With Progress Updates

Track progress while waiting for results:

<CodeGroup>
  ```python Python theme={null}
  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 sunset over mountains"},
      with_logs=True,
      on_queue_update=on_queue_update
  )
  ```

  ```python Python (async) theme={null}
  import asyncio
  import fal_client

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

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

  asyncio.run(main())
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/flux/schnell", {
    input: { prompt: "a sunset over mountains" },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs?.forEach(log => console.log(log.message));
      }
    }
  });
  ```
</CodeGroup>

## `run()` Parameters

<Note>
  In JavaScript, `fal.run()` does not currently support `timeout`, `hint`, or `headers`. It does support `startTimeout`. To use `hint`, `headers`, or `priority` from JavaScript, use [`fal.queue.submit()`](/documentation/model-apis/inference/queue#submit-parameters) or [`fal.subscribe()`](#subscribe-parameters).
</Note>

### `path`

Endpoint path appended to the model ID. Leave empty for the default root endpoint. See [`path` reference](/documentation/model-apis/inference/queue#path).

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.run("fal-ai/nano-banana-2", arguments={...}, path="/custom-endpoint")
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.run("fal-ai/nano-banana-2/custom-endpoint", {
    input: {...},
  });
  ```
</CodeGroup>

In JavaScript, append the path directly to the endpoint string.

### `timeout`

Client-side HTTP timeout in seconds (Python only). This is a standard HTTP connection timeout -- how long the client library waits for the server to send back a complete response. If the connection is idle for longer than this, the client raises a timeout error. It does not affect the server.

```python theme={null}
result = fal_client.run("fal-ai/nano-banana-2", arguments={...}, timeout=120)
```

### `start_timeout`

Server-side deadline covering total elapsed time until a runner successfully starts processing. Returns 504 if exceeded. See [`start_timeout` reference](/documentation/model-apis/inference/queue#start-timeout) for full details on how the clock behaves across retries.

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.run("fal-ai/nano-banana-2", arguments={...}, start_timeout=30)
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.run("fal-ai/nano-banana-2", {
    input: {...},
    startTimeout: 30,
  });
  ```
</CodeGroup>

### `hint`

Routing hint for session affinity -- routes requests to the same runner. See [`hint` reference](/documentation/model-apis/inference/queue#hint).

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.run("fal-ai/nano-banana-2", arguments={...}, hint="user-session-abc")
  ```

  ```javascript JavaScript theme={null}
  // fal.run() does not support hint -- use fal.queue.submit() instead
  const { request_id } = await fal.queue.submit("fal-ai/nano-banana-2", {
    input: {...},
    hint: "user-session-abc",
  });
  ```
</CodeGroup>

### `headers`

Additional HTTP headers for [platform-level controls](/documentation/model-apis/common-parameters) like disabling retries or payload storage. See [`headers` reference](/documentation/model-apis/inference/queue#headers).

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.run("fal-ai/nano-banana-2", arguments={...}, headers={"X-Fal-No-Retry": "1"})
  ```

  ```javascript JavaScript theme={null}
  // fal.run() does not support headers -- use fal.subscribe() instead
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: {...},
    headers: { "X-Fal-No-Retry": "1" },
  });
  ```
</CodeGroup>

***

## `subscribe()` Parameters

`subscribe()` accepts all the parameters above except `timeout`, plus the queue-specific options below. For shared parameters (`path`, `start_timeout`, `hint`, `headers`, `priority`), see the [`submit()` reference](/documentation/model-apis/inference/queue#submit-parameters). In JavaScript, `fal.subscribe()` supports `priority`, `headers`, and `webhookUrl` as named options; for `hint`, use [`fal.queue.submit()`](/documentation/model-apis/inference/queue#hint) directly.

### `client_timeout` / `timeout`

Client-side total deadline that limits the total time `subscribe()` blocks, including queue wait and processing. When exceeded, the client stops polling and raises an error. The request may still be processing on the server after the client gives up. In Python the parameter is called `client_timeout` and accepts seconds. In JavaScript the parameter is called `timeout` and accepts milliseconds.

If you set `client_timeout` without setting `start_timeout`, the Python SDK automatically sets `start_timeout = client_timeout` so the server also respects your deadline. If you set `start_timeout` larger than `client_timeout`, the SDK emits a warning.

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      client_timeout=60,
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    timeout: 60000,  // milliseconds
  });
  ```
</CodeGroup>

For a comparison of all timeout mechanisms, see [Timeouts and Retries](/documentation/serverless/reliability/retries#timeouts-and-retries).

### `with_logs` / `logs`

When enabled, status updates include runner logs (print statements from your model's code). Without this, the `logs` field in progress updates is empty. Useful for debugging or showing generation progress to users. The parameter is named `with_logs` in Python and `logs` in JavaScript.

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      with_logs=True,
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    logs: true,
  });
  ```
</CodeGroup>

### `on_enqueue`

A callback function that fires once, immediately after the request enters the queue. It receives the `request_id` as its argument. Use this to store the request ID for later reference -- for example, to display it in a UI or save it to a database so you can retrieve the result later even if the client disconnects.

<CodeGroup>
  ```python Python theme={null}
  def save_request_id(request_id):
      print(f"Enqueued: {request_id}")

  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      on_enqueue=save_request_id,
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    onEnqueue: (requestId) => {
      console.log(`Enqueued: ${requestId}`);
    },
  });
  ```
</CodeGroup>

### `on_queue_update` / `onQueueUpdate`

A callback function that fires each time the client polls for status. It receives a status object with a `status` field indicating the current state.

In Python, the status is one of three types: `Queued` (has `position`), `InProgress` (has `logs`), or `Completed` (has `logs` and `metrics`). In JavaScript, check the `status` string field: `"IN_QUEUE"`, `"IN_PROGRESS"`, or `"COMPLETED"`.

<CodeGroup>
  ```python Python theme={null}
  def on_update(update):
      if isinstance(update, fal_client.Queued):
          print(f"Queue position: {update.position}")
      elif isinstance(update, fal_client.InProgress):
          for log in update.logs:
              print(log["message"])

  result = fal_client.subscribe(
      "fal-ai/nano-banana-2",
      arguments={"prompt": "a sunset"},
      with_logs=True,
      on_queue_update=on_update,
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset" },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_QUEUE") {
        console.log(`Position: ${update.queue_position}`);
      } else if (update.status === "IN_PROGRESS") {
        update.logs?.forEach(log => console.log(log.message));
      }
    },
  });
  ```
</CodeGroup>

## When to Use

Synchronous methods are best for simple scripts, prototyping, and any situation where you just want the result without managing the request lifecycle. Use `run` when you want the fastest path with no overhead. Use `subscribe` when you want queue-backed reliability with automatic retries.

For production workloads that need parallel request processing, webhooks, or full visibility into queue status, use [async inference](/documentation/model-apis/inference/queue) instead.

## Error Responses

When a request fails due to infrastructure issues (timeouts, runner errors, etc.), the response includes a JSON body with `detail` and `error_type` fields, along with an `X-Fal-Error-Type` header. For the full list of error types and their meanings, see [Request Error Types](/documentation/model-apis/request-errors).

For model-level validation errors (invalid inputs, content policy violations, etc.), see [Model Errors](/documentation/model-apis/errors).


# https://fal.ai/docs/documentation/model-apis/inference/webhooks.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Webhooks work in tandem with the queue system explained above, it is another way to interact with our queue. By providing us a webhook endpoint you get notified when the request is done as opposed to polling it.

Webhooks let you receive a notification at a URL you control when an asynchronous request completes, instead of polling the queue for results. This is especially useful for long-running tasks like model training or video generation where you don't want to keep a connection open. You can manage and monitor your webhook endpoints from the [Webhooks dashboard](https://fal.ai/dashboard/webhooks).

Setting up a webhook is straightforward. Pass a `webhook_url` when submitting a request to the [queue](/documentation/model-apis/inference/queue), and fal will POST the result to that URL when processing completes.

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  handler = fal_client.submit("fal-ai/flux/dev",
      arguments={"prompt": "Photo of a cute dog"},
      webhook_url="https://url.to.your.app/api/fal/webhook",
  )

  print(f"Request submitted: {handler.request_id}")
  ```

  ```python Python (async) theme={null}
  import fal_client

  handler = await fal_client.submit_async("fal-ai/flux/dev",
      arguments={"prompt": "Photo of a cute dog"},
      webhook_url="https://url.to.your.app/api/fal/webhook",
  )

  print(f"Request submitted: {handler.request_id}")
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const { request_id } = await fal.queue.submit("fal-ai/flux/dev", {
    input: { prompt: "Photo of a cute dog" },
    webhookUrl: "https://url.to.your.app/api/fal/webhook",
  });

  console.log(`Request submitted: ${request_id}`);
  ```

  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://queue.fal.run/fal-ai/flux/dev?fal_webhook=https://url.to.your.app/api/fal/webhook' \
    --header "Authorization: Key $FAL_KEY" \
    --header 'Content-Type: application/json' \
    --data '{
    "prompt": "Photo of a cute dog"
  }'
  ```
</CodeGroup>

The request will be queued and you will get a response with the `request_id` and `gateway_request_id`:

```json theme={null}
{
  "request_id": "024ca5b1-45d3-4afd-883e-ad3abe2a1c4d",
  "gateway_request_id": "024ca5b1-45d3-4afd-883e-ad3abe2a1c4d"
}
```

These two will be mostly the same, but if the request failed and was retried, `gateway_request_id` will have the value of the last tried request, while
`request_id` will be the value used in the queue API.

Once the request is done processing in the queue, a `POST` request is made to the webhook URL, passing the request info and the resulting `payload`. The `status` indicates whether the request was successful or not.

<Note>
  **When to use it?**

  Webhooks are particularly useful for requests that can take a while to process and/or the result is not needed immediately. For example, if you are training a model, which is a process than can take several minutes or even hours, webhooks could be the perfect tool for the job.
</Note>

### Successful result

The following is an example of a successful request:

```json highlight={4} theme={null}
{
  "request_id": "123e4567-e89b-12d3-a456-426614174000",
  "gateway_request_id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "OK",
  "payload": {
    "images": [
      {
        "url": "https://url.to/image.png",
        "content_type": "image/png",
        "file_name": "image.png",
        "file_size": 1824075,
        "width": 1024,
        "height": 1024
      }
    ],
    "seed": 196619188014358660
  }
}
```

### Response errors

When an error happens, the `status` will be `ERROR`. The `error` property will contain a message and the `payload` will provide the error details. For example, if you forget to pass the required `model_name` parameter, you will get the following response:

```json highlight={4,5} theme={null}
{
  "request_id": "123e4567-e89b-12d3-a456-426614174000",
  "gateway_request_id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "ERROR",
  "error": "Invalid status code: 422",
  "payload": {
    "detail": [
      {
        "loc": ["body", "prompt"],
        "msg": "field required",
        "type": "value_error.missing"
      }
    ]
  }
}
```

### Payload errors

For the webhook to include the payload, it must be valid JSON. So if there is an error serializing it, `payload` is set to `null` and a `payload_error` will include details about the error.

```json highlight={5,6} theme={null}
{
  "request_id": "123e4567-e89b-12d3-a456-426614174000",
  "gateway_request_id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "OK",
  "payload": null,
  "payload_error": "Response payload is not JSON serializable. Either return a JSON serializable object or use the queue endpoint to retrieve the response."
}
```

### Retry policy

Initial webhook deliveries have a 15-second timeout. If a delivery exceeds this time or fails to deliver the payload, it will retry 10 times in the span of 2 hours. Design your webhook handler to be idempotent and tolerate repeat deliveries for the same `request_id`.

### Webhook IP Ranges

If your infrastructure requires allowlisting IP addresses for incoming webhook requests, you can retrieve the current list of IP ranges used by fal.ai webhooks from the metadata endpoint:

```bash theme={null}
curl https://api.fal.ai/v1/meta
```

The response includes the `webhook_ip_ranges` field containing all IP addresses that may send webhook requests:

```json theme={null}
{
  "webhook_ip_ranges": [
    "34.123.59.101/32",
    "34.135.41.243/32",
    "35.239.83.87/32",
    "104.198.204.37/32",
    "34.56.20.205/32",
    "34.170.94.127/32",
    "35.224.184.236/32",
    "136.114.56.197/32",
    "34.29.37.237/32",
    "35.225.160.28/32",
    "34.56.205.145/32",
    "34.59.170.72/32",
    "34.10.147.45/32",
    "104.198.64.245/32",
    "34.9.1.255/32"
  ]
}
```

<Note>
  These IP ranges may change over time. We recommend fetching this list periodically to keep your allowlist up to date.
</Note>

### Verifying Your Webhook

To ensure the security and integrity of incoming webhook requests, you must verify that they originate from the expected source. This involves validating a cryptographic signature included in the request using a set of public keys. Below is a step-by-step guide to the verification process, followed by example implementations in Python and JavaScript.

#### Verification Process

<Steps>
  <Step title="Fetch the JSON Web Key Set (JWKS)">
    * Retrieve the public keys from the JWKS endpoint: `https://rest.fal.ai/.well-known/jwks.json`.
    * The JWKS contains a list of public keys in JSON format, each with an `x` field holding a base64url-encoded ED25519 public key.
    * **Note**: The JWKS is cacheable to reduce network requests. Ensure your implementation caches the keys and refreshes them after the cache duration expires. Do not cache longer than 24 hours since they can change.
  </Step>

  <Step title="Extract Required Headers">
    * Obtain the following headers from the incoming webhook request:
      * `X-Fal-Webhook-Request-Id`: The unique request ID.
      * `X-Fal-Webhook-User-Id`: Your user ID.
      * `X-Fal-Webhook-Timestamp`: The timestamp when the request was generated (in Unix epoch seconds).
      * `X-Fal-Webhook-Signature`: The cryptographic signature in hexadecimal format.
    * If any header is missing, the request is invalid.
  </Step>

  <Step title="Verify the Timestamp">
    * Compare the `X-Fal-Webhook-Timestamp` with the current Unix timestamp.
    * Allow a leeway of ±5 minutes (300 seconds) to account for clock skew and network delays.
    * If the timestamp differs by more than 300 seconds, reject the request to prevent replay attacks.
  </Step>

  <Step title="Construct the Message">
    * Compute the SHA-256 hash of the request body (raw bytes, not JSON-parsed).
    * Concatenate the following in strict order, separated by newline characters (`\n`):
      * `X-Fal-Webhook-Request-Id`
      * `X-Fal-Webhook-User-Id`
      * `X-Fal-Webhook-Timestamp`
      * Hex-encoded SHA-256 hash of the request body
    * Encode the resulting string as UTF-8 bytes to form the message to verify.
  </Step>

  <Step title="Verify the Signature">
    * Decode the `X-Fal-Webhook-Signature` from hexadecimal to bytes.
    * For each public key in the JWKS:
      * Decode the `x` field from base64url to bytes.
      * Use an ED25519 verification function (e.g., from PyNaCl in Python or libsodium in JavaScript) to verify the signature against the constructed message.
    * If any key successfully verifies the signature, the request is valid.
    * If no key verifies the signature, the request is invalid.
  </Step>
</Steps>

#### Example Implementations

Below are simplified functions to verify webhook signatures by passing the header values and request body directly. These examples handle the verification process as described above and include JWKS caching.

<Tabs>
  <Tab title="python" icon="python">
    **Install dependencies**:

    ```bash theme={null}
    pip install pynacl requests
    ```

    **Verification function**:

    ```python theme={null}
    import base64
    import hashlib
    import time
    from typing import Optional
    import requests
    from nacl.signing import VerifyKey
    from nacl.exceptions import BadSignatureError
    from nacl.encoding import HexEncoder

    JWKS_URL = "https://rest.fal.ai/.well-known/jwks.json"
    JWKS_CACHE_DURATION = 24 * 60 * 60  # 24 hours in seconds
    _jwks_cache = None
    _jwks_cache_time = 0

    def fetch_jwks() -> list:
        """Fetch and cache JWKS, refreshing after 24 hours."""
        global _jwks_cache, _jwks_cache_time
        current_time = time.time()
        if _jwks_cache is None or (current_time - _jwks_cache_time) > JWKS_CACHE_DURATION:
            response = requests.get(JWKS_URL, timeout=10)
            response.raise_for_status()
            _jwks_cache = response.json().get("keys", [])
            _jwks_cache_time = current_time
        return _jwks_cache

    def verify_webhook_signature(
        request_id: str,
        user_id: str,
        timestamp: str,
        signature_hex: str,
        body: bytes
    ) -> bool:
        """
        Verify a webhook signature using provided headers and body.

        Args:
            request_id: Value of X-Fal-Webhook-Request-Id header.
            user_id: Value of X-Fal-Webhook-User-Id header.
            timestamp: Value of X-Fal-Webhook-Timestamp header.
            signature_hex: Value of X-Fal-Webhook-Signature header (hex-encoded).
            body: Raw request body as bytes.

        Returns:
            bool: True if the signature is valid, False otherwise.
        """
        # Validate timestamp (within ±5 minutes)
        try:
            timestamp_int = int(timestamp)
            current_time = int(time.time())
            if abs(current_time - timestamp_int) > 300:
                print("Timestamp is too old or in the future.")
                return False
        except ValueError:
            print("Invalid timestamp format.")
            return False

        # Construct the message to verify
        try:
            message_parts = [
                request_id,
                user_id,
                timestamp,
                hashlib.sha256(body).hexdigest()
            ]
            if any(part is None for part in message_parts):
                print("Missing required header value.")
                return False
            message_to_verify = "\n".join(message_parts).encode("utf-8")
        except Exception as e:
            print(f"Error constructing message: {e}")
            return False

        # Decode signature
        try:
            signature_bytes = bytes.fromhex(signature_hex)
        except ValueError:
            print("Invalid signature format (not hexadecimal).")
            return False

        # Fetch public keys
        try:
            public_keys_info = fetch_jwks()
            if not public_keys_info:
                print("No public keys found in JWKS.")
                return False
        except Exception as e:
            print(f"Error fetching JWKS: {e}")
            return False

        # Verify signature with each public key
        for key_info in public_keys_info:
            try:
                public_key_b64url = key_info.get("x")
                if not isinstance(public_key_b64url, str):
                    continue
                public_key_bytes = base64.urlsafe_b64decode(public_key_b64url)
                verify_key = VerifyKey(public_key_bytes.hex(), encoder=HexEncoder)
                verify_key.verify(message_to_verify, signature_bytes)
                return True
            except (BadSignatureError, Exception) as e:
                print(f"Verification failed with a key: {e}")
                continue

        print("Signature verification failed with all keys.")
        return False
    ```
  </Tab>

  <Tab title="javascript" icon="js">
    **Install dependencies**:

    ```bash theme={null}
    npm install libsodium-wrappers node-fetch
    ```

    **Verification function**:

    ```javascript theme={null}
    const crypto = require('crypto');
    const sodium = require('libsodium-wrappers');
    const fetch = require('node-fetch');

    const JWKS_URL = 'https://rest.fal.ai/.well-known/jwks.json';
    const JWKS_CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
    let jwksCache = null;
    let jwksCacheTime = 0;

    async function fetchJwks() {
        const currentTime = Date.now();
        if (!jwksCache || (currentTime - jwksCacheTime) > JWKS_CACHE_DURATION) {
            const response = await fetch(JWKS_URL, { timeout: 10000 });
            if (!response.ok) throw new Error(`JWKS fetch failed: ${response.status}`);
            jwksCache = (await response.json()).keys || [];
            jwksCacheTime = currentTime;
        }
        return jwksCache;
    }

    async function verifyWebhookSignature(requestId, userId, timestamp, signatureHex, body) {
        /*
         * Verify a webhook signature using provided headers and body.
         *
         * @param {string} requestId - Value of x-fal-webhook-request-id header.
         * @param {string} userId - Value of x-fal-webhook-user-id header.
         * @param {string} timestamp - Value of x-fal-webhook-timestamp header.
         * @param {string} signatureHex - Value of x-fal-webhook-signature header (hex-encoded).
         * @param {Buffer} body - Raw request body as a Buffer.
         * @returns {Promise<boolean>} True if the signature is valid, false otherwise.
         */
        await sodium.ready;

        // Validate timestamp (within ±5 minutes)
        try {
            const timestampInt = parseInt(timestamp, 10);
            const currentTime = Math.floor(Date.now() / 1000);
            if (Math.abs(currentTime - timestampInt) > 300) {
                console.error('Timestamp is too old or in the future.');
                return false;
            }
        } catch (e) {
            console.error('Invalid timestamp format:', e);
            return false;
        }

        // Construct the message to verify
        try {
            const messageParts = [
                requestId,
                userId,
                timestamp,
                crypto.createHash('sha256').update(body).digest('hex')
            ];
            if (messageParts.some(part => part == null)) {
                console.error('Missing required header value.');
                return false;
            }
            const messageToVerify = messageParts.join('\n');
            const messageBytes = Buffer.from(messageToVerify, 'utf-8');

            // Decode signature
            let signatureBytes;
            try {
                signatureBytes = Buffer.from(signatureHex, 'hex');
            } catch (e) {
                console.error('Invalid signature format (not hexadecimal).');
                return false;
            }

            // Fetch public keys
            let publicKeysInfo;
            try {
                publicKeysInfo = await fetchJwks();
                if (!publicKeysInfo.length) {
                    console.error('No public keys found in JWKS.');
                    return false;
                }
            } catch (e) {
                console.error('Error fetching JWKS:', e);
                return false;
            }

            // Verify signature with each public key
            for (const keyInfo of publicKeysInfo) {
                try {
                    const publicKeyB64Url = keyInfo.x;
                    if (typeof publicKeyB64Url !== 'string') continue;
                    const publicKeyBytes = Buffer.from(publicKeyB64Url, 'base64url');
                    const isValid = sodium.crypto_sign_verify_detached(signatureBytes, messageBytes, publicKeyBytes);
                    if (isValid) return true;
                } catch (e) {
                    console.error('Verification failed with a key:', e);
                    continue;
                }
            }

            console.error('Signature verification failed with all keys.');
            return false;
        } catch (e) {
            console.error('Error constructing message:', e);
            return false;
        }
    }
    ```
  </Tab>
</Tabs>

#### Usage Notes

* **Caching the JWKS**: The JWKS can be cached for 24 hours to minimize network requests. The example implementations include basic in-memory caching.
* **Timestamp Validation**: The ±5-minute leeway ensures robustness against minor clock differences. Adjust this value if your use case requires stricter or looser validation.
* **Error Handling**: The examples include comprehensive error handling for missing headers, invalid signatures, and network issues. Log errors appropriately for debugging.
* **Framework Integration**: For frameworks like FastAPI (Python) or Express (JavaScript), ensure the raw request body is accessible. For Express, use `express.raw({ type: 'application/json' })` middleware before JSON parsing.


# https://fal.ai/docs/documentation/model-apis/media-expiration.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Retention & Storage

> How fal stores your request data and generated media, and how to control retention.

Every request to fal produces data that is stored on the platform: the JSON inputs and outputs of your request (viewable in [Dashboard > Recent History](https://fal.ai/dashboard)), and the actual media files generated by the model (images, videos, audio) hosted on the [fal CDN](/documentation/model-apis/fal-cdn). This page explains how long each type of data is retained and how to control that retention.

Understanding retention matters for compliance, cost, and privacy. Generated media files are stored on the CDN and served as public URLs. Request payloads (the JSON data) are stored separately and power the request history in your dashboard. Each has its own default retention and its own header for overriding it. If you are using [persistent storage](/documentation/development/use-persistent-storage) (`/data` volume), those files are retained indefinitely and managed manually.

## Generated Media (CDN Files)

When your app generates output files, they are uploaded to the [fal CDN](/documentation/model-apis/fal-cdn) and returned as URLs (e.g., `https://v3.fal.media/files/...`). Files you upload as inputs via `fal_client.upload_file` are also stored on the CDN. Both input uploads and output media are subject to the same retention controls.

### Per-Request Expiration

Control how long generated media is stored using the `X-Fal-Object-Lifecycle-Preference` header:

<CodeGroup>
  ```python Python theme={null}
  import fal_client
  import json

  result = fal_client.subscribe(
      "fal-ai/flux/schnell",
      arguments={"prompt": "a sunset"},
      headers={
          "X-Fal-Object-Lifecycle-Preference": json.dumps({
              "expiration_duration_seconds": 3600
          })
      }
  )
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/flux/schnell", {
    input: { prompt: "a sunset" },
    headers: {
      "X-Fal-Object-Lifecycle-Preference": JSON.stringify({
        expiration_duration_seconds: 3600
      })
    }
  });
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/flux/schnell" \
    -H "Authorization: Key $FAL_KEY" \
    -H "Content-Type: application/json" \
    -H 'X-Fal-Object-Lifecycle-Preference: {"expiration_duration_seconds": 3600}' \
    -d '{"prompt": "a sunset"}'
  ```
</CodeGroup>

Set `expiration_duration_seconds` to the number of seconds, or `null` for no expiration.

<Warning>
  Expired files are permanently deleted and cannot be recovered. Download files before they expire if you need them later.
</Warning>

***

## Request Payloads

Request inputs and outputs (the JSON data) are stored in the platform for **30 days** by default. This powers the request history in your dashboard.

### Preventing Payload Storage

To prevent fal from storing request payloads entirely, add the `X-Fal-Store-IO: 0` header:

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe(
      "fal-ai/flux/schnell",
      arguments={"prompt": "a sunset"},
      headers={"X-Fal-Store-IO": "0"}
  )
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/flux/schnell", {
    input: { prompt: "a sunset" },
    headers: { "X-Fal-Store-IO": "0" }
  });
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/flux/schnell" \
    -H "Authorization: Key $FAL_KEY" \
    -H "X-Fal-Store-IO: 0" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a sunset"}'
  ```
</CodeGroup>

<Note>
  This prevents storage of the JSON payloads only. CDN files generated during processing are still accessible (subject to the media expiration setting above).
</Note>

### Deleting Payloads

You can delete a request's payloads and the CDN files in its output via the [Platform API](/api-reference/platform-apis/index):

<Card title="Delete Request Payloads API" icon="trash" href="/platform-apis/v1/models/requests/payloads">
  Delete IO payloads and CDN output files for a specific request
</Card>

<Note>
  CDN files found in the **input** of a request are not deleted, as they may be used by other requests.
</Note>

***

## Summary

| Data Type                                                                             | Default Retention | Control                                                  |
| ------------------------------------------------------------------------------------- | ----------------- | -------------------------------------------------------- |
| **Generated media** (CDN files)                                                       | Configurable      | `X-Fal-Object-Lifecycle-Preference` header               |
| **Request payloads** (JSON)                                                           | 30 days           | `X-Fal-Store-IO: 0` header to opt out, or delete via API |
| **[Persistent storage](/documentation/development/use-persistent-storage)** (`/data`) | Forever           | Manual deletion via Dashboard or CLI                     |


# https://fal.ai/docs/documentation/model-apis/model-arguments.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Common Model Arguments

> Input parameters like seed, image_size, and safety checker that appear across many models on fal.

When you call a model on fal, everything you pass in the `arguments` dict (Python) or `input` object (JavaScript) goes into the request body as the model's input. Each model defines its own schema, and you can always find the exact schema on the model's API page (e.g., [Nano Banana 2 API](https://fal.ai/models/fal-ai/nano-banana-2/api)).

Many image generation models on fal share a set of common arguments that behave consistently across models. These are not platform-level controls (those are [platform headers](/documentation/model-apis/common-parameters) passed via the `headers` dict). They are model inputs that affect what the model generates and how. This page documents the most common ones for image generation so you don't have to look them up on every model's API page individually.

## seed

Random seed for reproducible outputs. The same seed with the same inputs produces the same result. Useful for debugging, A/B testing, or letting users "lock" a generation they like and iterate on the prompt.

|             |                 |
| ----------- | --------------- |
| **Type**    | Integer or null |
| **Default** | Random          |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a sunset",
      "seed": 42
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset", seed: 42 }
  });
  ```
</CodeGroup>

## num\_images

Number of images to generate per request. Higher values produce more results in a single call but increase processing time and cost proportionally.

|             |               |
| ----------- | ------------- |
| **Type**    | Integer       |
| **Default** | 1             |
| **Range**   | Typically 1-4 |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a sunset",
      "num_images": 4
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset", num_images: 4 }
  });
  ```
</CodeGroup>

## image\_size

Output image dimensions, used by models built with fal's [toolkit](/documentation/development/working-with-files) (such as [FLUX](https://fal.ai/models/fal-ai/flux/schnell) models). You can pass a preset string for common aspect ratios, or a custom `{width, height}` object for precise control.

| Preset           | Dimensions |
| ---------------- | ---------- |
| `square_hd`      | 1024x1024  |
| `square`         | 512x512    |
| `portrait_4_3`   | 768x1024   |
| `portrait_16_9`  | 576x1024   |
| `landscape_4_3`  | 1024x768   |
| `landscape_16_9` | 1024x576   |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset",
      "image_size": "landscape_16_9"
  })

  result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset",
      "image_size": {"width": 1280, "height": 720}
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/flux/schnell", {
    input: { prompt: "a sunset", image_size: "landscape_16_9" }
  });

  const result = await fal.subscribe("fal-ai/flux/schnell", {
    input: { prompt: "a sunset", image_size: { width: 1280, height: 720 } }
  });
  ```
</CodeGroup>

## aspect\_ratio

Some models (such as [Nano Banana 2](https://fal.ai/models/fal-ai/nano-banana-2)) use `aspect_ratio` instead of `image_size`. This accepts a ratio string and the model determines the output resolution internally.

|                   |                                                                                             |
| ----------------- | ------------------------------------------------------------------------------------------- |
| **Type**          | String                                                                                      |
| **Default**       | Varies by model                                                                             |
| **Common values** | `"1:1"`, `"16:9"`, `"9:16"`, `"4:3"`, `"3:4"`, `"3:2"`, `"2:3"`, `"21:9"`, `"4:5"`, `"5:4"` |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a sunset",
      "aspect_ratio": "16:9"
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset", aspect_ratio: "16:9" }
  });
  ```
</CodeGroup>

<Note>
  Check the model's API page to see whether it uses `image_size` or `aspect_ratio`. Passing the wrong one will have no effect.
</Note>

## enable\_safety\_checker

Enable or disable the content safety filter on generated outputs. When enabled, fal runs an ML-based classifier on each generated image to detect NSFW content (nudity and sexual content).

|                      |                        |
| -------------------- | ---------------------- |
| **Type**             | Boolean                |
| **Default**          | `true`                 |
| **Also accepted as** | `enable_safety_checks` |

Each generated image is analyzed by a classifier after generation. Images flagged as unsafe are replaced with a black image of the same dimensions. The response includes a `has_nsfw_concepts` array indicating which images were flagged, so you can detect and handle filtered outputs in your code.

```json theme={null}
{
  "images": [
    {"url": "https://v3.fal.media/files/...", "width": 1024, "height": 1024},
    {"url": "https://v3.fal.media/files/...", "width": 1024, "height": 1024}
  ],
  "has_nsfw_concepts": [false, true]
}
```

In this example, the second image was flagged and replaced with a black image.

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a sunset",
      "enable_safety_checker": True
  })

  if any(result.get("has_nsfw_concepts", [])):
      print("Some images were filtered by the safety checker")
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset", enable_safety_checker: true }
  });

  if (result.has_nsfw_concepts?.some(Boolean)) {
    console.log("Some images were filtered by the safety checker");
  }
  ```
</CodeGroup>

To disable the safety checker:

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a sunset",
      "enable_safety_checker": False
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset", enable_safety_checker: false }
  });
  ```
</CodeGroup>

<Note>
  Not all models support disabling the safety checker. Check the model's API page (e.g., [Nano Banana 2 API](https://fal.ai/models/fal-ai/nano-banana-2/api)) for the available parameters.
</Note>

## enable\_prompt\_expansion

When enabled, fal runs your prompt through an LLM before passing it to the model. The LLM rewrites short or vague prompts into richer descriptions with detail on composition, textures, colors, lighting, and mood. For example, "a sunset" might become a detailed scene description with specific lighting conditions, color palettes, and framing. This typically improves output quality for brief prompts but may alter the result if your prompt is already detailed and precise.

|                      |                                                     |
| -------------------- | --------------------------------------------------- |
| **Type**             | Boolean                                             |
| **Default**          | Varies by model                                     |
| **Also accepted as** | `expand_prompt` (some models use this name instead) |
| **Additional cost**  | Small per-request charge for the LLM inference step |

The expansion adds an LLM inference step before generation, so expect slightly higher latency per request. The expanded prompt is not returned in the response, so if you want to see what the model actually received, run the model with expansion disabled and handle prompt enhancement in your own pipeline.

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a sunset",
      "expand_prompt": True
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a sunset", expand_prompt: true }
  });
  ```
</CodeGroup>

<Note>
  Check the model's API page for the exact parameter name. Some models use `enable_prompt_expansion`, others use `expand_prompt`.
</Note>

## output\_format

Format of the generated image file. Choose based on your use case: `jpeg` for smaller file sizes with lossy compression, `png` for lossless quality with transparency support, or `webp` for a modern format that balances both.

|             |                                                 |
| ----------- | ----------------------------------------------- |
| **Type**    | String                                          |
| **Default** | Varies by model (typically `"jpeg"` or `"png"`) |
| **Values**  | `"jpeg"`, `"jpg"`, `"png"`, `"webp"`, `"gif"`   |

<CodeGroup>
  ```python Python theme={null}
  result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
      "prompt": "a sunset",
      "output_format": "png"
  })
  ```

  ```javascript JavaScript theme={null}
  const result = await fal.subscribe("fal-ai/flux/schnell", {
    input: { prompt: "a sunset", output_format: "png" }
  });
  ```
</CodeGroup>


# https://fal.ai/docs/documentation/model-apis/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Model APIs

> Access 1,000+ production-ready AI models through simple API calls

Model APIs gives you instant access to state-of-the-art AI models for image, video, audio, and multimodal generation. Every model is already optimized and production-ready, so you can [authenticate](/documentation/model-apis/authentication) and start generating immediately.

Each model runs on fal's infrastructure with automatic scaling, [queue-based reliability](/documentation/model-apis/inference/queue), and [pay-per-use billing](/documentation/model-apis/pricing). You call them the same way whether you use the [Python or JavaScript client](/documentation/model-apis/inference/client-setup) or raw HTTP. If you need to deploy your own model instead, see [Serverless](/documentation/serverless).

## Quick Example

Generate an image in three lines of code. Install the client, set your [API key](/documentation/model-apis/authentication), and call a model.

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a futuristic cityscape at sunset"
  })
  print(result["images"][0]["url"])
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: { prompt: "a futuristic cityscape at sunset" }
  });
  console.log(result.data.images[0].url);
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/nano-banana-2" \
    -H "Authorization: Key $FAL_KEY" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a futuristic cityscape at sunset"}'
  ```
</CodeGroup>

The response includes a [CDN URL](/documentation/model-apis/fal-cdn) for the generated image, along with metadata like dimensions and seed. Every model follows the same pattern: send inputs as JSON, receive outputs as JSON with media URLs.

## How It Works

Every model on fal is exposed as an HTTP endpoint. You can call it directly, or go through the [queue](/documentation/model-apis/inference/queue) for automatic retries, status tracking, and scaling. There are several calling patterns depending on your use case.

**[Direct (`run`)](/documentation/model-apis/inference/synchronous)** sends a synchronous HTTP request to `fal.run` and returns the result directly. This is the simplest approach for quick scripts and prototyping.

**[Subscribe](/documentation/model-apis/inference/synchronous)** uses the queue under the hood but handles polling automatically, so it feels synchronous. This is what the Quick Example above uses.

**[Asynchronous (`submit`)](/documentation/model-apis/inference/queue)** gives you full control over the queue. Submit a request and return immediately, then poll for status or receive results via [webhook](/documentation/model-apis/inference/webhooks). This is the recommended approach for production workloads with parallel processing.

**[Streaming](/documentation/model-apis/inference/streaming)** delivers output progressively as the model generates it. This is useful for LLMs that produce tokens incrementally, or for showing generation progress in a UI.

**[`realtime()`](/documentation/model-apis/inference/real-time)** uses WebSockets for persistent connections, bypassing the queue entirely for sub-100ms latency. Only available for models with an explicit real-time endpoint.

## What You Can Generate

The [model gallery](https://fal.ai/models) has 1,000+ models spanning several categories. Here are some popular starting points.

### Image Generation and Editing

<CardGroup cols={3}>
  <Card title="Nano Banana 2" href="https://fal.ai/models/fal-ai/nano-banana-2" img="https://v3b.fal.media/files/b/0a900b9e/ptbZcVWIQ_fXGGHfv8Zez_0ea5ca41bdf143a29e21e30a53120672.jpg">
    Google's fast image generation and editing model
  </Card>

  <Card title="Nano Banana Pro" href="https://fal.ai/models/fal-ai/nano-banana-pro" img="https://v3b.fal.media/files/b/kangaroo/WcNt4yo_7RJaCZa0Og6gE_37660458463d4008959517c59a40aafd.jpg">
    State-of-the-art image generation with realism and typography
  </Card>

  <Card title="Flux 2 Flex" href="https://fal.ai/models/fal-ai/flux-2-flex" img="https://v3b.fal.media/files/b/panda/LqyVE8NElm_vf-t27Yfkz_6c1dd3323df343e4a3ec968d8f67024c.jpg">
    Enhanced typography and text rendering from BFL
  </Card>

  <Card title="Recraft V4 Pro" href="https://fal.ai/models/fal-ai/recraft/v4/pro/text-to-image" img="https://v3b.fal.media/files/b/0a8e35b5/OO8LkBQxwwkEj6SVlP3Bl_2ebfa787acba475b883a9f4ad9106032.jpg">
    Professional design and marketing visuals
  </Card>

  <Card title="Nano Banana 2 Edit" href="https://fal.ai/models/fal-ai/nano-banana-2/edit" img="https://v3b.fal.media/files/b/0a900b75/DHb_RgXoXsYLdvzQz6mdn_95e87a44239c43448939b4c382dd957c.jpg">
    Intelligent image editing with Google's latest model
  </Card>

  <Card title="FLUX Kontext Pro" href="https://fal.ai/models/fal-ai/flux-pro/kontext" img="https://v3b.fal.media/files/b/0a8691ce/SR0_u1zPJbx8jCIO6bJR0_8c83f0d66bbd48f3b55f825117941f84.jpg">
    Targeted edits and complex scene transformations
  </Card>
</CardGroup>

### Video Generation

<CardGroup cols={3}>
  <Card title="Veo 3.1" href="https://fal.ai/models/fal-ai/veo3.1" img="https://v3b.fal.media/files/b/tiger/IwzOGSbzp6e8N00QuLtFF_129417bb24f248298e95c3fa2b1b82fb.jpg">
    Google DeepMind's latest video model with sound
  </Card>

  <Card title="Kling 3.0 Pro" href="https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/image-to-video" img="https://v3b.fal.media/files/b/0a8cfd08/Ji4e0i6Afbeql3Wr5UTz6_ab60b14661424612bf19059e97e996a5.jpg">
    Cinematic image-to-video with fluid motion
  </Card>

  <Card title="Kling O3" href="https://fal.ai/models/fal-ai/kling-video/o3/standard/image-to-video" img="https://v3b.fal.media/files/b/0a8d2007/gV_LMXNrguqRaDB9sLqir_b5d36b36de5a40bdb5cb2cd3f8af29d7.jpg">
    Start and end frame animation with scene guidance
  </Card>

  <Card title="Sora 2" href="https://fal.ai/models/fal-ai/sora-2/text-to-video" img="https://v3b.fal.media/files/b/lion/0bXyMS_zSKpeaG3LM6ARv_d4ee6acbfd9a4168b012a848c33b154d.jpg">
    OpenAI's video model with audio generation
  </Card>

  <Card title="LTX-2 19B" href="https://fal.ai/models/fal-ai/ltx-2-19b/image-to-video" img="https://v3b.fal.media/files/b/0a8935fe/Ezbvf27opeW6gEoDS4nlw_da7064399f9c4342b5e118f6875ec389.jpg">
    Video with audio from images using LTX-2
  </Card>

  <Card title="Sora 2 Pro" href="https://fal.ai/models/fal-ai/sora-2/text-to-video/pro" img="https://v3b.fal.media/files/b/lion/0bXyMS_zSKpeaG3LM6ARv_d4ee6acbfd9a4168b012a848c33b154d.jpg">
    OpenAI's premium video model with enhanced quality
  </Card>
</CardGroup>

### Audio and Speech

<CardGroup cols={3}>
  <Card title="Chatterbox TTS" href="https://fal.ai/models/fal-ai/chatterbox/text-to-speech" img="https://fal.media/files/rabbit/FzzCnGuQNXLOEYuQq8CE8_7afb3290e0de46d5a7e4d13495938e3f.jpg">
    Natural text-to-speech from Resemble AI
  </Card>

  <Card title="MiniMax Speech-02 HD" href="https://fal.ai/models/fal-ai/minimax/speech-02-hd" img="https://fal.media/files/panda/A-mMZvJzo3C_kFbO7NmMi_28b71bd757bf4319973fb209c96453f9.jpg">
    High-quality multi-voice text-to-speech
  </Card>

  <Card title="Dia TTS" href="https://fal.ai/models/fal-ai/dia-tts/voice-clone" img="https://storage.googleapis.com/fal_cdn/fal/Sound-4.jpg">
    Multi-speaker dialogue with voice cloning
  </Card>

  <Card title="Beatoven Music" href="https://fal.ai/models/fal-ai/beatoven/music-generation" img="https://v3b.fal.media/files/b/rabbit/-fqZhGXxiW3usZOZ267NO_9c5cd9c1-62d9-4ed9-8c8e-3c148614c137.png">
    Royalty-free instrumental music generation
  </Card>

  <Card title="Beatoven SFX" href="https://fal.ai/models/fal-ai/beatoven/sound-effect-generation" img="https://v3b.fal.media/files/b/penguin/SV2axpXDRJpr3LamW4PGo_9bca6ced-1271-4fbf-9869-c8db8ff81977.png">
    Professional sound effect generation
  </Card>

  <Card title="ElevenLabs Music" href="https://fal.ai/models/fal-ai/elevenlabs/music" img="https://v3b.fal.media/files/b/0a875694/SZffdb8layV90JxfN5fkP_d2048a658d9e4dc9973598f3542833a0.jpg">
    High quality, realistic music generation
  </Card>
</CardGroup>

<Card title="Explore All Models" icon="cube" href="https://fal.ai/explore" arrow={true}>
  Browse 1,000+ models across image, video, audio, 3D, and more
</Card>

Every model page on fal.ai includes a [Playground](/documentation/model-apis/playground) for testing, full API documentation with [input/output schemas](/documentation/model-apis/common-parameters), [pricing](/documentation/model-apis/pricing), and ready-to-copy code examples.

## Next Steps

<CardGroup cols={2}>
  <Card title="Playground" icon="play" href="/documentation/model-apis/playground">
    Test and compare models interactively before integrating
  </Card>

  <Card title="Inference" icon="server" href="/documentation/model-apis/inference">
    Learn the different ways to call models
  </Card>

  <Card title="Client Setup" icon="code" href="/documentation/model-apis/inference/client-setup">
    Install and configure the fal client for Python, JavaScript, and more
  </Card>

  <Card title="Examples" icon="flask" href="/examples">
    Step-by-step tutorials for image, video, and audio generation
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/model-apis/playground.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Playground

> Test any model with real inputs, see results, and copy working code.

Every model on fal has a Playground where you can try it with real inputs, see outputs instantly, and copy working code in Python, JavaScript, or cURL. When you [deploy your own app](/documentation/serverless), it gets a Playground too, so your teammates and users can test it the same way.

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/8WsQEbl1OYp5vQ4g/images/examples/playground-nano-banana-2.png?fit=max&auto=format&n=8WsQEbl1OYp5vQ4g&q=85&s=e230ae5495b191fca50bd9ec27194ab4" alt="Playground for Nano Banana 2 on fal.ai" width="1920" height="1088" data-path="images/examples/playground-nano-banana-2.png" />
</Frame>

The Playground is the fastest way to validate a model before writing any integration code. Once you have a result you like, copy the generated code into your project and you are ready to go. If you want to compare multiple models side by side, use the [Sandbox](/documentation/model-apis/sandbox) instead. For programmatic access, see [Client Setup](/documentation/model-apis/inference/client-setup).

## Try It

The best way to understand the Playground is to open one. Pick a model and start generating.

<CardGroup cols={3}>
  <Card title="Nano Banana 2" href="https://fal.ai/models/fal-ai/nano-banana-2" img="https://v3b.fal.media/files/b/0a900b9e/ptbZcVWIQ_fXGGHfv8Zez_0ea5ca41bdf143a29e21e30a53120672.jpg">
    Google's fast image generation and editing
  </Card>

  <Card title="Veo 3.1" href="https://fal.ai/models/fal-ai/veo3.1" img="https://v3b.fal.media/files/b/tiger/IwzOGSbzp6e8N00QuLtFF_129417bb24f248298e95c3fa2b1b82fb.jpg">
    Google DeepMind's latest video model with sound
  </Card>

  <Card title="ElevenLabs Music" href="https://fal.ai/models/fal-ai/elevenlabs/music" img="https://v3b.fal.media/files/b/0a875694/SZffdb8layV90JxfN5fkP_d2048a658d9e4dc9973598f3542833a0.jpg">
    High quality, realistic music generation
  </Card>
</CardGroup>

## What the Playground Shows

Each model page on fal.ai (for example, [Nano Banana 2](https://fal.ai/models/fal-ai/nano-banana-2)) is organized into tabs. The **Playground** tab lets you fill in inputs and run the model directly in your browser. The **API** tab shows the full input and output schemas with type information, so you know exactly what fields are available and what the response looks like. The page also displays pricing, average latency, and ready-to-copy code examples.

## Testing a Model

<Steps>
  <Step title="Find a model">
    Browse the [model gallery](https://fal.ai/models) or search for a specific model. Click on it to open its page.
  </Step>

  <Step title="Fill in the inputs">
    The Playground form is auto-generated from the model's input schema. Required fields are marked, and optional fields have sensible defaults. For models that accept images, video, or audio, you can upload files directly.
  </Step>

  <Step title="Run the model">
    Click **Run** to submit your request. The result appears below the form, typically within a few seconds.
  </Step>

  <Step title="Iterate">
    Adjust your inputs and run again. Each result stays visible so you can compare outputs across runs.
  </Step>
</Steps>

## Copying Code

Every Playground result includes generated code that reproduces the exact request you just ran. Click the code tab to see examples in Python, JavaScript, and cURL, then copy them directly into your project.

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={
      "prompt": "a futuristic cityscape at sunset",
      "aspect_ratio": "16:9"
  })
  print(result["images"][0]["url"])
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: {
      prompt: "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
    },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash cURL theme={null}
  curl -X POST "https://queue.fal.run/fal-ai/nano-banana-2" \
    -H "Authorization: Key $FAL_KEY" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "a futuristic cityscape at sunset", "aspect_ratio": "16:9"}'
  ```
</CodeGroup>

The generated code includes all the parameters you configured in the form, so there is no gap between what you tested and what you ship.

## Your Own Apps

When you run `fal deploy`, the output includes a Playground URL for your app. This means anyone with access can test your endpoints through the same interface that powers the model gallery.

```bash theme={null}
fal deploy my_app.py::MyApp
# Output includes:
#   Playground: https://fal.ai/models/your-username/my-app
```

To control how your app's inputs render in the Playground (image uploaders, hidden fields, field ordering), see [Handle Inputs and Outputs](/documentation/development/handle-inputs-and-outputs). For example, naming a field with an `image_url` suffix renders it as an image upload widget, and wrapping a field in `Hidden()` keeps it accessible via API but hides it from the Playground form.

## Playground vs Sandbox

The Playground and the [Sandbox](https://fal.ai/sandbox) serve different purposes. The Playground is for testing a single model with specific inputs and copying code. The Sandbox is for comparing multiple models at once, with features like model sets, cost estimates, search across past generations, and shareable links.

|                     | Playground                | Sandbox                                  |
| ------------------- | ------------------------- | ---------------------------------------- |
| **Purpose**         | Test one model, copy code | Compare multiple models                  |
| **Where**           | Each model's page         | [fal.ai/sandbox](https://fal.ai/sandbox) |
| **Your own apps**   | Yes, after `fal deploy`   | Yes, can be added manually               |
| **Code generation** | Python, JS, cURL          | Not available                            |
| **Sharing**         | Not available             | Shareable links with previews            |

## More Models to Try

<CardGroup cols={3}>
  <Card title="Nano Banana 2 Edit" href="https://fal.ai/models/fal-ai/nano-banana-2/edit" img="https://v3b.fal.media/files/b/0a900b75/DHb_RgXoXsYLdvzQz6mdn_95e87a44239c43448939b4c382dd957c.jpg">
    Intelligent image editing
  </Card>

  <Card title="Kling 3.0 Pro" href="https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/image-to-video" img="https://v3b.fal.media/files/b/0a8cfd08/Ji4e0i6Afbeql3Wr5UTz6_ab60b14661424612bf19059e97e996a5.jpg">
    Cinematic image-to-video
  </Card>

  <Card title="Sora 2" href="https://fal.ai/models/fal-ai/sora-2/text-to-video" img="https://v3b.fal.media/files/b/lion/0bXyMS_zSKpeaG3LM6ARv_d4ee6acbfd9a4168b012a848c33b154d.jpg">
    OpenAI's video model with audio
  </Card>

  <Card title="Recraft V4 Pro" href="https://fal.ai/models/fal-ai/recraft/v4/pro/text-to-image" img="https://v3b.fal.media/files/b/0a8e35b5/OO8LkBQxwwkEj6SVlP3Bl_2ebfa787acba475b883a9f4ad9106032.jpg">
    Professional design visuals
  </Card>

  <Card title="Chatterbox TTS" href="https://fal.ai/models/fal-ai/chatterbox/text-to-speech" img="https://fal.media/files/rabbit/FzzCnGuQNXLOEYuQq8CE8_7afb3290e0de46d5a7e4d13495938e3f.jpg">
    Natural text-to-speech
  </Card>

  <Card title="Browse All" icon="cube" href="https://fal.ai/explore">
    1,000+ models to explore
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/model-apis/pricing.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pricing

> How billing works for fal Model APIs.

When you call a pre-trained model through fal's Model APIs, you are billed based on the output you generate. Each model on fal has its own pricing and billing unit, visible on the model's page in the [gallery](https://fal.ai/models) and at [fal.ai/pricing](https://fal.ai/pricing). You pay only for successful outputs, and you are never charged for server errors or time spent waiting in the queue.

fal uses a prepaid credit model. You purchase credits in advance and they are drawn down as you use the platform. Credits fund both Model API usage and your [concurrency limit](/documentation/model-apis/concurrency-limits), which scales with your purchase history. If you deploy your own applications on [Serverless](/documentation/serverless), billing works differently and is covered on the [Serverless pricing](/documentation/serverless/pricing) page.

## Per-Model Pricing

The billing unit varies by model type. Image generation models typically charge per image or per megapixel of output, where higher resolutions cost proportionally more. Video generation models charge per second of generated video or a flat rate per video. Other models, such as LLMs or audio models, charge per request or per output unit specific to the model.

Models that do not have a fixed per-output price fall back to per-second billing based on the GPU [machine type](/documentation/deployment/machine-types) used to run the request. This fallback applies to some less common models and to your own Serverless endpoints.

| Model type       | Billing unit                   | How it works                                              |
| ---------------- | ------------------------------ | --------------------------------------------------------- |
| Image generation | Per image or per megapixel     | Flat rate per image, or proportional to output resolution |
| Video generation | Per second or per video        | Per second of generated video, or flat rate per video     |
| Other models     | Per request or compute seconds | Flat rate per request, or per-second billing by GPU type  |

<Note>
  Prices vary by model and may change. Check the model's page or the [pricing page](https://fal.ai/pricing) for current rates. You can also query prices programmatically through the [Platform APIs](/api-reference/platform-apis/for-models).
</Note>

## What You Pay For

You are billed for successfully generated outputs. The billing unit (image, megapixel, video second, etc.) is defined per model. When a model does not have a fixed output price, billing falls back to per-second pricing based on the GPU machine type that processed your request.

## What You Are Not Charged For

Server errors are never billed. If a request fails with an HTTP 500 or higher status code, no charge is incurred. Time spent waiting in the [queue](/documentation/model-apis/inference/queue) before a runner starts processing your request is also free. Only the actual inference work counts toward your bill.

## Checking Prices Programmatically

You can retrieve pricing information for any model endpoint through the [Platform APIs](/api-reference/platform-apis/for-models). This is useful for building cost estimation into your application or comparing rates across models.

```bash theme={null}
curl "https://api.fal.ai/v1/models/pricing?endpoint_id=fal-ai/flux/dev" \
  -H "Authorization: Key $FAL_KEY"
```

The response includes the billing unit and unit price for each endpoint:

```json theme={null}
{
  "prices": [
    {
      "endpoint_id": "fal-ai/flux/dev",
      "unit_price": 0.025,
      "unit": "image",
      "currency": "USD"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
```

You can also estimate costs before running a request, query usage line items with unit quantities and prices, and access time-bucketed analytics for spend tracking.

<Card title="Platform APIs for Models" icon="arrow-right" href="/api-reference/platform-apis/for-models">
  Full reference for pricing, usage, and analytics APIs
</Card>

## Enterprise Pricing

Enterprise customers can receive custom per-endpoint pricing and volume discounts. These are configured per account and apply automatically to all requests. Contact the [sales team](https://fal.ai/enterprise#contact-sales) for details.

## Monitoring Your Usage

The billing dashboard shows your overall spend, invoices, and payment history. For per-model cost breakdowns and request-level detail, use the usage and analytics Platform APIs, or check the billing reports available in the dashboard.

<CardGroup cols={2}>
  <Card title="Dashboard Billing" icon="chart-line" href="https://fal.ai/dashboard/billing">
    View your overall spend, invoices, and payment methods
  </Card>

  <Card title="Concurrency Limits" icon="gauge" href="/documentation/model-apis/concurrency-limits">
    Understand how credit purchases affect your concurrency limit
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/model-apis/request-errors.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Request Error Types

> Infrastructure-level error types for timeouts, runner failures, and connection errors.

When a request fails due to infrastructure-level issues rather than model validation, the platform returns a structured error response with a machine-readable `error_type` field. These errors cover timeouts, runner crashes, scheduling failures, and connection problems that occur before or during request processing.

Request errors use a different response format than [model validation errors](/documentation/model-apis/errors). Model errors return a `detail` array of typed error objects. Request errors return a flat object with `detail` as a human-readable string and `error_type` as a machine-readable category. The same value is also available in the `X-Fal-Error-Type` response header for programmatic access without parsing the body.

## Response Structure

| Property     | Description                                                                 |
| :----------- | :-------------------------------------------------------------------------- |
| `detail`     | A human-readable description of the error.                                  |
| `error_type` | A machine-readable string identifying the error category (see table below). |

```json theme={null}
{
  "detail": "Request timed out",
  "error_type": "request_timeout"
}
```

The `X-Fal-Error-Type` response header contains the same value as `error_type`.

## Error Type Reference

| Error Type                   | Description                                                    | Typical Status Code |
| :--------------------------- | :------------------------------------------------------------- | :------------------ |
| `request_timeout`            | The request exceeded the allowed processing time.              | 504                 |
| `startup_timeout`            | The runner did not start within the allowed time.              | 504                 |
| `runner_scheduling_failure`  | No runner could be allocated to handle the request.            | 503                 |
| `runner_connection_timeout`  | The connection to the runner timed out.                        | 503                 |
| `runner_disconnected`        | The runner disconnected unexpectedly during processing.        | 503                 |
| `runner_connection_refused`  | The runner refused the connection.                             | 503                 |
| `runner_connection_error`    | A general connection error occurred with the runner.           | 503                 |
| `runner_incomplete_response` | The runner sent an incomplete response payload.                | 502                 |
| `runner_server_error`        | The runner encountered an internal server error.               | 500                 |
| `client_disconnected`        | The client closed the connection before the response was sent. | 499                 |
| `client_cancelled`           | The request was cancelled by the client.                       | 499                 |
| `bad_request`                | The request was malformed (e.g., invalid timeout header).      | 400                 |
| `internal_error`             | An unexpected internal error occurred.                         | 500                 |

## Handling Request Errors

**For retry logic:** Use `error_type` to decide whether to retry. Runner and timeout errors (e.g., `runner_connection_timeout`, `startup_timeout`) are typically transient and worth retrying. Client errors (`client_disconnected`, `bad_request`) should not be retried. See [Retries and Error Handling](/documentation/serverless/reliability/retries) for how the platform handles retries automatically.

**For monitoring:** The `error_type` is also available in [queue status responses](/documentation/model-apis/inference/queue#request-lifecycle) for failed requests, making it useful for tracking failure patterns in your [analytics dashboard](/documentation/serverless/observability/app-analytics).

<CardGroup cols={2}>
  <Card title="Model Errors" icon="triangle-exclamation" href="/documentation/model-apis/errors">
    Validation errors from model inputs (images, video, audio)
  </Card>

  <Card title="Retries" icon="rotate" href="/documentation/serverless/reliability/retries">
    How fal automatically retries failed requests
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/model-apis/sandbox.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandbox

> Sandbox is your creative playground for testing and comparing the latest AI models across all popular media generation operations. Compare models side-by-side, estimate costs before running, and share your creations.

Sandbox is your creative playground for testing and comparing the latest AI models across all popular media generation operations. Run any prompt through multiple models at once to quickly find the best fit for your use case.

Whether you're generating images from text, animating photos into videos, upscaling content, or creating music and sound effects or many other operations, [Sandbox](https://fal.ai/sandbox) provides a unified interface to experiment with multiple state-of-the-art models simultaneously.

## Try it

<CardGroup cols={3}>
  <Card title="Generate an Image" href="https://fal.ai/sandbox/image/text-to-image" img="https://v3b.fal.media/files/b/0a900b9e/ptbZcVWIQ_fXGGHfv8Zez_0ea5ca41bdf143a29e21e30a53120672.jpg">
    Text-to-image with Nano Banana 2, FLUX, Recraft, and more
  </Card>

  <Card title="Generate a Video" href="https://fal.ai/sandbox/video/image-to-video" img="https://v3b.fal.media/files/b/tiger/IwzOGSbzp6e8N00QuLtFF_129417bb24f248298e95c3fa2b1b82fb.jpg">
    Image-to-video with Veo 3.1, Kling, Sora 2, and more
  </Card>

  <Card title="Generate Music" href="https://fal.ai/sandbox/audio/text-to-music" img="https://v3b.fal.media/files/b/0a875694/SZffdb8layV90JxfN5fkP_d2048a658d9e4dc9973598f3542833a0.jpg">
    Text-to-music with ElevenLabs, Beatoven, MiniMax, and more
  </Card>
</CardGroup>

## What you can do

* **Compare models side-by-side**: Run the same prompt or input across multiple models to see which produces the best results for your use case
* **Test all major operations**: Text-to-image, image editing, video generation, upscaling, background removal, audio generation, and more
* **Estimate costs before running**: See the estimated cost for your selected models and quantity before submitting
* **Search your generations**: Find previous results by text, image similarity, or dominant color
* **Share your creations**: Generate shareable links with social media previews

## Supported operations

### Image

| Operation             | Description                                        |
| --------------------- | -------------------------------------------------- |
| **Text to Image**     | Generate images from text prompts                  |
| **Edit Image**        | Modify an image using a prompt and reference image |
| **Edit Multi-Images** | Apply edits using multiple reference images        |
| **Upscale**           | Increase image resolution with AI enhancement      |
| **Remove Background** | Extract subjects from their backgrounds            |

### Video

| Operation             | Description                                          |
| --------------------- | ---------------------------------------------------- |
| **Text to Video**     | Generate videos from text prompts                    |
| **Image to Video**    | Animate a still image into a video                   |
| **Start + End Frame** | Generate a video that transitions between two images |
| **Upscale**           | Enhance video resolution                             |
| **Remove Background** | Remove backgrounds from video clips                  |
| **Video to Audio**    | Generate audio/sound effects for a video             |

### Audio

| Operation                 | Description                            |
| ------------------------- | -------------------------------------- |
| **Text to Music**         | Generate music from a description      |
| **Text to Speech**        | Convert text into spoken audio         |
| **Text to Sound Effects** | Create sound effects from descriptions |

## Key concepts

### Canonical input

Different AI models, even when performing the same task, often have different input schemas. For example, one image generation model might accept `prompt` while another uses `text` or `description`.

Sandbox solves this with **canonical input** — a standardized input format for each operation type. When you fill out the form in Sandbox, you're providing canonical input. Behind the scenes, Sandbox automatically remaps your input to match each model's expected schema.

For example, when you enter a prompt in the image editing operation:

* The canonical field is `prompt`
* It may be remapped to `text`, `edit_prompt`, or `instruction` depending on the model
* Image URL fields may be remapped to `image`, `source_image`, `input_image`, etc.

This means the actual API request sent to each model may have a slightly different input shape than what you see in Sandbox, but the semantic meaning is preserved.

### Model sets

With many models available for each operation, selecting the right ones can be overwhelming. **Model sets** solve this by grouping models into curated collections:

* **State of the Art**: The best-performing models for general use
* **Anime Style**: Models optimized for anime and illustration aesthetics
* **Fast Generation**: Models prioritizing speed over maximum quality
* **Custom Sets**: Create your own collections for specific workflows

To use a model set:

1. Click the "explore sets" button in the prompt bar
2. Pick a pre-built set or create your own from the modal

Model sets are operation-specific — each operation type has its own available model sets.

### Runs and requests

Understanding Sandbox's structure:

* **Run**: A single submission in Sandbox. When you click "Run", you create one run.
* **Requests**: Individual API calls to each model within a run. If you select 3 models with quantity 2x, your run contains 6 requests.

Each run:

* Has a unique share ID for sharing
* Records all input parameters (canonical input)
* Tracks the status, cost, and duration of each request
* Generates a preview image for social sharing

### Estimated cost

Before running, Sandbox displays an estimated cost based on:

* The models you've selected
* The quantity (number of times to run each model)

The estimate appears in the footer of the prompt bar with color-coded badges:

* **Green**: Under \$1
* **Yellow**: $1 - $2.50
* **Red**: Over \$2.50

The actual cost may vary based on output complexity (e.g., longer videos cost more).

## Using Sandbox

### Running a generation

<Steps>
  <Step>
    **Select the media type**: Choose Image, Video, or Audio from the top tabs
  </Step>

  <Step>
    **Choose an operation**: Select the specific operation (e.g., Text to Image,
    Image to Video)
  </Step>

  <Step>
    **Fill in the inputs**: Enter your prompt and any required media inputs
  </Step>

  <Step>
    **Select models**: Choose which models to run (or use a model set)
  </Step>

  <Step>**Set quantity**: Optionally run each model multiple times</Step>
  <Step>**Click Run**: Submit your generation</Step>
</Steps>

### Enhancing prompts

Many operations support **prompt enhancement** — an AI-powered feature that expands your basic prompt into a more detailed, effective version:

1. Enter your initial prompt
2. Click the sparkle/enhance icon next to the prompt field
3. Sandbox uses an LLM (or VLM for image-based operations) to expand your prompt
4. The enhanced prompt replaces your original

Enhancement is especially useful for:

* **Text-to-image**: Adds artistic style, lighting, and composition details
* **Image-to-video**: Describes motion and camera movements
* **Video generation**: Specifies pacing and transitions

### Random examples

Not sure what to try? Click the **dice icon** next to the operation selector to fill the form with a curated example. Each click cycles through different examples for that operation.

### Working with results

After a run completes, each generation appears in the canvas area.

**Viewing results**

* Click any result to open the full-screen media viewer
* Navigate between results using arrow keys or on-screen controls
* View detailed metadata including model, cost, and generation time

**Badges on results**

* **Fastest**: Quickest generation in the run
* **Cheapest**: Lowest cost in the run
* **Free**: Generated using free credits

**Using results as input**

* Hover over any image/video result
* Click the "Use as input" button to apply it to a compatible operation
* Sandbox automatically switches to an appropriate operation if needed

### Copying and rerunning

The **Input Card** (visible when "Show Metadata" is enabled) provides quick actions:

| Action       | Description                                               |
| ------------ | --------------------------------------------------------- |
| **Copy**     | Populate the input form with this run's settings          |
| **Rerun**    | Immediately execute the same run again                    |
| **Archive**  | Remove from Sandbox (still accessible in request history) |
| **Share**    | Generate a shareable link                                 |
| **Bookmark** | Bookmark the run for easy access later                    |

You can also click individual fields in the input card to copy just that value to your current form.

## Searching generations

Sandbox provides powerful search capabilities to find previous generations.

### Text search

Type in the search bar to find generations by semantic similarity to your query. This searches the prompts and other text fields.

### Image search

1. Click the image icon in the search bar
2. Upload an image
3. Find visually similar generations

### Color search

1. Click the palette icon in the search bar
2. Select a color
3. Find generations with that dominant color

### Filtering

Combine search with filters:

* **Operation Type**: Show only specific operations (e.g., just video generations)
* **Team Member**: In team workspaces, filter by who created the generation
* **Bookmarks**: Show only bookmarked favorites
* **Similarity Threshold**: Adjust how closely results must match your search

## Free credits

Sandbox occasionally offers free credits for specific models:

* Look for the **gift icon** with an orange dot in the interface
* Click to see all models with remaining free credits
* Free credits come from:
  * Global campaigns (available to all users)
  * User-specific grants

When you have free credits, the cost badge shows "Free" and generations are marked with a gift icon.

<Note>
  Free credits and free request coupons are only usable in Sandbox and the
  Playground — they cannot be used through the API or Workflows.
</Note>

## Sharing runs

Share your generations with anyone:

1. Complete a run (all generations must finish)
2. Click the share icon on the input card
3. Copy the generated link

Shared runs include:

* A preview image/video for social media cards
* All generations from the run
* Input parameters used

Recipients can view the shared run without a fal account. If they want to remix it, they can copy the inputs to their own Sandbox.

## Keyboard shortcuts

| Shortcut | Action                             |
| -------- | ---------------------------------- |
| `←` `→`  | Navigate between results in viewer |
| `Escape` | Close viewer                       |

## Using your own apps and workflows

You can add your own [serverless apps](/serverless) and [workflows](/model-apis/model-endpoints/workflows) to Sandbox, allowing you to compare your custom models alongside platform models.

### Requirements

For your app or workflow to work in Sandbox, it must:

1. **Accept the canonical input fields** (or supported variations) for the operation type
2. **Return the expected output fields** for that operation's media type

Sandbox automatically validates your app's schema when you add it and will show warnings if there are compatibility issues.

### Adding your apps

<Steps>
  <Step>
    **Click the apps icon** in the operation selector bar (next to the operation dropdown)
  </Step>

  <Step>
    **Search for your app or workflow** using the search field
  </Step>

  <Step>
    **Select apps to add** — Sandbox validates each app's schema against the operation requirements
  </Step>

  <Step>
    **Save your selection** — Added apps appear in the model picker alongside platform models
  </Step>
</Steps>

Apps are added per-operation. If your app works for multiple operations (e.g., both text-to-image and image editing), you'll need to add it to each operation separately.

<Note>
  When running your own apps in Sandbox, cost and duration metrics may not be
  available since these are tracked differently for private endpoints.
</Note>

### Canonical input schemas

Each operation type has a **canonical input schema** — the standardized fields that Sandbox uses. Your app can use either the canonical field names or any of the supported variations.

#### Image operations

| Operation             | Canonical Fields                       |
| --------------------- | -------------------------------------- |
| **Text to Image**     | `prompt`, `aspect_ratio`               |
| **Edit Image**        | `prompt`, `image_url`, `aspect_ratio`  |
| **Edit Multi-Images** | `prompt`, `image_urls`, `aspect_ratio` |
| **Upscale**           | `image_url`, `scale`                   |
| **Remove Background** | `image_url`                            |

#### Video operations

| Operation             | Canonical Fields                                                 |
| --------------------- | ---------------------------------------------------------------- |
| **Text to Video**     | `prompt`, `duration`, `aspect_ratio`                             |
| **Image to Video**    | `prompt`, `image_url`, `duration`, `aspect_ratio`                |
| **Start + End Frame** | `prompt`, `start_frame`, `end_frame`, `duration`, `aspect_ratio` |
| **Upscale**           | `video_url`, `scale`                                             |
| **Remove Background** | `video_url`                                                      |
| **Video to Audio**    | `video_url`, `prompt`                                            |

#### Audio operations

| Operation                 | Canonical Fields |
| ------------------------- | ---------------- |
| **Text to Music**         | `prompt`         |
| **Text to Speech**        | `prompt`         |
| **Text to Sound Effects** | `prompt`         |

### Supported field variations

If your app uses different field names, Sandbox can automatically remap them. The table below shows which field names are recognized for each canonical field:

| Canonical Field | Accepted Variations                                                                                   |
| --------------- | ----------------------------------------------------------------------------------------------------- |
| `prompt`        | `text`, `description`, `edit_prompt`, `instruction`, `lyrics_prompt`, `script`, `text_prompt`         |
| `image_url`     | `image`, `source_image`, `input_image`, `control_image_url`, `reference_image_url`, `start_image_url` |
| `image_urls`    | `images`, `source_images`, `input_images`, `control_images`, `reference_image_urls`                   |
| `video_url`     | `video`, `source_video`, `input_video`                                                                |
| `start_frame`   | `start_image_url`, `start_image`, `first_frame`, `first_frame_url`, `first_image_url`                 |
| `end_frame`     | `end_image_url`, `end_image`, `last_frame`, `last_frame_url`, `tail_image_url`, `last_image_url`      |
| `scale`         | `upscaling_factor`, `upscale_factor`                                                                  |
| `duration`      | `video_length`                                                                                        |

### Field transforms

Some fields undergo value transformation in addition to name remapping:

| Canonical Field | Transform Behavior                                                                                                                |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `aspect_ratio`  | Values like `16:9`, `4:3`, `1:1` may be converted to `landscape_16_9`, `landscape_4_3`, `square_hd` for models using `image_size` |
| `duration`      | Automatically matched to the closest available option if model has enumerated durations (e.g., `5s`, `10s`)                       |
| `scale`         | May be converted to discrete values like `"2"` or `"4"` for models with `desired_increase` field                                  |

### Required output fields

Your app must return the correct output structure for Sandbox to display results:

| Output Type | Required Fields                                    |
| ----------- | -------------------------------------------------- |
| **Image**   | `images` (array), `image` (object), or `image_url` |
| **Video**   | `video` (object) or `video_url`                    |
| **Audio**   | `audio` (object) or `audio_url`                    |

For image outputs, the standard structure is:

```json theme={null}
{
  "images": [
    {
      "url": "https://...",
      "width": 1024,
      "height": 1024,
      "content_type": "image/png"
    }
  ]
}
```

For video outputs:

```json theme={null}
{
  "video": {
    "url": "https://...",
    "content_type": "video/mp4"
  }
}
```

For audio outputs:

```json theme={null}
{
  "audio_url": "https://..."
}
```

### Validation indicators

When adding apps, Sandbox shows validation status:

| Icon     | Meaning                                                        |
| -------- | -------------------------------------------------------------- |
| ✓ Green  | Fully compatible — schema matches operation requirements       |
| ⚠ Yellow | Has warnings — may work but some fields require transformation |
| ✕ Red    | Incompatible — missing required fields or wrong output type    |
| ℹ Blue   | Has info — some fields will be automatically transformed       |

<Warning>
  Apps with validation errors (red icon) cannot be added. You'll need to update
  your app's schema to match the operation requirements.
</Warning>

## Tips for best results

1. **Start with model sets**: Typically, the default models automatically selected are the best performing models for the operation.
2. **Enhance your prompts**: Let AI expand basic ideas into detailed prompts with the "enhance prompt" button.
3. **Compare with quantity 1x**: Save costs by running single generations when comparing models
4. **Use image search**: Find similar past generations to avoid recreating work
5. **Bookmark favorites**: Mark your best results for easy access later
6. **Check free credits**: Look for the gift icon before running expensive models


# https://fal.ai/docs/documentation/model-apis/support.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Support

> Support documentation for fal.ai AI APIs. Developer guide with examples, best practices, and implementation details.

The fal team is here to help you build and scale your AI applications. Whether you have questions about integration, need help debugging, or want to discuss your use case, we offer several support channels.

From direct email support to an active Discord community, you can get the assistance you need to make the most of the fal platform.

## Contact Us

If you need assistance, please reach out to us at [support@fal.ai](mailto:support@fal.ai).

## Join Our Community

Join our Discord community for discussions and updates: [Discord](https://discord.com/invite/fal-ai).

## Quickstart Guide

New to fal.ai? Check out our [Quickstart Guide](/serverless/getting-started/quick-start) to get started quickly.


# https://fal.ai/docs/documentation/model-apis/workflows.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflow Endpoints

> Workflows are a way to chain multiple models together to create a more complex pipeline. This allows you to create a single endpoint that can take an input and pass it through multiple models in sequence. This is useful for creating more complex models that require multiple steps, or for creating a single endpoint that can handle multiple tasks.

Workflows let you chain multiple models together into a single endpoint, creating complex pipelines that run as one API call. Instead of orchestrating individual model requests yourself, you define the steps and fal handles the execution, passing outputs from one model as inputs to the next.

Unlike standard model calls that return a single result, workflows emit streaming events as each step progresses, giving you access to intermediate results along the way. This makes them ideal for multi-step generation tasks where you want real-time feedback. For more on consuming streaming responses, see [streaming inference](/documentation/model-apis/inference/streaming).

## Workflow as an API

Workflow APIs work the same way as other model endpoints, you can simply send a request and get a response back. However, it is common for workflows to contain multiple steps and produce intermediate results, as each step contains their own response that could be relevant in your use-case.

Therefore, workflows benefit from the **streaming** feature, which allows you to get partial results as they are being generated.

## Workflow events

The workflow API will trigger a few events during its execution, these events can be used to monitor the progress of the workflow and get intermediate results. Below are the events that you can expect from a workflow stream:

### The `submit` event

This event is triggered every time a new step has been submitted to execution. It contains the `app_id`, `request_id` and the `node_id`.

```json theme={null}
{
  "type": "submit",
  "node_id": "stable_diffusion_xl",
  "app_id": "fal-ai/fast-sdxl",
  "request_id": "d778bdf4-0275-47c2-9f23-16c27041cbeb"
}
```

### The `completion` event

This event is triggered upon the completion of a specific step.

```json theme={null}
{
  "type": "completion",
  "node_id": "stable_diffusion_xl",
  "output": {
    "images": [
      {
        "url": "https://fal.media/result.jpeg",
        "width": 1024,
        "height": 1024,
        "content_type": "image/jpeg"
      }
    ],
    "timings": { "inference": 2.1733 },
    "seed": 6252023,
    "has_nsfw_concepts": [false],
    "prompt": "a cute puppy"
  }
}
```

### The `output` event

The `output` event means that the workflow has completed and the final result is ready.

```json theme={null}
{
  "type": "output",
  "output": {
    "images": [
      {
        "url": "https://fal.media/result.jpeg",
        "width": 1024,
        "height": 1024,
        "content_type": "image/jpeg"
      }
    ]
  }
}
```

### The `error` event

The `error` event is triggered when an error occurs during the execution of a step. The `error` object contains the `error.status` with the HTTP status code, an error `message` as well as `error.body` with the underlying error serialized.

```json theme={null}
{
  "type": "error",
  "node_id": "stable_diffusion_xl",
  "message": "Error while fetching the result of the request d778bdf4-0275-47c2-9f23-16c27041cbeb",
  "error": {
    "status": 422,
    "body": {
      "detail": [
        {
          "loc": ["body", "num_images"],
          "msg": "ensure this value is less than or equal to 8",
          "type": "value_error.number.not_le",
          "ctx": { "limit_value": 8 }
        }
      ]
    }
  }
}
```

## Example

A cool and simple example of the power of workflows is `workflows/fal-ai/sdxl-sticker`, which consists of three steps:

<Steps>
  <Step>
    Generates an image using `fal-ai/fast-sdxl`.
  </Step>

  <Step>
    Remove the background of the image using `fal-ai/imageutils/rembg`.
  </Step>

  <Step>
    Converts the image to a sticker using `fal-ai/face-to-sticker`.
  </Step>
</Steps>

What could be a tedious process of running and coordinating three different models is now a single endpoint that you can call with a single request.

<Tabs>
  <Tab title="Javascript" icon="js">
    ```js theme={null}
    import { fal } from "@fal-ai/client";

    const stream = await fal.stream("workflows/fal-ai/sdxl-sticker", {
    input: {
      prompt: "a face of a cute puppy, in the style of pixar animation",
    },
    });

    for await (const event of stream) {
    console.log("partial", event);
    }

    const result = await stream.done();

    console.log("final result", result);
    ```
  </Tab>

  <Tab title="python" icon="python">
    ```python theme={null}
    import fal_client

    stream = fal_client.stream(
        "workflows/fal-ai/sdxl-sticker",
        arguments={
            "prompt": "a face of a cute puppy, in the style of pixar animation",
        },
    )
    for event in stream:
        print(event)
    ```
  </Tab>

  <Tab title="python (async)" icon="python">
    ```python theme={null}
    import asyncio
    import fal_client

    async def main():
        stream = await fal_client.stream_async(
            "workflows/fal-ai/sdxl-sticker",
            arguments={
                "prompt": "a face of a cute puppy, in the style of pixar animation",
            },
        )

        async for event in stream:
            print(event)


    if __name__ == "__main__":
        asyncio.run(main())
    ```
  </Tab>

  <Tab title="Swift" icon="swift">
    <Note>
      **Coming soon**

      The Swift client does not support streaming yet.
    </Note>
  </Tab>
</Tabs>

## Type definitions

Below are the type definition in TypeScript of events that you can expect from a workflow stream:

```ts theme={null}
type WorkflowBaseEvent = {
  type: "submit" | "completion" | "error" | "output";
  node_id: string;
};

export type WorkflowSubmitEvent = WorkflowBaseEvent & {
  type: "submit";
  app_id: string;
  request_id: string;
};

export type WorkflowCompletionEvent<Output = any> = WorkflowBaseEvent & {
  type: "completion";
  app_id: string;
  output: Output;
};

export type WorkflowDoneEvent<Output = any> = WorkflowBaseEvent & {
  type: "output";
  output: Output;
};

export type WorkflowErrorEvent = WorkflowBaseEvent & {
  type: "error";
  message: string;
  error: any;
};
```


# https://fal.ai/docs/documentation/organizations/access-controls.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Access Controls

> Restrict which models your team members can access via the API and Playground.

Model Access Controls let organization admins restrict which models team members can call. Use them to enforce compliance (only approved models), control costs (block expensive models), or limit usage to models that meet your security requirements. Access controls are configured from the [Access Controls dashboard](https://fal.ai/dashboard/access-controls).

Controls are enforced separately for two contexts. **API Access** controls whether a model can be called via the fal client SDKs or REST API. **UI Access** controls whether a model can be run from the Playground and Sandbox. This separation lets you allow models in the API for production use while blocking them from the Playground, or vice versa.

## Access Statuses

Each model can be set to one of three statuses:

| Status      | Behavior                                                                                 |
| ----------- | ---------------------------------------------------------------------------------------- |
| **Allowed** | Model can be used in the given context                                                   |
| **Blocked** | Model is blocked. API calls return an error; Playground shows an access control message. |
| **Inherit** | Uses the parent organization's setting (child teams only)                                |

<Note>
  Blocked models still appear in the Model Gallery and API documentation. Access controls only affect execution.
</Note>

## Organization Inheritance

When access controls are enabled, rules set at the org level flow down to all child teams by default. Child teams default to **Inherit** and follow the org's rules, but they can override specific models when they need different access.

```
Organization: FLUX.1 = Allowed
  ├── Team A: FLUX.1 = Inherit (uses org setting: Allowed)
  ├── Team B: FLUX.1 = Blocked (overrides org)
  └── Team C: FLUX.1 = Inherit (uses org setting: Allowed)
```

The dashboard shows which rules are inherited vs set at the team level.

## Enterprise Ready Models

fal designates certain models as "Enterprise Ready" based on licensing, compliance, and reliability criteria. By default, any model marked Enterprise Ready is automatically allowed and you only need to manage exceptions by blocking specific models you don't want.

For stricter control, you can switch to **Require Explicit Approval** mode where all models are blocked by default and must be individually approved, even Enterprise Ready ones.

<Warning>
  Switching to explicit approval may disrupt existing usage. Models that were previously auto-allowed will be blocked until explicitly approved.
</Warning>

You can opt in to receive email notifications when new models are designated as Enterprise Ready, so you can review and approve them promptly.

## What Happens When a Model Is Blocked

| Context        | Behavior                                                              |
| -------------- | --------------------------------------------------------------------- |
| **API call**   | Returns an error indicating the model is restricted for your account  |
| **Playground** | Model appears but execution is blocked with an access control message |
| **Sandbox**    | Model appears but cannot be included in comparison runs               |

<Note>
  Model Access Controls are available on enterprise plans. Contact [sales](https://fal.ai/enterprise#contact-sales) to enable this feature for your organization.
</Note>

<Card title="Managing Teams" icon="arrow-right" href="/documentation/organizations/managing-teams">
  Configure org-wide policies and member management
</Card>


# https://fal.ai/docs/documentation/organizations/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Organizations

> Centralized management for teams, billing, and model access across your company.

Organizations give enterprise customers a parent account that manages multiple [teams](/documentation/setting-up/teams) under a single umbrella. While standalone teams work well for small groups, organizations add centralized policies, SSO enforcement, cross-team billing visibility, and model access controls. Every team within an organization maintains its own API keys, secrets, deployed apps, and billing, but inherits policies set at the organization level.

If you are already using teams on fal and need centralized control over team creation, member management, or which models your teams can access, an organization is the next step. Organizations are available on enterprise plans. Contact [sales](https://fal.ai/enterprise#contact-sales) to get started.

## Organizations vs Teams

A team is a single group with its own API keys, secrets, apps, and billing. An organization is a parent account that manages multiple teams with shared policies.

```
Organization (root)
├── Team A (e.g., Research)
├── Team B (e.g., Production)
└── Team C (e.g., Platform)
```

Each child team operates independently for day-to-day work. The organization controls policies that apply across all teams, like who can create new teams, whether members need SSO, and which models are allowed.

## What Org Admins Can Do

Organization admins have centralized control over the full team lifecycle. They can create and archive teams, view and manage members across all teams (roles, assignments, invites), and configure policies that apply organization-wide. On the billing side, org admins can view invoices across all teams and set spending alerts. For security, they can enforce SSO for all team members and restrict which models teams can access via the API or Playground.

## Request Visibility

Organizations can enable **restricted request view** to limit team members to only seeing their own request payloads and logs. This is configured in the organization admin dashboard under "Restricted request view."

When enabled, the system tracks how each request was authenticated. When a team member views requests in the dashboard, they only see payloads for requests where their identity matches the request's authentication method.

<Warning>
  **Playground and API key submissions behave differently under restricted view:**

  * **Playground submissions** are authenticated with your personal login token. You can see your own Playground requests.
  * **API key submissions** are authenticated with the team's API key, not your personal identity. You cannot see API-submitted request payloads in the dashboard, even if you submitted them, because the API key identity does not match your personal login.

  If your team needs per-user request isolation for API submissions, contact support to discuss options.
</Warning>

## SSO Account Visibility

Organizations with SSO can restrict whether users can access their personal fal account alongside their SSO-linked team account. This ensures users only interact through the organization's managed teams. See [Managing Teams](/documentation/organizations/managing-teams) for configuration details.

## Next Steps

<CardGroup cols={2}>
  <Card title="Managing Teams" icon="arrow-right" href="/documentation/organizations/managing-teams">
    Team lifecycle, member management, and org-wide policies
  </Card>

  <Card title="Model Access Controls" icon="arrow-right" href="/documentation/organizations/access-controls">
    Restrict which models your teams can use
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/organizations/managing-teams.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Managing Teams

> Control team lifecycle, member management, and organization-wide policies.

Organization administrators manage teams and members from the [Organization dashboard](https://fal.ai/dashboard/organization). This page covers the day-to-day operations of running an organization: creating and archiving teams, managing members across teams, and configuring the policies that govern how teams operate.

For an overview of what organizations are and when you need one, see [Organizations](/documentation/organizations/index). For controlling which models teams can access, see [Model Access Controls](/documentation/organizations/access-controls).

## Team Lifecycle

Org admins can create new teams from the Organization dashboard. New teams are automatically associated with your organization and inherit org-wide policies. You can control whether child team admins are also allowed to create teams, or restrict team creation to org admins only.

When a team is no longer needed, org admins can archive it. Archived teams are locked and can no longer deploy apps, make API calls, or create compute instances. Existing deployed apps stop serving requests. To reverse an archive, contact the fal team.

<Warning>
  Archiving a team locks the account and stops all deployed apps from serving requests.
</Warning>

## Team Roles

Every team member has one of three roles. The role determines what they can access within the team.

| Role          | What they can do                                                                                                                                                                            |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Admin**     | Full team management: invite and remove members, manage API keys, configure scaling, set up [log drains](/documentation/serverless/observability/log-drains), and access all team settings. |
| **Developer** | Deploy and manage apps, view analytics, access logs, and use the API. This is the default role for new members.                                                                             |
| **Billing**   | View and manage billing: invoices, payment methods, spending alerts, and usage analytics. Cannot deploy apps or manage members.                                                             |

Admin and Billing roles can both access billing-related features. Only Admins can invite members, manage API keys, or configure log drains.

## Member Management

The Organization dashboard provides a unified view of all members across all teams. You can see which teams each member belongs to and their roles, filter by team or status (active, pending, unassigned), change roles or reassign members between teams, and onboard multiple members via CSV upload with team assignments.

Org admins can invite members to any team in the organization. You can also control whether child team admins are allowed to send invites themselves, or require all invitations to go through org admins.

<Tip>
  When SSO is configured, invites can require members to authenticate through your identity provider before joining.
</Tip>

## Organization Policies

These policies are configured from the Organization dashboard and apply across all child teams.

| Policy                     | What it controls                                                                                                                                                          |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Team Creation**          | Whether child team admins can create new teams, or only org admins can.                                                                                                   |
| **Invite Permissions**     | Whether child team admins can invite new members, or all invitations must go through org admins.                                                                          |
| **Cross-Team Visibility**  | Whether admins and billing managers can see analytics and usage across all teams, not just their own.                                                                     |
| **Request Visibility**     | Whether team members see all requests made by their team, or only their own. Useful for organizations handling sensitive data.                                            |
| **SSO Account Visibility** | Whether users can access their personal fal account alongside their SSO-linked team account. Disabling this ensures users only interact through the organization's teams. |

## Billing Across Teams

Each team in an organization maintains its own billing and subscription. Org admins with billing access can view invoices across all teams from the Organization dashboard, set spending alerts for any team, and monitor usage analytics across the organization (when cross-team visibility is enabled).

<Card title="Model Access Controls" icon="arrow-right" href="/documentation/organizations/access-controls">
  Control which models your teams can access
</Card>


# https://fal.ai/docs/documentation/quickstart.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Get started with fal in minutes

fal gives you two ways to work with AI models. If you want to generate images, video, audio, or other media, the [Model APIs](/documentation/model-apis/overview) let you call 1,000+ production-ready models with a single API call. If you have your own model to deploy, [Serverless](/documentation/serverless) gives you the full lifecycle: develop, test, deploy, and scale on the same infrastructure that powers the [marketplace](https://fal.ai/models).

Both paths start with an [API key](/documentation/model-apis/authentication) and take a few minutes. The "consume" path is for calling existing models through fal's [client libraries](/documentation/model-apis/inference/client-setup) or HTTP. The "deploy" path is for teams bringing their own models to run on fal's GPU infrastructure, using the same [fal.App](/documentation/development/app-setup) framework that powers every model on the platform.

<Tabs>
  <Tab title="I want to consume a model">
    ### What do you want to build?

    <CardGroup cols={2}>
      <Card title="Generate Images" icon="image" href="/examples/image-generation/generate-images-from-text">
        Create images from text prompts with FLUX, Nano Banana 2, and more
      </Card>

      <Card title="Generate Videos" icon="video" href="/examples/video-generation/generate-videos-from-image">
        Transform images into videos with Kling 3.0, Sora 2, and other models
      </Card>

      <Card title="Transcribe Audio" icon="microphone" href="/examples/audio-speech/convert-speech-to-text">
        Convert speech to text with Whisper
      </Card>

      <Card title="Use LLMs" icon="message-bot" href="/examples/integrations/use-llms">
        Build with Llama, Mistral, and other large language models
      </Card>

      <Card title="Fast FLUX" icon="bolt" href="/examples/image-generation/fast-flux">
        Ultra-fast image generation with optimized FLUX
      </Card>

      <Card title="Build a Workflow UI" icon="window" href="/examples/integrations/custom-workflow-ui">
        Create interfaces for complex AI workflows
      </Card>

      <Card title="Next.js Integration" icon="code" href="/examples/integrations/nextjs">
        Build full-stack AI apps with Next.js and fal
      </Card>

      <Card title="Vercel Integration" icon="cloud" href="/examples/integrations/vercel">
        Deploy AI-powered apps on Vercel with fal
      </Card>

      <Card title="n8n Integration" icon="diagram-project" href="/examples/integrations/n8n">
        Automate workflows by connecting fal models to n8n
      </Card>
    </CardGroup>

    ### Quick example

    Generate your first image in under a minute.

    <Steps>
      <Step title="Install the client">
        <CodeGroup>
          ```bash Python theme={null}
          pip install fal-client
          ```

          ```bash JavaScript theme={null}
          npm install @fal-ai/client
          ```
        </CodeGroup>
      </Step>

      <Step title="Set your API key">
        Get a key from the [fal dashboard](https://fal.ai/dashboard/keys) and set it as an environment variable:

        ```bash theme={null}
        export FAL_KEY="your-api-key-here"
        ```
      </Step>

      <Step title="Generate an image">
        <CodeGroup>
          ```python Python theme={null}
          import fal_client

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

          ```javascript JavaScript theme={null}
          import { fal } from "@fal-ai/client";

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

          ```bash cURL theme={null}
          curl -X POST "https://queue.fal.run/fal-ai/flux/schnell" \
            -H "Authorization: Key $FAL_KEY" \
            -H "Content-Type: application/json" \
            -d '{"prompt": "a futuristic cityscape at sunset"}'
          ```
        </CodeGroup>
      </Step>
    </Steps>
  </Tab>

  <Tab title="I want to deploy a model">
    ### What do you want to deploy?

    <CardGroup cols={2}>
      <Card title="Text-to-Image Model" icon="image" href="/examples/image-generation/deploy-text-to-image-model">
        Deploy Sana, FLUX, or your custom image generation model
      </Card>

      <Card title="Text-to-Video Model" icon="video" href="/examples/video-generation/deploy-text-to-video-model">
        Deploy WAN or other video generation models
      </Card>

      <Card title="Text-to-Speech Model" icon="volume-high" href="/examples/audio-speech/deploy-text-to-speech-model">
        Deploy Kokoro or custom voice synthesis models
      </Card>

      <Card title="Text-to-Music Model" icon="music" href="/examples/audio-speech/deploy-text-to-music-model">
        Deploy DiffRhythm or music generation models
      </Card>

      <Card title="ComfyUI Server" icon="server" href="/examples/image-generation/deploy-comfyui-server">
        Run ComfyUI workflows as a serverless API
      </Card>

      <Card title="LoRA Training" icon="sliders" href="/examples/image-generation/deploy-wan-lora-training">
        Fine-tune WAN video generation with LoRA training
      </Card>

      <Card title="Multi-GPU Inference" icon="microchip" href="/examples/video-generation/deploy-multi-gpu-inference">
        Scale generation across multiple GPUs with streaming
      </Card>

      <Card title="3D Progressive Rendering" icon="cube" href="/examples/video-generation/deploy-3d-progressive-rendering">
        Stream real-time text-to-3D reconstruction
      </Card>

      <Card title="Real-time Video-to-Video" icon="video" href="/examples/video-generation/deploy-realtime-video-to-video-model">
        Run real-time video-to-video with object detection
      </Card>

      <Card title="Real-time World Model" icon="globe" href="/examples/video-generation/deploy-realtime-world-model">
        Deploy a real-time world model powered by Matrix-Game
      </Card>

      <Card title="Custom Container" icon="docker" href="/examples/deploy-models-with-custom-containers">
        Deploy any model with custom Docker containers
      </Card>
    </CardGroup>

    ### Migrating from another platform?

    <CardGroup cols={2}>
      <Card title="Migrate from Replicate" icon="arrow-right" href="/examples/integrations/migrate-from-replicate">
        Move your Replicate models to fal
      </Card>

      <Card title="Migrate from Modal" icon="arrow-right" href="/examples/integrations/migrate-from-modal">
        Move your Modal apps to fal
      </Card>

      <Card title="Migrate from RunPod" icon="arrow-right" href="/examples/integrations/migrate-from-runpod">
        Move your RunPod Serverless workers to fal
      </Card>

      <Card title="Migrate Docker Server" icon="arrow-right" href="/examples/integrations/migrate-external-docker-server">
        Move your existing Docker-based inference server to fal
      </Card>
    </CardGroup>

    ### Quick example

    Deploy your first app in under 2 minutes.

    <Steps>
      <Step title="Install the CLI and authenticate">
        ```bash theme={null}
        pip install fal
        fal auth login
        ```
      </Step>

      <Step title="Create your app">
        Create a file called `my_app.py`:

        ```python my_app.py theme={null}
        import fal

        class MyApp(fal.App):
            @fal.endpoint("/")
            def run(self, prompt: str) -> dict:
                return {"message": f"Hello from fal! You said: {prompt}"}
        ```
      </Step>

      <Step title="Test on cloud GPUs">
        ```bash theme={null}
        fal run my_app.py::MyApp
        ```
      </Step>

      <Step title="Deploy to production">
        ```bash theme={null}
        fal deploy my_app.py::MyApp
        ```
      </Step>
    </Steps>

    <Card title="Deploy a real model" icon="rocket" href="/documentation/development/getting-started/deploy-your-first-image-generator">
      Step-by-step guide to deploying an image generation model
    </Card>
  </Tab>
</Tabs>

***

## Next Steps

<CardGroup cols={3}>
  <Card title="Get Your API Key" icon="key" href="/documentation/model-apis/authentication">
    Create an API key to authenticate your requests
  </Card>

  <Card title="AI Tools" icon="message-bot" href="/documentation/model-apis/mcp">
    Use AI coding assistants to build with fal faster
  </Card>

  <Card title="Explore Models" icon="cube" href="https://fal.ai/models">
    Browse 1,000+ available models
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/distributed/api-reference.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Essential API reference for fal.distributed: the key methods you need to build multi-GPU applications

This page covers the essential APIs for building multi-GPU applications with `fal.distributed`. We focus on the methods you'll actually use in your code.

## DistributedRunner

The `DistributedRunner` class orchestrates multiple GPU workers for distributed computation. It handles process management, inter-process communication via ZMQ, and coordination between worker processes.

### Constructor

```python theme={null}
DistributedRunner(
    worker_cls: type[DistributedWorker],
    world_size: int,
)
```

**Parameters:**

* **`worker_cls`** (`type[DistributedWorker]`): Your custom worker class that inherits from `DistributedWorker`.
* **`world_size`** (`int`): Total number of worker processes to spawn (typically equals `num_gpus`).

**Example:**

```python theme={null}
from fal.distributed import DistributedRunner, DistributedWorker

class MyWorker(DistributedWorker):
    def setup(self, **kwargs):
        self.model = load_model().to(self.device)
    
    def __call__(self, prompt: str, **kwargs):
        return self.model.generate(prompt)

# Create runner for 4 GPUs
runner = DistributedRunner(
    worker_cls=MyWorker,
    world_size=4,
)
```

***

### start()

Starts all distributed worker processes and initializes them.

```python theme={null}
async def start(
    self,
    timeout: int = 1800,
    **kwargs: Any
) -> None
```

**Parameters:**

* **`timeout`** (`int`): Maximum time (in seconds) to wait for all workers to be ready. Default: `1800` (30 minutes).
* **`**kwargs`**: Additional keyword arguments passed to each worker's `setup()` method.

**Raises:**

* `RuntimeError`: If processes are already running or fail to start.
* `TimeoutError`: If workers don't become ready within the timeout period.

**Example:**

```python theme={null}
class MyApp(fal.App):
    num_gpus = 2
    
    async def setup(self):
        self.runner = DistributedRunner(
            worker_cls=MyWorker,
            world_size=self.num_gpus,
        )
        
        # Start workers and pass model path to their setup()
        await self.runner.start(model_path="/data/models/flux")
        
        # Workers are now ready to process requests
```

**What it does:**

1. Spawns `world_size` worker processes (one per GPU)
2. Each worker runs its `setup()` method with the provided `**kwargs`
3. Waits for all workers to signal "READY"
4. Starts the keepalive timer if configured
5. Returns when all workers are initialized and ready

<Note>
  This method must be called before using `invoke()` or `stream()`. It's typically called once in your app's `setup()` method.
</Note>

***

### invoke()

Executes the worker's `__call__()` method across all GPUs and returns the final result from rank 0.

```python theme={null}
async def invoke(
    self,
    payload: dict[str, Any] = {},
    timeout: int | None = None,
) -> Any
```

**Parameters:**

* **`payload`** (`dict[str, Any]`): Dictionary of arguments to pass to each worker's `__call__()` method. Default: `{}`.
* **`timeout`** (`int | None`): Maximum time (in seconds) to wait for the result. If `None`, uses the runner's default timeout. Default: `None`.

**Returns:**

* `Any`: The result returned by rank 0 worker's `__call__()` method.

**Raises:**

* `RuntimeError`: If workers are not running or encounter an error during execution.
* `TimeoutError`: If the operation exceeds the timeout.

**Example:**

```python theme={null}
@fal.endpoint("/generate")
async def generate(self, request: GenerateRequest) -> GenerateResponse:
    # Invoke workers to generate images
    result = await self.runner.invoke({
        "prompt": request.prompt,
        "num_steps": request.num_steps,
        "width": 1024,
        "height": 1024,
    })
    
    return GenerateResponse(image=result["image"])
```

**How it works:**

1. Serializes the payload and sends it to all workers
2. Each worker executes its `__call__()` method with `streaming=False`
3. Workers coordinate using PyTorch distributed operations (e.g., `dist.gather()`)
4. Only rank 0 returns the result
5. Result is deserialized and returned to the caller

<Tip>
  Use `invoke()` for standard (non-streaming) requests where you need the final result only.
</Tip>

***

### stream()

Streams intermediate results from workers during execution, useful for long-running operations like image generation or training.

```python theme={null}
async def stream(
    self,
    payload: dict[str, Any] = {},
    timeout: int | None = None,
    streaming_timeout: int | None = None,
    as_text_events: bool = False,
) -> AsyncIterator[Any]
```

**Parameters:**

* **`payload`** (`dict[str, Any]`): Dictionary of arguments to pass to each worker's `__call__()` method. Default: `{}`.
* **`timeout`** (`int | None`): Maximum total time (in seconds) for the entire operation. Default: `None` (no limit).
* **`streaming_timeout`** (`int | None`): Maximum time (in seconds) between consecutive yields. If no data is received within this period, raises `TimeoutError`. Default: `None`.
* **`as_text_events`** (`bool`): If `True`, yields Server-Sent Events (SSE) formatted as bytes. If `False`, yields deserialized Python objects. Default: `False`.

**Returns:**

* `AsyncIterator[Any]`: Async iterator yielding intermediate results and the final result.

**Raises:**

* `RuntimeError`: If workers are not running, encounter an error, or yield no data.
* `TimeoutError`: If the operation exceeds timeout or streaming\_timeout.

**Example:**

```python theme={null}
@fal.endpoint("/stream")
async def stream_generate(self, request: GenerateRequest) -> StreamingResponse:
    return StreamingResponse(
        self.runner.stream(
            payload={
                "prompt": request.prompt,
                "num_steps": request.num_steps,
            },
            as_text_events=True,
        ),
        media_type="text/event-stream",
    )
```

**How it works:**

1. Serializes the payload and sends it to all workers
2. Each worker executes its `__call__()` method with `streaming=True`
3. Workers can call `self.add_streaming_result()` to send intermediate updates
4. The runner yields each intermediate result as it's received
5. After workers finish, yields the final result
6. Automatically handles serialization based on `as_text_events`

<Tip>
  Set `as_text_events=True` when using with `StreamingResponse` for browser-compatible Server-Sent Events.
</Tip>

***

## DistributedWorker

The `DistributedWorker` class is the base class for your custom GPU workers. Each instance runs on a separate GPU and handles model loading, inference, or training.

Create your own worker by inheriting from `DistributedWorker` and overriding the `setup()` and `__call__()` methods.

```python theme={null}
class MyWorker(DistributedWorker):
    def setup(self, **kwargs):
        # Load model on this GPU
        self.model = load_model().to(self.device)
    
    def __call__(self, prompt: str, **kwargs):
        # Process request
        return self.model.generate(prompt)
```

***

### Properties

#### device

Returns the CUDA device assigned to this worker.

```python theme={null}
@property
def device(self) -> torch.device
```

**Returns:**

* `torch.device`: The PyTorch device for this worker, e.g., `cuda:0`, `cuda:1`, etc.

**Example:**

```python theme={null}
class MyWorker(DistributedWorker):
    def setup(self):
        # Load model on this worker's GPU
        self.model = MyModel().to(self.device)
        print(f"Model loaded on {self.device}")
```

***

#### rank

The rank (ID) of this worker, from 0 to world\_size-1.

```python theme={null}
self.rank: int
```

**Example:**

```python theme={null}
if self.rank == 0:
    print("I'm the master worker!")
    # Only rank 0 saves checkpoints, uploads files, etc.
```

***

#### world\_size

Total number of workers in the distributed setup.

```python theme={null}
self.world_size: int
```

**Example:**

```python theme={null}
print(f"Running with {self.world_size} GPUs")
```

***

### Methods to Override

#### setup()

Called once when the worker is initialized. Use this to load models, download weights, and prepare resources.

```python theme={null}
def setup(self, **kwargs: Any) -> None
```

**Parameters:**

* **`**kwargs`**: Any keyword arguments passed to `runner.start()`.

**Example:**

```python theme={null}
class FluxWorker(DistributedWorker):
    def setup(self, model_path: str = "/data/flux", **kwargs):
        """Initialize the Flux model on this GPU"""
        import torch
        from diffusers import FluxPipeline
        
        self.rank_print(f"Loading Flux on {self.device}")
        
        self.pipeline = FluxPipeline.from_pretrained(
            model_path,
            torch_dtype=torch.bfloat16,
        ).to(self.device)
        
        # Disable progress bar for non-main workers
        if self.rank != 0:
            self.pipeline.set_progress_bar_config(disable=True)
        
        self.rank_print("Model loaded successfully")
```

<Tip>
  Heavy operations like model loading should go in `setup()`, not `__call__()`, so they only happen once per worker.
</Tip>

***

#### **call**()

Called for each request. Implement your main processing logic here.

```python theme={null}
def __call__(self, streaming: bool = False, **kwargs: Any) -> Any
```

**Parameters:**

* **`streaming`** (`bool`): `True` if called via `runner.stream()`, `False` if called via `runner.invoke()`.
* **`**kwargs`**: Arguments from the `payload` dict passed to `runner.invoke()` or `runner.stream()`.

**Returns:**

* `Any`: The result to return. Only rank 0's return value is sent back to the caller.

**Example:**

```python theme={null}
class FluxWorker(DistributedWorker):
    def __call__(
        self,
        prompt: str,
        num_steps: int = 20,
        streaming: bool = False,
        **kwargs
    ) -> dict:
        """Generate an image on this GPU"""
        import torch.distributed as dist
        
        # Each GPU generates independently
        image = self.pipeline(
            prompt=prompt,
            num_inference_steps=num_steps,
            output_type="pt",
        ).images[0]
        
        # Gather all images to rank 0
        if self.rank == 0:
            gather_list = [
                torch.zeros_like(image, device=self.device)
                for _ in range(self.world_size)
            ]
        else:
            gather_list = None
        
        dist.gather(image, gather_list, dst=0)
        
        # Only rank 0 returns the result
        if self.rank == 0:
            combined_image = create_grid(gather_list)
            return {"image": combined_image}
        
        return {}  # Other ranks return empty dict
```

***

### Utility Methods

#### add\_streaming\_result()

Sends an intermediate result to the client during streaming.

```python theme={null}
def add_streaming_result(
    self,
    result: Any,
    image_format: str = "jpeg",
    as_text_event: bool = False,
) -> None
```

**Parameters:**

* **`result`** (`Any`): The data to stream. Can be a dict, PIL image, or any serializable object.
* **`image_format`** (`str`): Image format for PIL images (`"jpeg"` or `"png"`). Default: `"jpeg"`.
* **`as_text_event`** (`bool`): If `True`, formats as Server-Sent Event. Must match the `as_text_events` parameter in `runner.stream()`. Default: `False`.

**Example:**

```python theme={null}
def __call__(self, prompt: str, num_steps: int = 20, streaming: bool = False):
    for step in range(num_steps):
        # Generate intermediate result
        latent = self.model.step(prompt)
        
        # Stream progress (only rank 0)
        if streaming and self.rank == 0 and step % 5 == 0:
            preview_image = self.decode_latent(latent)
            self.add_streaming_result({
                "step": step,
                "progress": (step + 1) / num_steps,
                "preview": preview_image,
            }, as_text_event=True)
    
    # Return final result
    return {"image": final_image}
```

<Note>
  Only call `add_streaming_result()` from rank 0 to avoid duplicate messages to the client.
</Note>

***

#### rank\_print()

Prints a message with the worker's rank prefix for easy debugging.

```python theme={null}
def rank_print(self, message: str, debug: bool = False) -> None
```

**Parameters:**

* **`message`** (`str`): The message to print.
* **`debug`** (`bool`): If `True`, prefixes with `[debug]`. Default: `False`.

**Example:**

```python theme={null}
self.rank_print("Starting generation...")
# Output: [rank 0] Starting generation...

self.rank_print("Model loaded", debug=True)
# Output: [debug] [rank 0] Model loaded
```

***

## Common Patterns

### Pattern 1: Data Parallelism (Inference)

Each GPU processes different data independently:

```python theme={null}
class ParallelWorker(DistributedWorker):
    def __call__(self, prompt: str, **kwargs):
        import torch.distributed as dist
        
        # Each GPU generates independently with different seed
        result = self.model.generate(prompt)
        
        # Gather all results to rank 0
        if self.rank == 0:
            gather_list = [torch.zeros_like(result) for _ in range(self.world_size)]
        else:
            gather_list = None
        
        dist.gather(result, gather_list, dst=0)
        
        # Only rank 0 returns combined result
        if self.rank == 0:
            return {"outputs": gather_list}
        return {}
```

***

### Pattern 2: Distributed Data Parallel (Training)

All GPUs have the same model, process different batches, and sync gradients:

```python theme={null}
class DDPWorker(DistributedWorker):
    def setup(self, **kwargs):
        from torch.nn.parallel import DistributedDataParallel as DDP
        
        self.model = MyModel().to(self.device)
        
        # Wrap with DDP for gradient synchronization
        self.model = DDP(
            self.model,
            device_ids=[self.rank],
            output_device=self.rank,
        )
        
        self.optimizer = torch.optim.Adam(self.model.parameters())
    
    def __call__(self, data_path: str, **kwargs):
        import torch.distributed as dist
        
        # Load and distribute data
        if self.rank == 0:
            data = load_data(data_path)
        else:
            data = None
        
        # Broadcast to all ranks
        data = dist.broadcast_object_list([data], src=0)[0]
        
        # Each GPU processes different batch
        local_batch = data[self.rank::self.world_size]
        
        # Training loop
        for batch in local_batch:
            loss = self.model(batch)
            loss.backward()  # DDP syncs gradients automatically
            self.optimizer.step()
            self.optimizer.zero_grad()
        
        # Only rank 0 saves checkpoint
        if self.rank == 0:
            torch.save(self.model.state_dict(), "checkpoint.pt")
            return {"checkpoint": "checkpoint.pt"}
        
        return {}
```

***

### Pattern 3: Streaming with Progress Updates

Stream intermediate results during long-running operations:

```python theme={null}
class StreamingWorker(DistributedWorker):
    def __call__(self, prompt: str, steps: int = 50, streaming: bool = False):
        import torch.distributed as dist
        
        for step in range(steps):
            result = self.model.step(prompt)
            
            # Stream progress every 5 steps
            if streaming and self.rank == 0 and step % 5 == 0:
                self.add_streaming_result({
                    "step": step,
                    "progress": step / steps,
                }, as_text_event=True)
            
            # Sync all workers
            dist.barrier()
        
        # Return final result
        if self.rank == 0:
            return {"output": result}
        return {}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Multi-GPU Inference Tutorial" icon="bolt" href="/serverless/tutorials/deploy-multi-gpu-inference">
    Complete example with data parallelism
  </Card>

  <Card title="Multi-GPU Training Tutorial" icon="graduation-cap" href="/serverless/tutorials/deploy-multi-gpu-training">
    Complete example with DDP training
  </Card>

  <Card title="Event Streaming" icon="signal-stream" href="/serverless/distributed/streaming">
    Learn about streaming intermediate results
  </Card>

  <Card title="Overview" icon="book" href="/serverless/distributed/overview">
    High-level overview of multi-GPU workloads
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/distributed/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Learn how to leverage multiple GPUs for faster inference and training with fal.distributed

The `fal.distributed` module enables you to scale your AI workloads across multiple GPUs, dramatically improving performance for both inference and training tasks. Whether you need to generate multiple images simultaneously or train large models faster, distributed computing on fal makes it straightforward.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=1111&end=1195&autoplay=1'><img src='/docs/images/video-thumbs/distributed-overview.jpg' alt='Multi-GPU Support - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Why Use Multiple GPUs?

### For Inference

* **Higher Throughput**: Generate multiple outputs simultaneously (e.g., 4 images at once on 4 GPUs)
* **Faster Single Output**: Split large models across GPUs for faster generation
* **Cost Efficiency**: Maximize GPU utilization for batch processing

### For Training

* **Faster Training**: Distribute training across multiple GPUs with synchronized gradient updates
* **Larger Batches**: Train with bigger batch sizes for better model convergence
* **Parallel Preprocessing**: Speed up data preprocessing by distributing it across GPUs

## Core Concepts

### Architecture Overview

Here's how the distributed computing components work together:

```mermaid theme={null}
flowchart TB
    App["fal.App<br/>Your Application<br/>• Defines num_gpus<br/>• Creates DistributedRunner"]
    Runner["DistributedRunner<br/>Orchestration Layer<br/>• Spawns worker processes<br/>• Manages communication (ZMQ)<br/>• Coordinates execution"]
    
    subgraph GPU0["GPU 0"]
        Worker0["DistributedWorker<br/>(Rank 0)<br/>• self.device = cuda:0<br/>• setup(): Load model<br/>• __call__(): Process data"]
    end
    
    subgraph GPU1["GPU 1"]
        Worker1["DistributedWorker<br/>(Rank 1)<br/>• self.device = cuda:1<br/>• setup(): Load model<br/>• __call__(): Process data"]
    end
    
    subgraph GPU2["GPU N-1"]
        WorkerN["DistributedWorker<br/>(Rank N-1)<br/>• self.device = cuda:N-1<br/>• setup(): Load model<br/>• __call__(): Process data"]
    end
    
    App --> Runner
    Runner --> Worker0
    Runner --> Worker1
    Runner -.-> WorkerN
    
    style App fill:#e1d7f9
    style Runner fill:#f0e7ff
    style Worker0 fill:#d4f1f4
    style Worker1 fill:#d4f1f4
    style WorkerN fill:#d4f1f4
```

### DistributedRunner

The `DistributedRunner` is the main orchestration class that manages multi-GPU workloads. It handles process management, inter-process communication via ZMQ, and coordination between worker processes.

#### Key Methods

**`DistributedRunner(worker_cls, world_size)`**
Creates a runner that will spawn `world_size` instances of your `worker_cls`.

**`await runner.start(**kwargs)`**
Launches all worker processes and calls their `setup()` method. Any `**kwargs` are passed to each worker's setup. Call this once in your app's `setup()`.

**`await runner.invoke(payload)`**
Executes your worker's `__call__()` method with the given payload dict and returns the final result. Use this for standard (non-streaming) requests.

**`runner.stream(payload, as_text_events=True)`**
Returns an async iterator that streams intermediate results from workers. Use this with `StreamingResponse` for real-time progress updates.

#### Example Usage

```python theme={null}
from fal.distributed import DistributedRunner, DistributedWorker

class MyWorker(DistributedWorker):
    def setup(self, model_path):
        # Load model on this GPU (called once per worker)
        self.model = load_model(model_path).to(self.device)
    
    def __call__(self, prompt, **kwargs):
        # Process request (called for each request)
        return self.model.generate(prompt)

class MyApp(fal.App):
    num_gpus = 4  # Use 4 GPUs
    
    async def setup(self):
        # Create and start the runner
        self.runner = DistributedRunner(
            worker_cls=MyWorker,
            world_size=self.num_gpus
        )
        await self.runner.start(model_path="/data/model")
    
    @fal.endpoint("/")
    async def run(self, request: MyRequest):
        # Invoke workers for each request
        result = await self.runner.invoke({
            "prompt": request.prompt,
        })
        return result
```

<Info>
  For complete API documentation with all parameters and examples, see the [DistributedRunner API Reference](/serverless/distributed/api-reference#distributedrunner).
</Info>

### DistributedWorker

Your custom worker class extends `DistributedWorker` and runs on each GPU. Each worker is independent and has its own copy of the model.

#### Methods to Override

**`def setup(self, **kwargs)`**
Called once when the worker initializes. Load your model, download weights, and prepare resources here. Receives any `**kwargs` passed to `runner.start()`.

**`def __call__(self, streaming=False, **kwargs)`**
Called for each request. Implement your inference or training logic here. Receives the payload dict from `runner.invoke()` or `runner.stream()` as `**kwargs`.

#### Properties You'll Use

**`self.device`** - The PyTorch CUDA device for this worker (`cuda:0`, `cuda:1`, etc.)

**`self.rank`** - The worker's rank (0 to world\_size-1). Rank 0 is typically responsible for returning results.

**`self.world_size`** - Total number of workers (GPUs).

#### Utility Methods

**`self.add_streaming_result(data, as_text_event=True)`**
Sends intermediate results to the client during streaming. Only call from rank 0 to avoid duplicates.

**`self.rank_print(message)`**
Prints a message with the worker's rank prefix for easier debugging.

<Info>
  For complete API documentation with detailed examples, see the [DistributedWorker API Reference](/serverless/distributed/api-reference#distributedworker).
</Info>

### PyTorch Distributed Primitives

For training and coordinated inference, you can use PyTorch's distributed primitives:

```python theme={null}
import torch.distributed as dist

# Gather results from all GPUs to rank 0
dist.gather(tensor, gather_list if self.rank == 0 else None, dst=0)

# Broadcast data from rank 0 to all GPUs
dist.broadcast(tensor, src=0)

# Synchronize all GPUs at a barrier
dist.barrier()
```

## Parallelism Strategies

### Inference Strategies

Different parallelism strategies optimize for different inference scenarios. Choose based on your use case and model architecture.

<CardGroup cols={2}>
  <Card title="Data Parallelism" icon="layer-group">
    Each GPU runs an independent model copy with different inputs. Best for high throughput scenarios where you need to generate multiple outputs simultaneously.

    **Use for:** Batch processing, generating multiple image variations, high throughput workloads\
    **Example:** Parallel SDXL in fal-demos
  </Card>

  <Card title="Pipeline Parallelism (PipeFusion)" icon="diagram-project">
    Split the model into sequential stages across GPUs, processing like an assembly line where each GPU handles specific layers. Reduces latency for single outputs.

    **Use for:** Large DiT models (SD3, FLUX), reducing latency for single image generation\
    **Example:** xFuser's PipeFusion implementation for DiT models
  </Card>

  <Card title="Tensor Parallelism" icon="grid">
    Split individual layers and tensors across GPUs, computing portions of each layer in parallel. Required when models are too large to fit on a single GPU.

    **Use for:** Extremely large models that don't fit on single GPU memory\
    **Example:** Large language models, very large diffusion models
  </Card>

  <Card title="Sequence Parallelism (Ulysses)" icon="timeline">
    Split attention computation across the sequence or spatial dimensions. Particularly effective for long sequences and can be combined with other strategies.

    **Use for:** Very long sequences, high-resolution images, combining with PipeFusion\
    **Example:** xFuser's Ulysses implementation
  </Card>

  <Card title="CFG Parallelism" icon="split">
    Parallel conditional and unconditional passes for classifier-free guidance. Runs both guidance passes simultaneously on separate GPUs.

    **Use for:** U-Net models (SDXL), requires exactly 2 GPUs\
    **Example:** xFuser supports this for U-Net architectures
  </Card>

  <Card title="Hybrid Strategies" icon="sitemap">
    Combine multiple approaches (e.g., PipeFusion + Ulysses + CFG) for maximum scaling efficiency across many GPUs.

    **Use for:** Maximum scaling across 4-8+ GPUs, complex production workloads\
    **Example:** xFuser configurations for 8 GPU setups
  </Card>
</CardGroup>

### Training Strategies

Multi-GPU training strategies focus on distributing the computational and memory requirements of training large models.

<CardGroup cols={2}>
  <Card title="Distributed Data Parallel (DDP)" icon="server">
    Each GPU has a full model copy and processes different data batches. Gradients are synchronized across all GPUs after each backward pass, ensuring all models stay identical.

    **Use for:** Standard multi-GPU training, best scaling for most use cases\
    **Example:** Flux LoRA training in fal-demos
  </Card>

  <Card title="Pipeline Parallelism" icon="pipe">
    Split model into stages and process microbatches through the pipeline. Requires careful load balancing to avoid GPU idle time (bubble overhead).

    **Use for:** Very large models, when combined with other parallelism strategies\
    **Example:** GPT-3 style training
  </Card>

  <Card title="Tensor Parallelism" icon="cubes">
    Split model layers across GPUs using Megatron-LM style parallelization. Each layer's computation is distributed across multiple GPUs.

    **Use for:** Models too large for single GPU even with gradient checkpointing\
    **Example:** Large transformer training
  </Card>

  <Card title="FSDP/ZeRO" icon="memory">
    Fully Sharded Data Parallel (FSDP) or ZeRO optimizer shard optimizer states, gradients, and parameters across GPUs to reduce memory footprint per GPU.

    **Use for:** Training very large models with memory constraints, scaling beyond DDP\
    **Example:** Large model training (70B+ parameters)
  </Card>
</CardGroup>

<Note>
  Many production workloads benefit from hybrid strategies. For example, xFuser can combine PipeFusion + Ulysses + CFG parallelism to scale across 8+ GPUs efficiently.
</Note>

## Configuration

### Specifying GPU Count

```python theme={null}
class MyApp(fal.App):
    num_gpus = 8  # Request 8 GPUs
    machine_type = "GPU-H100"  # Each GPU will be an H100
```

### Multi-GPU Machine Types

fal supports various multi-GPU configurations:

* `GPU-H100` with `num_gpus=2`: 2x H100 GPUs
* `GPU-H100` with `num_gpus=4`: 4x H100 GPUs
* `GPU-H100` with `num_gpus=8`: 8x H100 GPUs
* `GPU-A100` with `num_gpus=2/4/8`: 2-8x A100 GPUs

## Examples

All examples are available in the [fal-demos repository](https://github.com/fal-ai-community/fal-demos/tree/main/fal_demos/distributed):

* **Parallel SDXL**: Data parallelism for image generation ([code](https://github.com/fal-ai-community/fal-demos/blob/main/fal_demos/distributed/inference/parallel_sdxl/app.py))
* **xFuser**: Model parallelism with DiT models ([code](https://github.com/fal-ai-community/fal-demos/blob/main/fal_demos/distributed/inference/xfuser/app.py))
* **Flux LoRA Training**: Complete DDP training pipeline ([code](https://github.com/fal-ai-community/fal-demos/tree/main/fal_demos/distributed/training/flux_lora))

## Next Steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="book" href="/serverless/distributed/api-reference">
    Complete API documentation for DistributedRunner and DistributedWorker
  </Card>

  <Card title="Multi-GPU Inference Tutorial" icon="bolt" href="/serverless/tutorials/deploy-multi-gpu-inference">
    Step-by-step guide with parallel SDXL
  </Card>

  <Card title="Multi-GPU Training Tutorial" icon="graduation-cap" href="/serverless/tutorials/deploy-multi-gpu-training">
    Build a distributed Flux LoRA training service
  </Card>

  <Card title="Event Streaming" icon="signal-stream" href="/serverless/distributed/streaming">
    Stream intermediate results from workers
  </Card>
</CardGroup>

## Additional Resources

* [fal-demos distributed examples](https://github.com/fal-ai-community/fal-demos/tree/main/fal_demos/distributed) - Complete working code
* [Python SDK Reference](/serverless/python/api-reference) - Full Python API
* [App Lifecycle](/documentation/development/app-lifecycle) - How apps are structured and how runners start up and shut down


# https://fal.ai/docs/documentation/serverless/distributed/streaming.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Event Streaming

> Learn how to stream real-time results during distributed inference and training

Streaming allows you to send intermediate results from your distributed workers back to the client in real-time. This is particularly useful for long-running operations like image generation, video creation, or model training where users benefit from seeing progress updates.

<Note>
  For a complete working example of streaming with multi-GPU inference, see the [Parallel SDXL Tutorial](/serverless/tutorials/deploy-multi-gpu-inference).
</Note>

## How Streaming Works

With `fal.distributed`, you can stream results from workers during execution:

```mermaid theme={null}
flowchart LR
    Client["Client<br/>(Browser/API)"]
    App["fal.App<br/>Endpoint"]
    Runner["DistributedRunner"]
    
    subgraph Workers["Multiple GPUs"]
        W0["Worker 0<br/>add_streaming_result()"]
        W1["Worker 1<br/>add_streaming_result()"]
    end
    
    Client -->|"Request"| App
    App --> Runner
    Runner --> W0
    Runner --> W1
    W0 -.->|"Stream events"| Runner
    W1 -.->|"Stream events"| Runner
    Runner -.->|"Stream events"| App
    App -.->|"Server-Sent Events"| Client
    
    style Client fill:#e1d7f9
    style App fill:#f0e7ff
    style Runner fill:#f0e7ff
    style W0 fill:#d4f1f4
    style W1 fill:#d4f1f4
```

## Basic Streaming Example

### 1. Stream from Workers

In your `DistributedWorker`, use `add_streaming_result()` to send intermediate results:

```python theme={null}
from fal.distributed import DistributedWorker
import torch.distributed as dist

class StreamingWorker(DistributedWorker):
    def __call__(self, prompt: str, steps: int = 20):
        for step in range(steps):
            # Do some processing
            result = self.model.step(prompt)
            
            # Only rank 0 streams to avoid duplicates
            if self.rank == 0:
                self.add_streaming_result({
                    "step": step,
                    "progress": (step + 1) / steps,
                    "message": f"Processing step {step + 1}/{steps}"
                }, as_text_event=True)
        
        # Return final result
        return {"output": final_result}
```

**Key points:**

* `add_streaming_result()`: Sends data to the client
* `as_text_event=True`: Formats as Server-Sent Events (SSE)
* Only rank 0 should stream to avoid duplicate messages

### 2. Create Streaming Endpoint

Define an endpoint that returns a `StreamingResponse`:

```python theme={null}
import fal
from fal.distributed import DistributedRunner
from fastapi.responses import StreamingResponse

class MyApp(fal.App):
    num_gpus = 2
    
    def setup(self):
        self.runner = DistributedRunner(
            worker_cls=StreamingWorker,
            world_size=self.num_gpus,
        )
    
    @fal.endpoint("/stream")
    async def stream(self, request: MyRequest) -> StreamingResponse:
        """Endpoint that streams results"""
        return StreamingResponse(
            self.runner.stream(
                request.dict(),
                as_text_events=True,
            ),
            media_type="text/event-stream",
        )
```

### 3. Consume Stream from Client

**JavaScript/TypeScript:**

```javascript theme={null}
const response = await fetch('https://your-app.fal.run/stream', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ prompt: "A sunset", steps: 20 })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  
  const text = decoder.decode(value);
  const events = text.split('\n\n');
  
  for (const event of events) {
    if (event.startsWith('data: ')) {
      const data = JSON.parse(event.slice(6));
      console.log(`Step ${data.step}: ${data.progress * 100}%`);
    }
  }
}
```

**Python:**

```python theme={null}
import fal_client

for event in fal_client.stream(
    "username/app-name",
    arguments={"prompt": "A sunset", "steps": 20}
    # path="/stream"  # Optional: defaults to "/stream", change if your endpoint uses a different path
):
    print(f"Step {event['step']}: {event['progress'] * 100}%")
```

<Note>
  If your endpoint uses a path other than `/stream`, specify it with the `path` parameter to match your `@fal.endpoint()` decorator.
</Note>

## Advanced: Streaming with Gather

Stream intermediate results from all GPUs and combine them:

```python theme={null}
class MultiGPUStreamingWorker(DistributedWorker):
    def __call__(self, prompt: str, num_steps: int = 20):
        for step in range(0, num_steps, 5):  # Stream every 5 steps
            # Generate intermediate result on this GPU
            intermediate = self.model.step(prompt)
            
            # Gather from all workers
            if self.rank == 0:
                gather_list = [
                    torch.zeros_like(intermediate, device=self.device)
                    for _ in range(self.world_size)
                ]
            else:
                gather_list = None
            
            dist.gather(intermediate, gather_list, dst=0)
            
            # Only rank 0 streams the combined result
            if self.rank == 0:
                combined = self.combine_results(gather_list)
                self.add_streaming_result({
                    "step": step,
                    "preview": combined,
                    "num_gpus": self.world_size,
                }, as_text_event=True)
            
            # Synchronize before next step
            dist.barrier()
        
        return {"final": final_result}
```

## Best Practices

### 1. Stream Only from Rank 0

Avoid duplicate messages by only streaming from the main worker:

```python theme={null}
if self.rank == 0:
    self.add_streaming_result(data, as_text_event=True)
```

### 2. Throttle Stream Frequency

Don't stream on every iteration - use intervals:

```python theme={null}
if step % 5 == 0:  # Every 5 steps
    self.add_streaming_result(...)
```

### 3. Use Synchronization

Synchronize workers after streaming to maintain consistency:

```python theme={null}
if self.rank == 0:
    self.add_streaming_result(data, as_text_event=True)

dist.barrier()  # Wait for all workers
```

### 4. Keep Payloads Small

Stream minimal data for responsiveness:

```python theme={null}
# Good: Small progress updates
self.add_streaming_result({
    "step": step,
    "progress": 0.5,
})

# Avoid: Large data in every update
# self.add_streaming_result({"large_array": [...]})
```

### 5. Handle Images Efficiently

For streaming images, use base64 encoding:

```python theme={null}
import base64
import io

# Convert PIL image to base64
buffer = io.BytesIO()
image.save(buffer, format="JPEG")
image_b64 = base64.b64encode(buffer.getvalue()).decode()

self.add_streaming_result({
    "preview": f"data:image/jpeg;base64,{image_b64}"
}, as_text_event=True)
```

## Complete Example

See the [Multi-GPU Inference Tutorial](/serverless/tutorials/deploy-multi-gpu-inference) for a complete working example with streaming, including:

* Real-time preview generation
* Progress updates every 5 steps
* Gathering results from multiple GPUs
* Progressive blur effects during generation

## Next Steps

<CardGroup cols={2}>
  <Card title="Multi-GPU Inference Tutorial" icon="bolt" href="/serverless/tutorials/deploy-multi-gpu-inference">
    Complete streaming example with SDXL
  </Card>

  <Card title="Real-time Endpoints" icon="signal-stream" href="/serverless/development/realtime">
    Learn about fal's real-time framework
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/faq.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# FAQ

Common questions about deploying and running your own apps on fal Serverless. For questions about calling pre-trained models, see the [Model APIs FAQ](/documentation/model-apis/faq).

<AccordionGroup>
  <Accordion title="How easy is it to migrate from another platform?">
    If you already have a working Docker container or a Python inference server, migrating to fal is straightforward. You can bring your existing Dockerfile directly with [custom container images](/documentation/development/use-custom-container-image), or wrap your model in a `fal.App` class with `setup()` and endpoint methods. fal has step-by-step migration guides for [Replicate](/documentation/development/migrate-from-replicate), [Modal](/documentation/development/migrate-from-modal), [RunPod](/documentation/development/migrate-from-runpod), and [generic Docker servers](/documentation/development/migrate-external-docker-server).
  </Accordion>

  <Accordion title="Can I export metrics to my own monitoring stack?">
    Yes. fal exposes a Prometheus-compatible [metrics endpoint](/documentation/serverless/observability/exporting-metrics) that you can scrape with Grafana, Datadog, or any tool that reads Prometheus format. Metrics include request counts, queue depth, runner states, and latency percentiles, broken down by app and endpoint. You can also forward logs to external services with [log drains](/documentation/serverless/observability/log-drains).
  </Accordion>

  <Accordion title="How do I improve runner utilization?">
    The two most impactful settings are `keep_alive` and `scaling_delay`. Lowering `keep_alive` reduces idle time by shutting down runners sooner after they finish processing, which avoids paying for runners that are waiting for requests that never come. Increasing `scaling_delay` prevents fal from spinning up new runners too quickly during short traffic bursts, giving existing runners a chance to absorb the load first. Together these help you avoid over-provisioning. For further tuning, `max_multiplexing` lets a single runner handle multiple requests concurrently, and `concurrency_buffer` pre-warms runners ahead of demand. See [Optimizing Costs](/documentation/serverless/optimizations/optimizing-costs) for the full set of strategies.
  </Accordion>

  <Accordion title="How do I control retry behavior?">
    fal automatically [retries](/documentation/serverless/reliability/retries) failed queue requests up to 10 times for server errors, timeouts, and connection failures. You can disable retries for specific conditions by setting `skip_retry_conditions` on your app (e.g., `skip_retry_conditions=["timeout"]` if your model legitimately takes a long time). You can also disable retries for individual responses by setting the `X-Fal-Needs-Retry: 0` header from your endpoint, or per-request by the caller with the `X-Fal-No-Retry: 1` header.
  </Accordion>

  <Accordion title="How am I billed for Serverless?">
    You are billed per-second for the total time your runners are alive, at the rate for your chosen [machine type](/documentation/deployment/machine-types). This includes `setup()`, idle time (including `keep_alive`), active request processing, draining, and teardown. You are not billed for pending time or container image pulls. See [Serverless Pricing](/documentation/serverless/pricing) for the full breakdown by runner state.
  </Accordion>

  <Accordion title="Am I billed for idle runners?">
    Yes. Runners in the `IDLE` state are billed at the same per-second rate as running requests. The `keep_alive` setting controls how long a runner stays alive after finishing its last request. Set `keep_alive = 0` to shut down immediately after each request, or use `min_concurrency` to keep warm runners available. See [Optimizing Costs](/documentation/serverless/optimizations/optimizing-costs) for strategies to balance cost and cold starts.
  </Accordion>

  <Accordion title="What GPU types are available?">
    fal offers CPU instances (XS through L) and GPU instances including RTX 4090, RTX 5090, A100, L40, H100, H200, and B200. Multi-GPU configurations are available for distributed workloads. See [Machine Types](/documentation/deployment/machine-types) for full specs and guidance on choosing the right GPU.
  </Accordion>

  <Accordion title="How do I reduce cold start times?">
    Cold starts happen when no warm runner is available and a new one must be provisioned. You can reduce them by setting `min_concurrency` to keep runners warm, using [FlashPack](/documentation/serverless/optimizations/flashpack) for faster container pulls, storing model weights on [persistent storage](/documentation/development/use-persistent-storage) (`/data`) to avoid re-downloads, and optimizing your container image. See [Optimizing Cold Starts](/documentation/serverless/optimizations/optimize-cold-starts) for the full guide.
  </Accordion>

  <Accordion title="What is the /data volume?">
    Every runner has access to a shared [persistent storage](/documentation/development/use-persistent-storage) volume mounted at `/data`. Files written to `/data` persist across requests, runner restarts, and deployments. It is backed by a multi-layer cache (local NVMe, datacenter cache, global object store) and is the recommended place to store model weights, datasets, and configuration files.
  </Accordion>

  <Accordion title="Can I use my own Docker image?">
    Yes. You can specify a Dockerfile or reference a pre-built image from any container registry, including private registries. See [Using a Custom Container Image](/documentation/development/use-custom-container-image) for setup instructions.
  </Accordion>

  <Accordion title="How does autoscaling work?">
    fal automatically scales runners up and down based on incoming request volume. You control the behavior with `min_concurrency` (minimum warm runners), `max_concurrency` (maximum runners), `max_multiplexing` (requests per runner), and `keep_alive` (idle timeout). See [Scaling Your Application](/documentation/deployment/scale-your-application) for details.
  </Accordion>

  <Accordion title="What is the maximum request timeout?">
    The default request timeout is 3600 seconds (1 hour). You can configure this per-app with the `request_timeout` setting in your app class. Callers can also set a client-side [`start_timeout`](/documentation/model-apis/inference/queue#start_timeout) to limit how long they wait before processing begins.
  </Accordion>

  <Accordion title="Can I run multiple models on one endpoint?">
    Yes. You can load multiple models in `setup()` and route between them based on request input, or use [multi-app routing](/documentation/development/multi-app-routing) to serve different models from different endpoints within a single deployment. You can also use [runner hints](/documentation/serverless/optimizations/optimize-routing-behavior) to pin requests to runners with specific models loaded.
  </Accordion>

  <Accordion title="How do I rollback a bad deployment?">
    Every deployment creates a new revision. You can roll back to any previous revision from the dashboard or CLI. See [Rollbacks](/documentation/deployment/rollbacks) for instructions.
  </Accordion>

  <Accordion title="Can I access logs from my running app?">
    Yes. Logs from your app are available in the dashboard, via the CLI (`fal apps runners`), and through the [Platform APIs](/api-reference/platform-apis/for-serverless). You can also configure [log drains](/documentation/serverless/observability/log-drains) to forward logs to external services. See [Logging](/documentation/development/logging) for how to emit structured logs from your app.
  </Accordion>

  <Accordion title="Do concurrency limits apply to my own endpoints?">
    No. When you call your own Serverless endpoints, [concurrency limits](/documentation/model-apis/concurrency-limits) are not enforced. Your throughput is limited by your `max_concurrency` scaling configuration, not by the platform-level account concurrency limit.
  </Accordion>
</AccordionGroup>


# https://fal.ai/docs/documentation/serverless/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction to Serverless

> Deploy custom AI models on GPU infrastructure that autoscales from zero to thousands of machines.

fal Serverless lets you deploy your own AI models, pipelines, and applications on GPU infrastructure that scales automatically. You write a Python class, define your hardware requirements, and fal handles provisioning, scaling, networking, and observability. Your code runs on H100s, A100s, or any other [machine type](/documentation/deployment/machine-types) you choose, scaling from zero runners to thousands based on demand, and back to zero when traffic stops.

Every model in the [Model APIs](/documentation/model-apis/overview) marketplace is a `fal.App` running on Serverless. When you deploy your own app, you get the same [queue-based reliability](/documentation/model-apis/inference/queue), the same [analytics dashboard](/documentation/serverless/observability/app-analytics), and the same [client SDKs](/documentation/development/calling-your-endpoints). The difference is that you control the code, the model weights, and the container environment. You can also [publish your app to the marketplace](/documentation/serverless/publishing-to-marketplace) so anyone can call it with their own API key.

<Warning>
  **Enterprise Feature** - Please visit the [Serverless Get Started page](https://fal.ai/dashboard/serverless-get-started) to request access.
</Warning>

## How It Works

The best deployment approach depends on where you are starting from. If you are migrating from another provider, you can be up and running with minimal code changes. If you are starting a new project, fal can build and manage the container for you. All three paths give you the same autoscaling, observability, and [runner](/documentation/getting-started/runners-and-caching) management.

### Migrating an existing server

If you already have a working HTTP server (FastAPI, Flask, or any framework), this is the fastest path. Deploy it with `@fal.function` and `exposed_port`, and fal routes traffic to your server's port with no code changes to your existing application.

```python theme={null}
import subprocess
import fal
from fal.container import ContainerImage

@fal.function(
    image=ContainerImage.from_dockerfile_str("FROM your-existing-image:latest"),
    machine_type="GPU-A100",
    exposed_port=8000,
)
def run_server():
    subprocess.run(
        ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"],
        check=True,
    )
```

`fal.function` supports all the same scaling parameters as `fal.App` (keep\_alive, min\_concurrency, max\_concurrency, and more). See [Migrate a Docker Server](/documentation/development/migrate-external-docker-server) for a complete walkthrough and the [full `fal.function` parameter reference](/documentation/development/migrate-external-docker-server#fal-function-reference). There are also step-by-step guides for [Replicate](/documentation/development/migrate-from-replicate), [Modal](/documentation/development/migrate-from-modal), and [RunPod](/documentation/development/migrate-from-runpod).

### Migrating a custom container

If you have a Docker image with your model and dependencies baked in but not a full HTTP server, you can bring it directly. Use `ContainerImage` to reference your Dockerfile or pull from a registry. You keep full control over the build while using fal's endpoint system and scaling.

```python theme={null}
import fal
from fal.container import ContainerImage

class MyModel(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
        RUN apt-get update && apt-get install -y ffmpeg
        RUN pip install diffusers transformers
    """)
    machine_type = "GPU-A100"

    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: dict) -> dict:
        image = self.pipe(input["prompt"]).images[0]
        return {"image": image}
```

You can pull from private registries (Docker Hub, GCP Artifact Registry, AWS ECR). See [Custom Container Images](/documentation/development/use-custom-container-image) for the full guide.

### Starting a new project

If you are building from scratch, use a native `fal.App` with pip requirements. You write a Python class, list your dependencies, and define your endpoints. fal builds the container for you.

```python theme={null}
import fal
from pydantic import BaseModel

class Input(BaseModel):
    prompt: str

class Output(BaseModel):
    result: str

class MyModel(fal.App):
    machine_type = "GPU-H100"
    requirements = ["torch", "transformers"]

    def setup(self):
        from transformers import pipeline
        self.pipe = pipeline("text-generation", model="gpt2", device="cuda")

    @fal.endpoint("/")
    def generate(self, input: Input) -> Output:
        result = self.pipe(input.prompt, max_length=50)[0]["generated_text"]
        return Output(result=result)
```

For the full environment setup options, see [Defining Your Environment](/documentation/development/container-setup).

### Test and deploy

Regardless of which approach you use, the workflow is the same. Test locally with `fal run`, then deploy with `fal deploy`. After deployment, your app gets a persistent URL, a [Playground](/documentation/model-apis/playground) for browser-based testing, and automatic scaling based on incoming traffic. See the [Quick Start](/documentation/development/getting-started/quick-start) to try it in under two minutes.

## Scaling, Observability, and Cost

Once your app is deployed, fal manages the infrastructure for you. [Runners](/documentation/deployment/runners) spin up when requests arrive and shut down when idle. You control the tradeoff between latency and cost with parameters like [keep\_alive](/documentation/deployment/scale-your-application) (how long idle runners stay warm) and [min\_concurrency](/documentation/deployment/scale-your-application) (minimum warm runners). To understand how runners transition between states and how caching reduces [cold starts](/documentation/serverless/optimizations/optimize-cold-starts), see [Runners and Caching](/documentation/getting-started/runners-and-caching).

Observability is built in. [App Analytics](/documentation/serverless/observability/app-analytics) shows request volume, latency percentiles, runner utilization, and startup duration. [Error Analytics](/documentation/serverless/observability/error-analytics) surfaces failing requests with stack traces. You can export metrics to your own stack via the [Prometheus-compatible API](/documentation/serverless/observability/exporting-metrics) or forward logs with [Log Drains](/documentation/serverless/observability/log-drains). For billing, see [Serverless Pricing](/documentation/serverless/pricing) and [Optimizing Costs](/documentation/serverless/optimizations/optimizing-costs).

## Next Steps

If you are new to fal, start with the [Quick Start](/documentation/development/getting-started/quick-start), which walks through building and deploying a Hello World app in under two minutes. The [Deploy Your First Image Generator](/documentation/development/getting-started/deploy-your-first-image-generator) tutorial applies the same workflow to a real Stable Diffusion XL model. Once you are comfortable with the basics, the [App Lifecycle](/documentation/development/app-lifecycle) page explains how apps are structured, where code runs, and how runners start up and shut down.

For more deployment examples covering text-to-image, video, speech, ComfyUI, and custom containers, browse the [Examples](/examples#deploying-models) section. For recent platform updates, check the [Changelog](/changelog) or watch the overview below.

<div className="max-w-2xl mx-auto">
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?autoplay=1'><img src='https://img.youtube.com/vi/gDJJ9bppyV8/maxresdefault.jpg' alt='What's New in fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</div>


# https://fal.ai/docs/documentation/serverless/observability/app-analytics.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# App Analytics

> Monitor your application's performance with real-time metrics and detailed analytics.

Every deployed app on fal comes with built-in analytics accessible from the [dashboard](https://fal.ai/dashboard/apps). You can see request volume, latency, error rates, and runner utilization at a glance, then drill into individual requests or runners to understand what happened.

The analytics are split into two views. The requests view answers questions about traffic and performance: how many requests are coming in, how fast they complete, which endpoints are slowest, and which requests failed. The runners view answers questions about infrastructure: how runner time is split between setup, inference, and idle, how deep the queue is, and whether you have the right scaling parameters.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=775&end=818&autoplay=1'><img src='/docs/images/video-thumbs/app-analytics.jpg' alt='Observing Metrics - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Requests

Navigate to **Dashboard > Apps > \[your-app] > Analytics** to see request metrics. You can filter by endpoint, date range, and view mode (your requests vs all requests to your app).

The key metrics to watch are request throughput, latency percentiles (P50, P90), and error rate. If latency is higher than expected, drill into individual requests to see a full breakdown from submission to completion, including inputs, outputs, and [logs](/documentation/development/logging). If errors are spiking, use [Error Analytics](/documentation/serverless/observability/error-analytics) for a detailed breakdown by status code and error type.

## Runners

The runners view shows how your infrastructure is performing. Use it to understand whether your [scaling parameters](/documentation/deployment/scale-your-application) are tuned correctly.

If runners are spending most of their time in setup, your cold starts are too long. Look at [Optimizing Cold Starts](/documentation/serverless/optimizations/optimize-cold-starts) for strategies. If runners are mostly idle, your `keep_alive` or `min_concurrency` may be too high. If the queue is consistently deep, you may need to increase `max_concurrency` or add [concurrency buffer](/documentation/deployment/scale-your-application).

You can also inspect individual runners to see their CPU, memory, and VRAM usage, and jump directly to their [logs](/documentation/development/logging) for debugging.

## Metrics Definitions

### Request Timing

Every request passes through several stages. The dashboard breaks these into two key charts: **Request Startup** (time before processing begins) and **Request Duration** (time spent processing).

| Metric                                  | What it measures                                                                                                                                                                                                                                                                                                                                                      |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Request Startup**                     | Time from submission until the request starts processing on a runner. For queued requests, this includes queue wait time and runner acquisition. If a cold start is needed, the startup time includes waiting for the new runner's `setup()` to complete. This is the metric most affected by [scaling parameters](/documentation/deployment/scale-your-application). |
| **Request Duration**                    | Time the request spent processing once it reached a runner. This is the actual execution time of your endpoint handler. Does not include queue wait or cold start time.                                                                                                                                                                                               |
| **Time to First Byte**                  | Time from when the request was sent to the runner until the first byte of the response was received. Useful for [streaming endpoints](/documentation/development/streaming) where you want to measure how quickly the user sees initial output.                                                                                                                       |
| **Latency Percentiles (P50, P75, P90)** | Both Request Startup and Request Duration are shown at the 50th, 75th, and 90th percentile. P90 means 90% of requests completed faster than this value. Use P90 to understand worst-case performance for most users.                                                                                                                                                  |

### Runner Timing

Runner time is split into three categories. The dashboard shows these as a stacked area chart over time.

| Metric                 | What it measures                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------------------- |   |
| **Startup Time**       | Time spent in the SETUP state, running your `setup()` method. This is your cold start cost. Appears once per runner lifecycle, not per request. Reduce it with [FlashPack](/documentation/serverless/optimizations/flashpack), [compiled caches](/documentation/serverless/optimizations/optimize-startup-with-compiled-caches), or by optimizing your `setup()` code.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **Execution Time**     | Time the runner spent actively processing requests (in the RUNNING state). This is the productive time you want to maximize.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| **Idle Time**          | Time the runner was alive but not processing any requests (in the IDLE state). Several scaling parameters affect idle time. [`keep_alive`](/documentation/deployment/scale-your-application) controls how long a runner stays alive after its last request before being terminated. [`min_concurrency`](/documentation/deployment/scale-your-application) keeps runners permanently warm even with no traffic, which means they accumulate idle time continuously. [`concurrency_buffer`](/documentation/deployment/scale-your-application) maintains extra runners above current demand, so those buffer runners are idle until traffic increases. [`scaling_delay`](/documentation/deployment/scale-your-application) makes the autoscaler wait before spinning up new runners, which can reduce idle time by reusing existing runners instead of creating new ones that sit idle. |
| **Runner Utilization** | Execution time as a percentage of total runner time (startup + execution + idle). Higher utilization means your runners are spending more time doing useful work. If utilization is low, look at which idle-time factor is the largest contributor: reduce `keep_alive` if runners linger too long after traffic stops, reduce `min_concurrency` if you have more warm runners than you need, or increase `scaling_delay` to encourage runner reuse.                                                                                                                                                                                                                                                                                                                                                                                                                                 |

### Queue and Concurrency

| Metric                  | What it measures                                                                                                                                                                          |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Queue Size**          | Number of requests currently waiting in the queue for an available runner. A consistently growing queue means you need more runners (increase `max_concurrency` or `concurrency_buffer`). |
| **Concurrent Requests** | Number of requests being actively processed across all runners at a given moment.                                                                                                         |
| **Error Rate**          | Percentage of requests that returned a 4XX or 5XX status code over the selected time period.                                                                                              |


# https://fal.ai/docs/documentation/serverless/observability/app-events.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# App Events

> Track deployments, runner lifecycle, and config changes with a full audit trail.

App Events gives you a chronological timeline of everything that happens to your application -- who deployed, when runners started or failed, and what configuration changed. Use it to debug incidents, audit team activity, and understand your app's lifecycle.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=222&end=278&autoplay=1'><img src='/docs/images/video-thumbs/app-events.jpg' alt='App Events - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## What You Can Track

Navigate to [**Dashboard > Apps > \[your-app\] > Events**](https://fal.ai/dashboard/apps) to see the timeline. You can search, filter by event category (runner, deployment, config), and set a date range.

App Events tracks three categories of activity:

**Runner events** show the lifecycle of individual runners: when they were scheduled, when they started pulling your image, when `setup()` ran, and when they became ready or failed. Failure events include the stage that failed (SETUP, DOCKER\_PULL, etc.), so you can quickly tell whether the problem is your image, your setup code, or infrastructure.

**Deployment events** track when deployments start, succeed, or fail. Use these to correlate performance changes with deploys. If latency spiked right after a deploy, you know where to look.

**Config change events** record who changed what, with a diff of old vs new values. This is the audit trail for scaling parameter changes, machine type updates, and auth mode switches.

## API Access

Query events programmatically:

```bash theme={null}
curl "https://rest.fal.ai/applications/your-username/your-app/events?since=2026-02-17T00:00:00Z" \
  -H "Authorization: Key $FAL_KEY"
```

### Parameters

| Parameter    | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `since`      | Start time (ISO 8601)                                           |
| `until`      | End time (ISO 8601)                                             |
| `categories` | Filter by event type (e.g., `runner_started`, `config_changed`) |
| `page`       | Page number                                                     |
| `size`       | Events per page                                                 |

<CardGroup cols={2}>
  <Card title="Error Analytics" icon="arrow-right" href="/documentation/serverless/observability/error-analytics">
    Analyze error patterns across your apps
  </Card>

  <Card title="Slack Notifications" icon="arrow-right" href="/documentation/serverless/observability/slack-notifications">
    Get notified when runners fail
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/observability/error-analytics.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Analytics

> Explore, filter, and debug request errors across your applications.

The Error Analytics dashboard gives you a centralized view of all request errors across your deployed applications. Use it to spot error spikes, identify which endpoints or status codes are causing the most failures, and drill into individual failed requests to see full logs and timing.

You can access error analytics per-app (from any app's **Errors** tab) or globally across all apps at [**Dashboard > Apps > Errors**](https://fal.ai/dashboard/apps/errors). Filter by endpoint, status code, and date range to narrow down the issue.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=441&end=483&autoplay=1'><img src='/docs/images/video-thumbs/error-analytics.jpg' alt='Error Analytics - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Debugging Errors

When you see errors in the dashboard, click into any individual failed request to see the full details: when it was submitted, how long it took, what status code was returned, and the complete [request logs](/documentation/development/logging). This is the fastest way to go from "something is failing" to "here's the stack trace."

For errors that correlate with a deployment, check [App Events](/documentation/serverless/observability/app-events) to see if a recent deploy or config change caused the issue. If the error rate is tied to a specific status code, see [Retries and Error Handling](/documentation/serverless/reliability/retries) to understand what each code means for your runners and retries.

## Common Error Patterns

| Status  | What it usually means                                                |
| ------- | -------------------------------------------------------------------- |
| **500** | Unhandled exception in your endpoint code. Runner stays alive.       |
| **502** | Runner crashed or connection was lost during processing.             |
| **503** | Runner is in a bad state and was terminated. Request is retried.     |
| **504** | Request exceeded timeout. Often from cold starts or heavy workloads. |
| **429** | Concurrency limit reached. Request is re-queued automatically.       |

For a complete reference on how each status code affects runners, retries, and billing, see [Status Codes](/documentation/serverless/reliability/retries#status-code-reference).

<CardGroup cols={2}>
  <Card title="Status Codes" icon="list-ol" href="/documentation/serverless/reliability/retries#status-code-reference">
    How each HTTP status code affects runners and retries
  </Card>

  <Card title="Retries" icon="rotate" href="/documentation/serverless/reliability/retries">
    How fal automatically retries failed requests
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/observability/exporting-metrics.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Exporting Metrics

> Export Prometheus-compatible metrics to Grafana, Datadog, or any monitoring tool.

fal exposes a Prometheus-compatible metrics endpoint that you can scrape with any monitoring tool. Use it to build custom dashboards, set up alerts on queue depth or error rates, and feed fal metrics into the same observability stack you use for the rest of your infrastructure.

The endpoint returns metrics in [Prometheus exposition format](https://prometheus.io/docs/instrumenting/exposition_formats/), so it works with Grafana, Datadog, New Relic, Splunk, or any tool that can scrape a Prometheus target. Responses are cached for 10 seconds, so set your scrape interval accordingly.

## Endpoint

```bash theme={null}
curl -H "Authorization: Key $FAL_KEY" \
  https://api.fal.ai/v1/serverless/metrics
```

## Available Metrics

| Metric                        | Labels                                 | Description                            |
| ----------------------------- | -------------------------------------- | -------------------------------------- |
| `fal_app_runners`             | `application`, `state`, `machine_type` | Number of runners currently allocated  |
| `fal_app_queue_size`          | `application`                          | Requests waiting in queue              |
| `fal_app_concurrent_requests` | `application`                          | Requests being actively processed      |
| `fal_app_requests_completed`  | `application`, `method`, `status`      | Requests completed in the last minute  |
| `fal_app_requests_received`   | `application`, `method`                | Requests received in the last minute   |
| `fal_app_request_latency`     | `application`, `le`                    | Completed requests bucketed by latency |

The `fal_app_runners` metric tracks runners across three states: `idle` (warm, waiting), `running` (processing), and `pending` (cold start in progress).

## Integration

Add the endpoint as a Prometheus data source in your monitoring tool. The only requirement is passing your API key in the `Authorization: Key ...` header. Set the scrape interval to at least 10 seconds since responses are cached at that frequency.

### Example PromQL Queries

```promql theme={null}
# Active runners by app
fal_app_runners{state="running"}

# Queue depth across all apps
sum(fal_app_queue_size) by (application)

# Request rate (completed per minute)
fal_app_requests_completed

# P99 latency estimation
histogram_quantile(0.99, fal_app_request_latency)
```

<Note>
  All metrics are gauges. The `fal_app_request_latency` metric uses histogram-style buckets (labeled by `le`) for latency distribution analysis.
</Note>

<Card title="Platform API Reference" icon="arrow-right" href="/api-reference/platform-apis/for-serverless">
  Full API specification for the metrics endpoint
</Card>


# https://fal.ai/docs/documentation/serverless/observability/log-drains.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Log Drains

> Forward your application logs to external services like Datadog, Splunk, or Elasticsearch.

Log Drains automatically forward your application logs to an external HTTPS endpoint in real time. Use them to send logs to Datadog, Splunk, Elasticsearch, or any service that accepts HTTPS webhooks.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=278&end=345&autoplay=1'><img src='/docs/images/video-thumbs/log-drains.jpg' alt='Log Drains - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Setting Up a Log Drain

1. Go to [**Dashboard > Log Drains**](https://fal.ai/dashboard/drains)
2. Click **Create Log Drain**
3. Configure:
   * **Name** -- A label for this drain (e.g., "Production Datadog")
   * **Endpoint URL** -- The HTTPS URL to send logs to (must be HTTPS)
   * **Secret Token** -- Used to sign payloads so you can verify they came from fal (minimum 64 characters)
   * **Sampling Rate** -- Maximum logs per delivery batch (1-5000, default: 1000)
4. Click **Test** to verify connectivity before saving

<Note>
  Log Drains require **Admin** role in your team. Only one log drain can be active per account.
</Note>

## Log Format

Logs are delivered as [NDJSON](http://ndjson.org/) (newline-delimited JSON) via HTTP POST. Each line is a JSON object:

```json theme={null}
{"timestamp": "2026-02-17T10:30:00.123Z", "message": "Model loaded successfully", "level": "info", "fal_app_name": "my-model", "fal_app_id": "abc123", "fal_request_id": "req-456", "fal_job_id": "job-789", "fal_endpoint": "/", "fal_node_id": "node-1", "fal_worker_id": "worker-42"}
{"timestamp": "2026-02-17T10:30:01.456Z", "message": "Inference completed in 1.2s", "level": "info", "fal_app_name": "my-model", "fal_app_id": "abc123", "fal_request_id": "req-456", "fal_job_id": "job-789", "fal_endpoint": "/", "fal_node_id": "node-1", "fal_worker_id": "worker-42"}
```

### Fields

Every log line contains the core fields plus any available context labels. Fields beyond `timestamp`, `message`, and `level` are included only when the platform has a value for them.

| Field                | Description                                               |
| -------------------- | --------------------------------------------------------- |
| `timestamp`          | ISO 8601 timestamp                                        |
| `message`            | The log message                                           |
| `level`              | Log level (`info`, `warning`, `error`, etc.)              |
| `fal_app_name`       | Your application name                                     |
| `fal_app_id`         | Application identifier                                    |
| `fal_request_id`     | The request that generated this log                       |
| `fal_job_id`         | The fal-internal job identifier for the runner            |
| `fal_endpoint`       | The endpoint path that handled the request (e.g., `/`)    |
| `fal_node_id`        | The unique ID of the infrastructure node the runner is on |
| `fal_worker_id`      | The scheduler-level allocation ID for the runner          |
| `fal_source`         | Log source (e.g., `run`, `gateway`)                       |
| `fal_isolate_source` | Runtime-level log source                                  |

## Verifying Signatures

Every delivery includes an `X-Fal-Signature` header containing an HMAC-SHA256 signature of the request body, signed with your secret token. Use this to verify that deliveries are genuinely from fal.

```python theme={null}
import hmac
import hashlib

def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)
```

The `Content-Type` header is `application/x-ndjson`.

## Delivery Behavior

* Logs are delivered in batches on a regular schedule
* New drains start delivering logs from the last 30 seconds
* The **sampling rate** controls the maximum number of log lines per batch
* Deliveries time out after 10 seconds

### Failure Handling

If your endpoint returns an error or is unreachable:

* fal tracks consecutive failures
* After **5 consecutive failures**, the drain is automatically disabled
* You can re-enable it from the dashboard after fixing the endpoint
* The dashboard shows the failure count and last successful delivery time

## Managing Log Drains

Manage your drains from the [Dashboard](https://fal.ai/dashboard/drains). You can enable/disable, test connectivity, update the endpoint URL or sampling rate, or delete a drain entirely.

## External Services

Log drains work with any service that accepts HTTPS webhooks with NDJSON payloads. Point the drain at your service's HTTP log intake URL and include any required API keys in the URL path or query parameters as needed by your provider.

<Card title="Observability Overview" icon="arrow-right" href="/documentation/serverless/observability/monitor-performance">
  See all monitoring interfaces: dashboard, CLI, and integrations
</Card>


# https://fal.ai/docs/documentation/serverless/observability/monitor-performance.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Observability Overview

> Monitor your fal applications using the dashboard, CLI, and programmatic integrations.

Once your app is deployed and serving traffic, you need visibility into how it is performing. fal provides three interfaces for observability, each suited to different workflows. The [dashboard](https://fal.ai/dashboard) gives you visual, real-time insight into requests, runners, and errors. The [CLI](/api-reference/cli/runners) lets you check runner states and stream logs from your terminal. And the programmatic integrations (Prometheus metrics, log drains, Slack notifications) let you pipe fal's data into your existing monitoring stack.

Understanding which interface to use for which task saves you from digging through the wrong tool. The dashboard is best for investigating specific issues and getting a quick overview. The CLI is best for quick operational checks and scripting. The integrations are best for production alerting, long-term metrics storage, and centralized logging.

## Dashboard

The [fal dashboard](https://fal.ai/dashboard) is the primary interface for visual monitoring. It provides several views depending on what you need to understand.

**App Analytics** shows request volume, latency, runner counts, and queue depth for each deployed app. Use it to understand traffic patterns, identify slow endpoints, and verify that scaling is working correctly. The Requests tab shows individual request history with status, duration, and logs. The Runners tab shows runner lifecycle events and state transitions.

**Error Analytics** breaks down failures by error type, status code, and time. Use it to spot error spikes, identify recurring failure patterns, and understand which errors are transient vs systemic.

**App Events** tracks deployment events, configuration changes, and runner lifecycle events. Use it to correlate performance changes with deployments (e.g., "latency increased right after this deploy").

**Logs** streams runner logs in real-time and lets you filter by runner ID, request ID, version, and source. For understanding how request-level logs work, see [Logging](/documentation/development/logging).

<CardGroup cols={2}>
  <Card title="App Analytics" icon="chart-mixed" href="/documentation/serverless/observability/app-analytics">
    Request metrics, runner states, and per-app performance
  </Card>

  <Card title="Error Analytics" icon="triangle-exclamation" href="/documentation/serverless/observability/error-analytics">
    Error rates, patterns, and failure breakdown
  </Card>

  <Card title="App Events" icon="timeline" href="/documentation/serverless/observability/app-events">
    Deployment, config, and runner lifecycle events
  </Card>
</CardGroup>

## CLI

The fal CLI provides quick access to runner states, logs, and queue status from your terminal. This is useful for operational checks, scripting, and CI pipelines.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=1195&end=1296&autoplay=1'><img src='/docs/images/video-thumbs/monitor-performance.jpg' alt='CLI Updates - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

```bash theme={null}
# Runner monitoring
fal runners list                        # all runners with current states
fal runners list --state idle           # filter by state
fal runners list --since "1h"           # view history
fal runners logs <runner-id>            # stream logs from a runner

# Queue monitoring
fal queue size my-app                   # current queue depth
fal queue flush my-app                  # clear stuck requests

# App management
fal apps list                           # all deployed apps
fal apps runners my-app                 # runners for a specific app
fal apps scale my-app                   # view/update scaling config
```

See the CLI reference for [`fal runners`](/api-reference/cli/runners), [`fal queue`](/api-reference/cli/queue), and [`fal apps`](/api-reference/cli/apps/list).

## Programmatic Integrations

For production monitoring, you can pipe fal's data into your existing observability stack. This gives you long-term retention, custom dashboards, and alerting that the built-in dashboard does not provide.

**Prometheus Metrics** -- fal exposes a Prometheus-compatible metrics endpoint that you can scrape with Grafana, Datadog, or any Prometheus-compatible tool. Available metrics include runner counts, queue depth, concurrent requests, request throughput, and latency buckets.

**Log Drains** -- forward all runner logs to an external service (Datadog, Splunk, or any HTTP endpoint) in real-time via NDJSON over HTTPS. Logs include request IDs, timestamps, and structured metadata for correlation.

**Slack Notifications** -- receive alerts in Slack when runners fail to start, deployments complete, or configuration changes occur.

<CardGroup cols={2}>
  <Card title="Exporting Metrics" icon="chart-line" href="/documentation/serverless/observability/exporting-metrics">
    Prometheus endpoint, Grafana setup, and Datadog integration
  </Card>

  <Card title="Log Drains" icon="arrow-right-from-bracket" href="/documentation/serverless/observability/log-drains">
    Forward logs to external services in real-time
  </Card>

  <Card title="Slack Notifications" icon="bell" href="/documentation/serverless/observability/slack-notifications">
    Alert on deployments, failures, and config changes
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/observability/opentelemetry-cross-service.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cross-Service Tracing

> Propagate trace context between two fal apps so that preprocessing and inference appear as children of a single parent trace

When a request passes through more than one fal app, each app creates its own spans by default and those spans appear as separate, unrelated traces in your backend. Passing W3C trace context between apps connects them under a single trace ID, so preprocessing and inference show up as children of one root span. For single-app tracing, see [Custom Traces](/documentation/serverless/observability/opentelemetry-traces).

## How Context Propagation Works

The W3C Trace Context standard defines a `traceparent` header that carries a trace ID and parent span ID between services. The sending app injects the current span context into a carrier (a plain dict), passes it to the receiving app, and the receiving app extracts the context before creating its span. Both apps end up contributing spans to the same trace ID.

fal apps communicate over HTTP, and the carrier is passed as a field in the JSON request body. Both apps must export to the same OTLP backend for the spans to be correlated.

## Setup

Deploy `TextToImageWorker` first to get its app id, then deploy `ImagePipeline` and pass the app id when calling it.

```bash theme={null}
fal deploy pipeline.py::TextToImageWorker
# Note the app id, e.g. your-username/text-to-image-worker

fal deploy pipeline.py::ImagePipeline
```

Both apps must have `OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_EXPORTER_OTLP_HEADERS` set as fal secrets. See [Custom Traces](/documentation/serverless/observability/opentelemetry-traces#prerequisites) for backend options and how to store credentials.

## Implementation

```python Python theme={null}
import os

import fal
from fal.toolkit import Image
from pydantic import BaseModel, Field


def setup_tracer(service_name: str):
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor

    resource = Resource.create({"service.name": service_name})
    provider = TracerProvider(resource=resource)
    provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(provider)
    return trace.get_tracer(service_name), provider


# App 1: ImagePipeline - validates and preprocesses the prompt, then calls TextToImageWorker

class PipelineInput(BaseModel):
    prompt: str = Field(description="The prompt to generate an image from")
    worker_app: str = Field(description="Deployed app id of TextToImageWorker")


class PipelineOutput(BaseModel):
    image: Image
    trace_id: str


class ImagePipeline(fal.App):
    machine_type = "S"
    requirements = [
        "opentelemetry-sdk==1.41.0",
        "opentelemetry-exporter-otlp-proto-http==1.41.0",
        "fal-client",
    ]

    def setup(self):
        from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator

        self.tracer, self.tracer_provider = setup_tracer("image-pipeline")
        self._propagator = TraceContextTextMapPropagator()

    @fal.endpoint("/")
    def run(self, input: PipelineInput) -> PipelineOutput:
        import fal_client

        with self.tracer.start_as_current_span("image-pipeline") as root:
            with self.tracer.start_as_current_span("preprocess-prompt") as span:
                span.set_attribute("prompt.length", len(input.prompt))
                # Sanitize and enrich the prompt before passing to inference
                enriched_prompt = input.prompt.strip()

            # Inject the current span context into a carrier dict.
            # The carrier will contain {"traceparent": "00-<trace-id>-<span-id>-01"}.
            carrier: dict[str, str] = {}
            self._propagator.inject(carrier)

            with self.tracer.start_as_current_span("call-inference-worker"):
                result = fal_client.subscribe(
                    input.worker_app,
                    {"prompt": enriched_prompt, "trace_context": carrier},
                )

            trace_id = format(root.get_span_context().trace_id, "032x")

        return PipelineOutput(image=Image(**result["image"]), trace_id=trace_id)

    def teardown(self):
        if self.tracer_provider:
            self.tracer_provider.force_flush(timeout_millis=4000)


# App 2: TextToImageWorker - receives context and runs SDXL inference

class WorkerInput(BaseModel):
    prompt: str
    trace_context: dict  # W3C traceparent injected by ImagePipeline


class WorkerOutput(BaseModel):
    image: Image


class TextToImageWorker(fal.App):
    machine_type = "GPU-H100"
    requirements = [
        "hf-transfer==0.1.9",
        "diffusers[torch]==0.32.2",
        "torch==2.10.0",
        "transformers[sentencepiece]==4.51.0",
        "accelerate==1.6.0",
        "opentelemetry-sdk==1.41.0",
        "opentelemetry-exporter-otlp-proto-http==1.41.0",
    ]

    def setup(self):
        # Enable HF Transfer for faster downloads
        os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"

        import torch
        from diffusers import StableDiffusionXLPipeline
        from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator

        self.tracer, self.tracer_provider = setup_tracer("text-to-image-worker")
        self._propagator = TraceContextTextMapPropagator()
        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
            variant="fp16",
            use_safetensors=True,
        ).to("cuda")
        self.pipe("warmup")

    @fal.endpoint("/")
    def run(self, input: WorkerInput) -> WorkerOutput:
        # Extract the parent context from the carrier.
        # The new span becomes a child of ImagePipeline's active span.
        ctx = self._propagator.extract(input.trace_context)

        with self.tracer.start_as_current_span("inference", context=ctx) as span:
            span.set_attribute("model.name", "stable-diffusion-xl-base-1.0")
            span.set_attribute("prompt.length", len(input.prompt))

            with self.tracer.start_as_current_span("diffusion"):
                result = self.pipe(input.prompt)

            with self.tracer.start_as_current_span("upload"):
                image = Image.from_pil(result.images[0])

        return WorkerOutput(image=image)

    def teardown(self):
        if self.tracer_provider:
            self.tracer_provider.force_flush(timeout_millis=4000)
```

## Resulting Trace

Both apps export to the same backend using the same trace ID. The trace appears as:

```
image-pipeline                         (ImagePipeline app)
├── preprocess-prompt
├── call-inference-worker
└── inference                          (TextToImageWorker app)
    ├── diffusion
    └── upload
```

The `inference` span in `TextToImageWorker` is a child of `image-pipeline` in `ImagePipeline` because `_propagator.extract(input.trace_context)` reconstructed the parent context before the span was created.

The entity map shows both apps connected, and the span tree shows spans from both services under the same trace ID:

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/zo-kE_ST4HOR1zo1/images/observability/opentelemetry-cross-service-traces.png?fit=max&auto=format&n=zo-kE_ST4HOR1zo1&q=85&s=f20142220cd0c39c75d2adac5d1c9763" alt="Cross-service trace showing image-pipeline root span with preprocess-prompt, call-inference-worker, and inference children spanning two fal apps" width="2426" height="1578" data-path="images/observability/opentelemetry-cross-service-traces.png" />
</Frame>

<Note>
  Both apps must export to the same OTLP backend for the trace to appear connected. If each app sends spans to a different backend, they will not be correlated even though they share a trace ID.
</Note>

## What's Next

<CardGroup cols={2}>
  <Card title="Custom Traces" icon="code-branch" href="/documentation/serverless/observability/opentelemetry-traces">
    Instrument a single app with spans for each inference stage
  </Card>

  <Card title="Production Configuration" icon="sliders" href="/documentation/serverless/observability/opentelemetry-production">
    Sampling, batch export tuning, and graceful flush on shutdown
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/observability/opentelemetry-production.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenTelemetry in Production

> Configure sampling, batch export tuning, and graceful flush so your traces hold up under production load

Exporting 100% of traces from a high-throughput app generates significant backend ingestion cost, and spans buffered in `BatchSpanProcessor` are silently dropped when a runner shuts down if they are not flushed before `SIGKILL` arrives. For basic tracing setup, start with [Custom Traces](/documentation/serverless/observability/opentelemetry-traces).

## Conditional Tracing

Disable tracing entirely with an environment variable when you do not need it. When no `TracerProvider` is configured, the OpenTelemetry SDK returns a no-op tracer. All `start_as_current_span` calls become zero-cost no-ops and no export threads are started.

```python Python theme={null}
def setup_tracer(service_name: str):
    import os
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor

    if os.environ.get("ENABLE_TRACING", "true").lower() != "true":
        return trace.get_tracer(service_name), None

    resource = Resource.create({"service.name": service_name})
    provider = TracerProvider(resource=resource)
    provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(provider)
    return trace.get_tracer(service_name), provider
```

Set `ENABLE_TRACING=false` as a fal secret to turn off tracing without redeploying:

```bash theme={null}
fal secrets set ENABLE_TRACING=false
```

## Sampling

Sampling reduces the fraction of traces exported. Use it when your app handles many requests per second and exporting every trace would exceed your backend's ingestion limits or add measurable latency.

`ParentBased(root=TraceIdRatioBased(rate))` is the recommended sampler for services that receive calls from other services. It honours the sampling decision made upstream (so a trace that was sampled by a caller is always sampled here too), and applies ratio-based sampling only to new root spans.

```python Python theme={null}
def setup_tracer(service_name: str):
    import os
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    from opentelemetry.sdk.trace.sampling import ParentBased, TraceIdRatioBased

    if os.environ.get("ENABLE_TRACING", "true").lower() != "true":
        return trace.get_tracer(service_name), None

    # OTEL_SAMPLE_RATE=0.1 exports 10% of root spans; default is 1.0 (all spans).
    sample_rate = float(os.environ.get("OTEL_SAMPLE_RATE", "1.0"))
    sampler = ParentBased(root=TraceIdRatioBased(sample_rate))

    resource = Resource.create({"service.name": service_name})
    provider = TracerProvider(resource=resource, sampler=sampler)
    provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(provider)
    return trace.get_tracer(service_name), provider
```

Start with `OTEL_SAMPLE_RATE=0.1` under heavy load and increase it if you need more coverage for debugging.

## Batch Export Tuning

`BatchSpanProcessor` buffers spans in memory and exports them in bulk. Tune these parameters if you see dropped spans under burst traffic or export timeouts in your backend logs.

```python Python theme={null}
processor = BatchSpanProcessor(
    OTLPSpanExporter(),
    # Drop oldest spans when the in-memory queue is full.
    # Increase this if you see "SpanProcessor queue is full" warnings.
    max_queue_size=2048,
    # Spans per HTTP request to the collector.
    # Larger batches reduce request overhead at the cost of higher memory use.
    max_export_batch_size=512,
    # How often to flush the buffer, in milliseconds.
    schedule_delay_millis=5000,
    # Give up on an export request after this long.
    export_timeout_millis=30_000,
)
```

| Parameter               | Default | When to increase                                   |
| ----------------------- | ------- | -------------------------------------------------- |
| `max_queue_size`        | 2048    | Seeing dropped spans under burst traffic           |
| `max_export_batch_size` | 512     | High span volume with low per-request overhead     |
| `schedule_delay_millis` | 5000    | Backend is overwhelmed by frequent export requests |
| `export_timeout_millis` | 30000   | Backend is slow or on a high-latency network       |

## Flushing on Shutdown

fal gives runners a 5-second grace period between `SIGTERM` and `SIGKILL`. `teardown()` runs during that window, after all in-flight requests finish. See [App Lifecycle](/documentation/development/app-lifecycle) for the full shutdown sequence.

Call `force_flush()` in `teardown()`, not in your endpoint handler. Per-request flushing adds latency on every call; `BatchSpanProcessor` handles periodic exports on its own schedule.

```python Python theme={null}
import os

import fal
from fal.toolkit import Image
from pydantic import BaseModel, Field

def setup_tracer(service_name: str):
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    from opentelemetry.sdk.trace.sampling import ParentBased, TraceIdRatioBased

    if os.environ.get("ENABLE_TRACING", "true").lower() != "true":
        return trace.get_tracer(service_name), None

    sample_rate = float(os.environ.get("OTEL_SAMPLE_RATE", "1.0"))
    sampler = ParentBased(root=TraceIdRatioBased(sample_rate))

    resource = Resource.create({"service.name": service_name})
    provider = TracerProvider(resource=resource, sampler=sampler)
    provider.add_span_processor(
        BatchSpanProcessor(
            OTLPSpanExporter(),
            max_queue_size=2048,
            max_export_batch_size=512,
            schedule_delay_millis=5000,
            export_timeout_millis=30_000,
        )
    )
    trace.set_tracer_provider(provider)
    return trace.get_tracer(service_name), provider


class Input(BaseModel):
    prompt: str = Field(description="The prompt to generate an image from")
    num_inference_steps: int = Field(default=20)


class Output(BaseModel):
    image: Image
    trace_id: str


class ProductionApp(fal.App):
    machine_type = "GPU-A100"
    requirements = [
        "hf-transfer==0.1.9",
        "diffusers[torch]==0.32.2",
        "torch==2.10.0",
        "transformers[sentencepiece]==4.51.0",
        "accelerate==1.6.0",
        "opentelemetry-sdk==1.41.0",
        "opentelemetry-exporter-otlp-proto-http==1.41.0",
    ]

    def setup(self):
        # Enable HF Transfer for faster downloads
        os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"

        import torch
        from diffusers import StableDiffusionXLPipeline

        self.tracer, self.tracer_provider = setup_tracer("text-to-image")

        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
            variant="fp16",
            use_safetensors=True,
        ).to("cuda")
        self.pipe("warmup")

    @fal.endpoint("/")
    def run(self, input: Input) -> Output:
        with self.tracer.start_as_current_span("text-to-image") as root:
            root.set_attribute("model.name", "stable-diffusion-xl-base-1.0")

            with self.tracer.start_as_current_span("inference"):
                result = self.pipe(input.prompt, num_inference_steps=input.num_inference_steps)

            with self.tracer.start_as_current_span("upload"):
                image = Image.from_pil(result.images[0])

            trace_id = format(root.get_span_context().trace_id, "032x")

        return Output(image=image, trace_id=trace_id)

    def teardown(self):
        # Flush buffered spans before SIGKILL (5s grace period).
        # Use 4000ms to leave headroom for SIGKILL at 5000ms.
        if self.tracer_provider:
            self.tracer_provider.force_flush(timeout_millis=4000)
```

<Warning>
  The 5-second grace period is a shared budget across `handle_exit()`, remaining in-flight requests, `teardown()`, and `force_flush()`. If your endpoint handles long-running requests, use `handle_exit()` to signal them to stop early so `teardown()` has enough time to flush. See [App Lifecycle](/documentation/development/app-lifecycle) for the full shutdown sequence.
</Warning>

## What's Next

<CardGroup cols={2}>
  <Card title="Custom Traces" icon="code-branch" href="/documentation/serverless/observability/opentelemetry-traces">
    Add spans to trace inference stages end to end
  </Card>

  <Card title="Custom Metrics" icon="chart-bar" href="/documentation/serverless/observability/custom-metrics">
    Counters, histograms, and gauges for your inference workload
  </Card>

  <Card title="Cross-Service Tracing" icon="diagram-project" href="/documentation/serverless/observability/opentelemetry-cross-service">
    Connect traces across multiple fal apps
  </Card>

  <Card title="App Lifecycle" icon="rotate" href="/documentation/development/app-lifecycle">
    Full shutdown sequence and grace period details
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/observability/opentelemetry-traces.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Traces with OpenTelemetry

> Add OpenTelemetry spans to your fal app to trace inference stages like warmup, diffusion, and image upload

fal apps run on standard Python, so you can instrument them with the OpenTelemetry SDK the same way you would any other service. Add the SDK to `requirements`, initialize a tracer in `setup()`, and wrap your inference stages with spans. For custom metrics instrumentation, see [Custom Metrics](/documentation/serverless/observability/custom-metrics). For tracing across multiple fal apps, see [Cross-Service Tracing](/documentation/serverless/observability/opentelemetry-cross-service).

## Prerequisites

You need an OTLP-compatible backend. Any of the following work:

| Backend        | OTLP endpoint                                         | Auth header                                      |
| -------------- | ----------------------------------------------------- | ------------------------------------------------ |
| New Relic (US) | `https://otlp.nr-data.net:4318`                       | `api-key=<INGEST_LICENSE_KEY>`                   |
| New Relic (EU) | `https://otlp.eu01.nr-data.net:4318`                  | `api-key=<INGEST_LICENSE_KEY>`                   |
| Datadog (US)   | `https://otlp.datadoghq.com`                          | `dd-api-key=<API_KEY>`                           |
| Datadog (EU)   | `https://otlp.datadoghq.eu`                           | `dd-api-key=<API_KEY>`                           |
| Grafana Cloud  | `https://otlp-gateway-prod-<region>.grafana.net/otlp` | `Authorization=Basic <base64(instanceId:token)>` |
| Honeycomb      | `https://api.honeycomb.io`                            | `x-honeycomb-team=<API_KEY>`                     |

Store your credentials as fal secrets so they are available as environment variables on the runner without being embedded in your code.

<Tabs>
  <Tab title="Datadog (US)">
    ```bash theme={null}
    fal secrets set OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.datadoghq.com
    fal secrets set OTEL_EXPORTER_OTLP_HEADERS="dd-api-key=<YOUR_API_KEY>"
    ```
  </Tab>

  <Tab title="Datadog (EU)">
    ```bash theme={null}
    fal secrets set OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.datadoghq.eu
    fal secrets set OTEL_EXPORTER_OTLP_HEADERS="dd-api-key=<YOUR_API_KEY>"
    ```
  </Tab>

  <Tab title="New Relic (US)">
    ```bash theme={null}
    fal secrets set OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.nr-data.net:4318
    fal secrets set OTEL_EXPORTER_OTLP_HEADERS="api-key=<YOUR_LICENSE_KEY>"
    ```
  </Tab>

  <Tab title="New Relic (EU)">
    ```bash theme={null}
    fal secrets set OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.eu01.nr-data.net:4318
    fal secrets set OTEL_EXPORTER_OTLP_HEADERS="api-key=<YOUR_LICENSE_KEY>"
    ```
  </Tab>

  <Tab title="Grafana Cloud">
    ```bash theme={null}
    fal secrets set OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-<region>.grafana.net/otlp
    fal secrets set OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic <base64(instanceId:token)>"
    ```
  </Tab>

  <Tab title="Honeycomb">
    ```bash theme={null}
    fal secrets set OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io
    fal secrets set OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=<YOUR_API_KEY>"
    ```
  </Tab>
</Tabs>

See [Managing Secrets](/documentation/development/manage-secrets-securely) for details on how fal secrets work.

## Adding Traces to Your App

Add `opentelemetry-sdk` and `opentelemetry-exporter-otlp-proto-http` to your app's `requirements`. The exporter reads `OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_EXPORTER_OTLP_HEADERS` from the environment automatically, no endpoint or auth code required.

Initialize the tracer in `setup()`. The provider and export connection are created once per runner, not once per request.

The example below builds on the [Stable Diffusion XL quickstart](/documentation/development/getting-started/deploy-your-first-image-generator) and adds spans around each stage of a text-to-image request.

```python Python theme={null}
import os

import fal
from fal.toolkit import Image
from pydantic import BaseModel, Field


def setup_tracer(service_name: str):
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor

    resource = Resource.create({"service.name": service_name})
    provider = TracerProvider(resource=resource)
    provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(provider)
    return trace.get_tracer(service_name), provider


class Input(BaseModel):
    prompt: str = Field(description="The prompt to generate an image from")
    num_inference_steps: int = Field(default=20)


class Output(BaseModel):
    image: Image
    trace_id: str


class TextToImageApp(fal.App):
    machine_type = "GPU-H100"
    requirements = [
        "hf-transfer==0.1.9",
        "diffusers[torch]==0.32.2",
        "torch==2.10.0",
        "transformers[sentencepiece]==4.51.0",
        "accelerate==1.6.0",
        "opentelemetry-sdk==1.41.0",
        "opentelemetry-exporter-otlp-proto-http==1.41.0",
    ]

    def setup(self):
        # Enable HF Transfer for faster downloads
        os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"

        import torch
        from diffusers import StableDiffusionXLPipeline

        self.tracer, self.tracer_provider = setup_tracer("text-to-image")

        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            torch_dtype=torch.float16,
            variant="fp16",
            use_safetensors=True,
        ).to("cuda")

        # Warmup runs once per runner at startup - not per request.
        # It compiles CUDA kernels so the first real request does not pay that cost.
        with self.tracer.start_as_current_span("warmup") as span:
            span.set_attribute("model.name", "stable-diffusion-xl-base-1.0")
            self.pipe("warmup")

    @fal.endpoint("/")
    def run(self, input: Input) -> Output:
        with self.tracer.start_as_current_span("text-to-image") as root:
            root.set_attribute("model.name", "stable-diffusion-xl-base-1.0")
            root.set_attribute("prompt.length", len(input.prompt))
            root.set_attribute("num_inference_steps", input.num_inference_steps)

            with self.tracer.start_as_current_span("inference") as span:
                span.set_attribute("num_inference_steps", input.num_inference_steps)
                result = self.pipe(
                    input.prompt,
                    num_inference_steps=input.num_inference_steps,
                )

            with self.tracer.start_as_current_span("upload"):
                image = Image.from_pil(result.images[0])

            trace_id = format(root.get_span_context().trace_id, "032x")

        return Output(image=image, trace_id=trace_id)

    def teardown(self):
        # Flush buffered spans before SIGKILL (5s grace period).
        # For sampling, batch tuning, and conditional tracing see Production Configuration.
        if self.tracer_provider:
            self.tracer_provider.force_flush(timeout_millis=4000)
```

## Span Structure

The example above produces a tree of spans under a single root:

```
text-to-image
├── inference
└── upload
```

The `warmup` span appears in your backend attached to the runner's startup trace, not to individual requests. Each request produces its own `text-to-image` root span. The parent span's duration covers all of its children, so `text-to-image` reflects the total request time including upload.

The trace appears in your backend like this, with `inference` and `upload` shown as timed children of the root span:

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/zo-kE_ST4HOR1zo1/images/observability/opentelemetry-traces.png?fit=max&auto=format&n=zo-kE_ST4HOR1zo1&q=85&s=2afe2c89b16cc8ab8b5752e316f61b69" alt="Span tree showing text-to-image root span with inference and upload children in a trace backend" width="2426" height="1578" data-path="images/observability/opentelemetry-traces.png" />
</Frame>

## Span Attributes

Call `span.set_attribute(key, value)` to attach metadata to a span. Attributes appear as filterable fields in your backend's trace viewer, so you can search for all traces where `num_inference_steps` is above a threshold or `prompt.length` exceeds a limit.

```python Python theme={null}
with self.tracer.start_as_current_span("inference") as span:
    span.set_attribute("model.name", "stable-diffusion-xl-base-1.0")
    span.set_attribute("num_inference_steps", input.num_inference_steps)
    span.set_attribute("prompt.length", len(input.prompt))
    span.set_attribute("guidance_scale", 7.5)
```

Attribute keys follow the [OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/) where applicable. For model-specific attributes, use a consistent namespace like `model.*` or `inference.*`.

## Marking Errors

Use `record_exception` and `set_status` to mark a span as failed. This is the portable OpenTelemetry pattern — all OTLP backends interpret `StatusCode.ERROR` as a failed span, whereas a custom `error` attribute is backend-specific metadata.

```python Python theme={null}
from opentelemetry.trace import Status, StatusCode

with self.tracer.start_as_current_span("inference") as span:
    try:
        result = self.pipe(input.prompt)
    except RuntimeError as e:
        span.record_exception(e)
        span.set_status(Status(StatusCode.ERROR, str(e)))
        raise
```

<Note>
  `BatchSpanProcessor` exports spans asynchronously in the background. On a long-running runner, spans are batched and exported on a schedule. On shutdown, spans still in the buffer are flushed in `teardown()`. See [Production Configuration](/documentation/serverless/observability/opentelemetry-production) for how to configure this flush.
</Note>

## What's Next

<CardGroup cols={2}>
  <Card title="Custom Metrics" icon="chart-bar" href="/documentation/serverless/observability/custom-metrics">
    Add counters, histograms, and gauges to your app
  </Card>

  <Card title="Cross-Service Tracing" icon="diagram-project" href="/documentation/serverless/observability/opentelemetry-cross-service">
    Connect traces across two fal apps into a single parent trace
  </Card>

  <Card title="Production Configuration" icon="sliders" href="/documentation/serverless/observability/opentelemetry-production">
    Sampling, batch export tuning, and graceful flush on shutdown
  </Card>

  <Card title="App Lifecycle" icon="rotate" href="/documentation/development/app-lifecycle">
    How setup() and teardown() fit into the runner lifecycle
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/observability/slack-notifications.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack Notifications

> Receive real-time alerts in Slack when your apps fail to start.

Connect Slack to your fal account to receive notifications when your applications encounter startup issues. Get alerted immediately when a runner fails, so you can investigate before users are affected.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=570&end=633&autoplay=1'><img src='/docs/images/video-thumbs/slack-notifications.jpg' alt='Slack Notifications - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## Setting Up Slack

<Steps>
  <Step title="Go to Notification Settings">
    Navigate to [**Dashboard > Notifications > Settings**](https://fal.ai/dashboard/notifications/settings)
  </Step>

  <Step title="Connect Slack">
    Click **Add to Slack** to begin the OAuth flow. This installs the fal bot into your Slack workspace.
  </Step>

  <Step title="Choose a Channel">
    Select the Slack channel where you want to receive notifications. The fal bot will automatically join this channel.
  </Step>
</Steps>

<Note>
  Any authenticated team member can connect Slack to receive notifications.
</Note>

## What You'll Be Notified About

### App Startup Timeout

Triggered when a runner's `setup()` method doesn't complete within the configured `startup_timeout`. The notification includes:

* App name and runner ID
* The timeout duration that was exceeded
* Link to logs for investigation
* Link to the startup timeout documentation

This typically indicates your model loading or initialization is taking too long. Consider optimizing your `setup()` method or increasing the `startup_timeout` value.

### App Startup Failure

Triggered when a runner's `setup()` method throws an error. The notification includes:

* App name and runner ID
* Link to logs to see the full error traceback

Common causes include missing dependencies, incorrect model paths, or out-of-memory errors during model loading.

### Queue Size Threshold

Triggered when the number of requests waiting in your app's queue exceeds a threshold over a time window. This usually means your app isn't scaling fast enough to meet demand, or callers are sending more traffic than your `max_concurrency` can handle.

### HTTP 5xx Threshold

Triggered when the number of HTTP 5xx responses from your app exceeds a threshold over a time window. A spike in server errors often points to a crashing endpoint, a bad deployment, or resource exhaustion.

## Per-App Notification Settings

You can configure alert thresholds for each app from the dashboard. These control when queue size and error rate notifications fire.

| Setting                         | Default | Description                                       |
| ------------------------------- | ------- | ------------------------------------------------- |
| `queue_size_threshold`          | 100     | Number of queued requests that triggers an alert  |
| `queue_size_threshold_duration` | 1h      | Lookback window for queue size (e.g., `5m`, `1h`) |
| `http_5xx_threshold`            | 100     | Number of 5xx responses that triggers an alert    |
| `http_5xx_threshold_duration`   | 1h      | Lookback window for 5xx count (e.g., `5m`, `1h`)  |

Set a threshold to `null` to disable that notification type. Lower durations (e.g., `5m`) make alerts more sensitive to short spikes; longer durations (e.g., `1h`) smooth out transient errors.

## Managing Your Connection

From the [Notification Settings](https://fal.ai/dashboard/notifications/settings) page you can:

* **View connection status** -- See if Slack is connected, and which workspace and channel are configured
* **Change channel** -- Switch notifications to a different Slack channel
* **Reconnect** -- If the bot token expires or the bot is removed from your workspace, reconnect with one click

## Troubleshooting

**Not receiving notifications?**

* Verify the fal bot is still in your selected channel (it may have been removed)
* Check that your Slack connection hasn't expired in the notification settings
* Ensure the app experiencing issues belongs to your team account

**Bot was removed from workspace?**

* Go to notification settings and click **Reconnect** to re-authorize the fal bot

<Card title="Monitor Performance" icon="arrow-right" href="/documentation/serverless/observability/monitor-performance">
  View real-time metrics and logs in the fal dashboard
</Card>


# https://fal.ai/docs/documentation/serverless/optimizations/cold-start-scaling.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Adjust Scaling Parameters

> Reduce cold starts by keeping warm runners available.

The most effective way to reduce cold starts is maintaining warm runners using scaling parameters. These control how many runners stay alive and how quickly new ones spin up.

## `keep_alive`

**Default:** 60 seconds

Keep runners alive after their last request completes.

```python theme={null}
class MyApp(fal.App):
    keep_alive = 300  # Keep alive for 5 minutes
```

**Benefits:** Runners stay warm between requests, reduces cold starts for sporadic traffic

**Trade-offs:** Longer keep\_alive = higher costs; shorter = more cold starts

<Note>
  For apps without `min_concurrency` or `concurrency_buffer`, a newly started runner that never picks up a request is shut down after 10 seconds instead of waiting for the full `keep_alive` period.
</Note>

## `min_concurrency`

**Default:** 0

Maintain minimum runners alive at all times, regardless of traffic.

```python theme={null}
class MyApp(fal.App):
    min_concurrency = 2  # Always keep 2 runners warm
```

**Benefits:** Guarantees warm runners always available, eliminates cold starts for baseline capacity

**Trade-offs:** Costs money even with zero traffic

## `concurrency_buffer`

**Default:** 0

Maintain extra runners beyond current demand.

```python theme={null}
class MyApp(fal.App):
    concurrency_buffer = 2  # Keep 2 extra runners ready
```

**Benefits:** Cushion for sudden traffic increases, reduces cold starts during bursts

**Trade-offs:** Higher cost during all traffic levels

<Note>
  Takes precedence over `min_concurrency` when higher.
</Note>

## `concurrency_buffer_perc`

**Default:** 0

Set buffer as a percentage of current request volume.

```python theme={null}
class MyApp(fal.App):
    concurrency_buffer_perc = 20  # 20% buffer
```

**Benefits:** Scales buffer with traffic automatically

**Trade-offs:** No buffer during zero traffic, expensive during high traffic

<Note>
  Actual buffer is the maximum of `concurrency_buffer` and `concurrency_buffer_perc / 100 * request volume`.
</Note>

## `max_multiplexing`

**Default:** 1

Number of concurrent requests each runner handles simultaneously.

```python theme={null}
class MyApp(fal.App):
    max_multiplexing = 4  # Each runner handles up to 4 requests
```

**Benefits:** Fewer runners needed, fewer cold starts, better resource utilization

**Trade-offs:** Must use async handlers, each request gets fewer resources, not suitable for all workloads

## `scaling_delay`

**Default:** 0 seconds

Wait time before scaling up when a request is queued.

```python theme={null}
class MyApp(fal.App):
    scaling_delay = 30  # Wait 30 seconds before scaling
```

**Benefits:** Prevents premature scaling for brief spikes, reduces unnecessary cold starts

**Trade-offs:** Requests wait longer during genuine traffic increases

## `startup_timeout`

**Default:** Varies

Maximum time allowed for `setup()` to complete.

```python theme={null}
class MyApp(fal.App):
    startup_timeout = 600  # 10 minutes for setup
```

**Benefits:** Prevents runners from being killed during long setups, accommodates large model loading

**Trade-offs:** Doesn't reduce cold starts (only prevents failed startups), long timeouts can mask real issues

## Persistence Across Deploys

Scaling parameters set via CLI or dashboard (`keep_alive`, `min_concurrency`, `concurrency_buffer`, etc.) **persist across deployments** by default. You don't lose your tuning when you deploy a code change.

To reset all parameters back to code values, deploy with `--reset-scale`:

```bash theme={null}
fal deploy --reset-scale
```

<Card title="Deploy Behavior & Priority" icon="arrow-right" href="/documentation/deployment/scale-your-application#deploy-behavior-and---reset-scale">
  Full explanation of how code, CLI, and dashboard settings interact
</Card>

## Cost Considerations

More warm runners = lower latency but higher cost. Balance based on your needs:

* **Latency-critical apps**: Accept higher cost for warm runners (`min_concurrency`, `keep_alive`)
* **Cost-sensitive apps**: Optimize cold start duration instead (container images, caching)
* **Variable traffic**: Use buffers and scaling delays

<Card title="Full Scaling Reference" icon="arrow-right" href="/documentation/deployment/scale-your-application">
  Complete guide to scaling configuration including CLI and dashboard methods
</Card>


# https://fal.ai/docs/documentation/serverless/optimizations/flashpack.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# FlashPack

> High-throughput tensor loading for PyTorch -- load models at up to 25Gbps without GDS.

[FlashPack](https://github.com/fal-ai/flashpack) is an open-source library by fal that dramatically speeds up model loading by streaming weights directly from disk to GPU with zero-copy reconstruction. Use it in your `setup()` method to reduce cold start times.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=633&end=732&autoplay=1'><img src='/docs/images/video-thumbs/flashpack.jpg' alt='FlashPack - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## How It Works

### 1. Flatten weights into contiguous macroblocks

At save/convert time, FlashPack takes the model's entire `state_dict`, groups tensors by data type, then flattens them into one contiguous stream of bytes. A compact weight map at the end of the file stores every parameter's key, shape, and offset.

### 2. Stream with overlapping disk, CPU, and GPU transfers

When loading, FlashPack memory-maps the file and divides it into mid-sized CPU buffers (up to 64MB each). These buffers load in a round-robin pattern, keeping disk reads continuous. Each CPU buffer is paired with a dedicated CUDA stream -- while one stream writes to VRAM, another buffer is already being loaded from disk.

### 3. Rebuild parameters as zero-copy views

Once data is on the GPU, FlashPack reconstructs each tensor as a view into the flat memory block and creates new `nn.Parameter` instances with direct references to the loaded bytes. No copies, no moves -- the model is immediately ready to run.

***

## Integration Methods

### Direct Function Calling

The simplest approach when you don't want to modify your module code:

```python theme={null}
from flashpack import pack_to_file, assign_from_file

flashpack_path = "/data/models/my-model.flashpack"
model = MyModel(...)

pack_to_file(model, flashpack_path)
assign_from_file(model, flashpack_path)
```

### PyTorch Mixin

Add `FlashPackMixin` to your module for `save_flashpack` and `from_flashpack` methods:

```python theme={null}
from flashpack import FlashPackMixin

class MyModule(nn.Module, FlashPackMixin):
    def __init__(self, some_arg: int = 4) -> None:
        ...

module = MyModule(some_arg=4)
module.save_flashpack("model.flashpack")

loaded_module = MyModule.from_flashpack("model.flashpack", some_arg=4)
```

### Diffusers Models

Use `FlashPackDiffusersModelMixin` for diffusers models with `from_pretrained_flashpack` and `save_pretrained_flashpack`:

```python theme={null}
from flashpack.integrations.diffusers import FlashPackDiffusersModelMixin
from diffusers.models import AutoencoderKL

class FlashPackAutoencoderKL(FlashPackDiffusersModelMixin, AutoencoderKL):
    pass

# Load from original weights
sdxl_vae = FlashPackAutoencoderKL.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    variant="fp16",
    subfolder="vae",
)

# Save as FlashPack (optionally push to HuggingFace)
sdxl_vae.save_pretrained_flashpack(
    "/path/to/save/directory",
    push_to_hub=True,
    repo_id="my-org/sdxl-vae-flashpack",
)

# Load from FlashPack
sdxl_vae = FlashPackAutoencoderKL.from_pretrained_flashpack(
    "my-org/sdxl-vae-flashpack",
    device_map="cuda",
)
```

### Transformers Models

Works the same way with `FlashPackTransformersModelMixin`:

```python theme={null}
from flashpack.integrations.transformers import FlashPackTransformersModelMixin
from transformers import CLIPTextModel

class FlashPackCLIPTextModel(FlashPackTransformersModelMixin, CLIPTextModel):
    pass

# Load, convert, and save
clip = FlashPackCLIPTextModel.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    variant="fp16",
    subfolder="text_encoder",
)
clip.save_pretrained_flashpack(
    "/path/to/save/directory",
    push_to_hub=True,
    repo_id="my-org/sdxl-text-encoder-flashpack",
)

# Load from FlashPack
clip = FlashPackCLIPTextModel.from_pretrained_flashpack(
    "my-org/sdxl-text-encoder-flashpack",
    device_map="cuda",
)
```

### Diffusers Pipelines

FlashPack pipelines are made of FlashPack-enabled models. You don't need to enable FlashPack on every model in a pipeline -- it automatically uses `from_pretrained_flashpack` for FlashPack-enabled models and `from_pretrained` for the rest.

```python theme={null}
from typing import Optional
from diffusers import AutoencoderKL, StableDiffusionXLPipeline, UNet2DConditionModel
from diffusers.schedulers import KarrasDiffusionSchedulers
from flashpack.integrations.diffusers import (
    FlashPackDiffusersModelMixin,
    FlashPackDiffusionPipeline,
)
from flashpack.integrations.transformers import FlashPackTransformersModelMixin
from transformers import (
    CLIPImageProcessor,
    CLIPTextModel,
    CLIPTextModelWithProjection,
    CLIPTokenizer,
    CLIPVisionModelWithProjection,
)

# Define FlashPack-enabled classes
class FlashPackCLIPTextModel(FlashPackTransformersModelMixin, CLIPTextModel):
    pass

class FlashPackCLIPTextModelWithProjection(
    FlashPackTransformersModelMixin, CLIPTextModelWithProjection
):
    pass

class FlashPackAutoencoderKL(FlashPackDiffusersModelMixin, AutoencoderKL):
    pass

class FlashPackUNet2DConditionModel(FlashPackDiffusersModelMixin, UNet2DConditionModel):
    pass

class FlashPackStableDiffusionXLPipeline(
    FlashPackDiffusionPipeline, StableDiffusionXLPipeline
):
    def __init__(
        self,
        vae: FlashPackAutoencoderKL,
        text_encoder: FlashPackCLIPTextModel,
        text_encoder_2: FlashPackCLIPTextModelWithProjection,
        tokenizer: CLIPTokenizer,
        tokenizer_2: CLIPTokenizer,
        unet: FlashPackUNet2DConditionModel,
        scheduler: KarrasDiffusionSchedulers,
        feature_extractor: Optional[CLIPImageProcessor] = None,
        image_encoder: Optional[CLIPVisionModelWithProjection] = None,
        add_watermarker: Optional[bool] = None,
        force_zeros_for_empty_prompt: bool = True,
    ) -> None:
        super().__init__(
            vae=vae,
            text_encoder=text_encoder,
            text_encoder_2=text_encoder_2,
            tokenizer=tokenizer,
            tokenizer_2=tokenizer_2,
            unet=unet,
            scheduler=scheduler,
            feature_extractor=feature_extractor,
            image_encoder=image_encoder,
            add_watermarker=add_watermarker,
            force_zeros_for_empty_prompt=force_zeros_for_empty_prompt,
        )

# Save entire pipeline as FlashPack
pipeline = FlashPackStableDiffusionXLPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    variant="fp16",
)
pipeline.save_pretrained_flashpack(
    "flashpack-sdxl",
    push_to_hub=True,
    repo_id="my-org/sdxl-flashpack",
)

# Load from FlashPack -- immediately ready to use
pipeline = FlashPackStableDiffusionXLPipeline.from_pretrained_flashpack(
    "my-org/sdxl-flashpack",
    device_map="cuda",
)
image = pipeline("A sunset over mountains", num_inference_steps=50).images[0]
```

<Note>
  Use `Optional[]` syntax (not `| None`) for optional pipeline parameters. This is a limitation in diffusers, not FlashPack.
</Note>

***

## CLI Commands

FlashPack includes a CLI for converting, inspecting, and reverting files.

### Convert a model

```bash theme={null}
# Convert a local model
flashpack convert ./my_model ./my_model.flashpack

# Convert from HuggingFace
flashpack convert stabilityai/stable-diffusion-xl-base-1.0 \
  --subfolder unet --use-diffusers

# Convert with specific dtype
flashpack convert ./my_model ./my_model.flashpack --dtype float16
```

### Inspect metadata

```bash theme={null}
flashpack metadata ./my_model.flashpack
flashpack metadata ./my_model.flashpack --show-index --json
```

### Revert to safetensors

```bash theme={null}
flashpack revert ./my_model.flashpack ./my_model.safetensors
```

***

## Using FlashPack on fal

Convert your model to FlashPack format, store it on `/data` or HuggingFace, and load in `setup()`:

```python theme={null}
import fal
from flashpack import assign_from_file

class MyModel(fal.App):
    machine_type = "GPU-A100"
    requirements = ["flashpack", "torch", "diffusers"]

    def setup(self):
        import torch
        from my_model import build_model

        self.model = build_model()
        assign_from_file(self.model, "/data/models/my-model.flashpack")

    @fal.endpoint("/")
    def generate(self, prompt: str) -> dict:
        return self.model(prompt)
```

Or with the Diffusers integration:

```python theme={null}
import fal

class SDXLApp(fal.App):
    machine_type = "GPU-A100"
    requirements = ["flashpack", "torch", "diffusers", "transformers"]

    def setup(self):
        from my_flashpack_classes import FlashPackStableDiffusionXLPipeline

        self.pipe = FlashPackStableDiffusionXLPipeline.from_pretrained_flashpack(
            "my-org/sdxl-flashpack",
            device_map="cuda",
        )

    @fal.endpoint("/")
    def generate(self, prompt: str) -> dict:
        image = self.pipe(prompt, num_inference_steps=30).images[0]
        return {"image": fal.toolkit.Image.from_pil(image)}
```

<Tip>
  Store FlashPack files on `/data` for automatic caching across cold starts. The first runner downloads the file, and subsequent runners load from the cached copy.
</Tip>

<Card title="GitHub Repository" icon="github" href="https://github.com/fal-ai/flashpack">
  View source, benchmarks, and contribute on GitHub
</Card>


# https://fal.ai/docs/documentation/serverless/optimizations/optimize-cold-starts.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimizing Cold Starts

> Understanding cold starts and how to reduce them.

## Cold Starts vs Warm Starts

A **cold start** occurs when a new runner needs to be created from scratch. The runner goes through `PENDING` → `SETUP` → `IDLE` (or `PENDING` → `DOCKER_PULL` → `SETUP` → `IDLE` if the Docker image isn't [cached](/documentation/deployment/caching)) before it can serve requests.

A **warm start** occurs when an existing IDLE runner is reused to handle a new request: `IDLE` → `RUNNING`.

### What Triggers Cold Starts

* No warm runners available (all busy or expired)
* Traffic spike exceeds warm runner capacity
* First deployment
* Runners expired during low traffic periods

### Factors Affecting Cold Start Duration

* **Image size**: Larger Docker images take longer to pull
* **Model size**: Larger models take longer to download and load
* **Setup complexity**: Complex initialization in `setup()` adds time
* **Cache state**: First runs are slower, subsequent runs benefit from caching
* **Hardware availability**: GPU availability varies by region and time

## How to Reduce Cold Starts

Each of these strategies targets a different phase of the cold start:

<CardGroup cols={2}>
  <Card title="Scaling Parameters" icon="sliders" href="/documentation/serverless/optimizations/cold-start-scaling">
    Keep warm runners available with keep\_alive, min\_concurrency, and buffers
  </Card>

  <Card title="Container Images" icon="docker" href="/documentation/serverless/optimizations/optimize-container-images">
    Reduce image size for faster pulls with multi-stage builds and smaller base images
  </Card>

  <Card title="Compiled Caches" icon="bolt" href="/documentation/serverless/optimizations/optimize-startup-with-compiled-caches">
    Cache compiled kernels to speed up setup() across runners
  </Card>

  <Card title="Persistent Storage" icon="hard-drive" href="/documentation/development/use-persistent-storage">
    Download models to /data for automatic caching between runners
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/optimizations/optimize-container-images.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimize Container Images

> Container optimization is key to achieving faster cold starts, reducing deployment sizes, and improving overall application performance. This guide covers Dockerfile optimization techniques, layer caching strategies, multi-stage builds, and build performance improvements to help you create efficient containers for your fal.ai applications.

## Overview

Under the hood, we use [buildkit](https://docs.docker.com/build/buildkit) (or [docker buildx](https://docs.docker.com/reference/cli/docker/buildx)) to build docker images. This allows us to take advantage of advanced caching mechanisms to improve build times and reduce resource consumption. In this guide, we'll provide some guidelines for creating cache-efficient Dockerfiles.

<Note>
  **Note**

  Ensure you have Docker Buildx and BuildKit enabled in your Docker environment
  if you want to test your containers locally. Otherwise, you don't need to
  worry about it. fal platform takes care of it for you when you deploy your
  application using container support.
</Note>

Check out the [Docker buildx documentation](https://github.com/docker/buildx) for more information.

## General Guidelines

<Note>
  **Note**

  Please also refer to the [Dockerfile best
  practices](https://docs.docker.com/build/building/best-practices) for detailed
  information on Dockerfile best practices.
</Note>

### 1. Minimize Layers

Each `RUN`, `COPY`, or `ADD` instruction creates a new layer. Minimize the number of layers by combining commands.

**Bad Example:**

```dockerfile theme={null}
RUN apt-get update
RUN apt-get install -y curl
```

**Good Example:**

```dockerfile theme={null}
RUN apt-get update && apt-get install -y curl
```

### 2. Leverage Layer Caching

Order instructions from least to most frequently changing to maximize layer caching.

**Example:**

```dockerfile theme={null}
# Install dependencies (changes less frequently)
COPY requirements.txt /app/
RUN pip install -r requirements.txt

# Copy application code (changes more frequently)
COPY . /app
```

### 3. Use `--mount=type=cache`

Utilize BuildKit's `--mount=type=cache` to cache directories across builds.

**Example:**

<CodeGroup>
  ```dockerfile 1.3-labs theme={null}
  # syntax=docker/dockerfile:1.3-labs
  FROM python:3.9

  # Use BuildKit cache for pip
  RUN --mount=type=cache,target=/root/.cache/pip \
      pip install --upgrade pip

  COPY requirements.txt /app/
  RUN --mount=type=cache,target=/root/.cache/pip \
      pip install -r requirements.txt

  COPY . /app
  ```
</CodeGroup>

### 4. Multi-Stage Builds

Use multi-stage builds to reduce the final image size by copying only the necessary artifacts from intermediate stages.

**Example:**

<CodeGroup>
  ```dockerfile 1.3 theme={null}
  # syntax=docker/dockerfile:1.3
  FROM python:3.9 AS builder
  WORKDIR /app
  COPY . .
  RUN pip install --upgrade pip \
   && pip install -r requirements.txt

  FROM python:3.9-slim
  COPY --from=builder /app /app
  WORKDIR /app
  ENTRYPOINT ["python", "app.py"]
  ```
</CodeGroup>

### 5. Clean Up After Installations

Remove unnecessary files and caches after installing packages to keep the image size small.

**Example:**

```dockerfile theme={null}
RUN apt-get update && apt-get install -y \
    build-essential \
 && rm -rf /var/lib/apt/lists/*
```

### 6. Use `.dockerignore`

Specify files and directories to ignore during the build process to avoid unnecessary files in the build context.

fal supports `.dockerignore` files when using `COPY` and `ADD` commands in your Dockerfile. Create a `.dockerignore` file in your project root to exclude files:

**Example:**

```plaintext theme={null}
# .dockerignore
.git
.venv
venv
__pycache__
*.pyc
*.pyo
.env
node_modules
```

You can also define ignore patterns programmatically:

```python theme={null}
from fal.container import ContainerImage

image = ContainerImage.from_dockerfile_str(dockerfile_str)
image.add_dockerignore(patterns=[".git", "*.pyc", ".env"])
```

If no `.dockerignore` exists, fal uses sensible defaults that exclude common development artifacts. See the [custom container image guide](/serverless/development/use-custom-container-image#dockerignore-support) for more details.

## Complete Example

Here is an example of a cache-efficient Dockerfile using the principles outlined above:

<CodeGroup>
  ```dockerfile 1.3 theme={null}
  # syntax=docker/dockerfile:1.3
  FROM python:3.9 AS base
  WORKDIR /app

  # Install dependencies
  COPY requirements.txt ./
  RUN --mount=type=cache,target=/root/.cache/pip \
      pip install --upgrade pip \
   && pip install -r requirements.txt

  # Copy source files
  COPY . .

  # Build the application
  RUN python setup.py build

  # Production image
  FROM python:3.9-slim
  COPY --from=base /app /app
  WORKDIR /app
  ENTRYPOINT ["python", "app.py"]
  ```
</CodeGroup>

## Conclusion

By following these guidelines, you can create Dockerfiles that build efficiently and take full advantage of Docker Buildx and BuildKit's caching capabilities. This will lead to faster build times and reduced resource usage.

For more detailed information, refer to the [Docker documentation](https://docs.docker.com/build).


# https://fal.ai/docs/documentation/serverless/optimizations/optimize-startup-with-compiled-caches.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimize Startup with Compiled Caches

> Reduce cold-start time for compiled PyTorch models by sharing Inductor caches across workers.

When using `torch.compile()` with PyTorch models, the first run compiles optimized CUDA kernels, which can take significant time. By sharing these compiled kernels across workers, you can dramatically reduce startup latency for subsequent workers.

<Frame>
  <iframe className="w-full aspect-video rounded-lg" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href='https://www.youtube.com/embed/gDJJ9bppyV8?start=732&end=775&autoplay=1'><img src='/docs/images/video-thumbs/optimize-startup-with-compiled-caches.jpg' alt='Kernel Caching - fal Serverless'><span>▶</span></a>" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen />
</Frame>

## The Problem

PyTorch's Inductor compiler (`torch.compile`) generates optimized GPU kernels on first run. Without cache sharing:

* **Every worker recompiles** the same kernels, wasting GPU time
* **Startup latency multiplies** across workers (N workers × compilation time)
* **GPU resources** are used inefficiently during deployment

With Inductor cache sharing:

* **One worker compiles** during initial warmup
* **Other workers load** pre-compiled kernels (significantly faster)
* **Consistent performance** across all workers

## Quick Start

The simplest way to use Inductor caching is with the `synchronized_inductor_cache` context manager:

```python theme={null}
from fal.toolkit import synchronized_inductor_cache

class MyApp(fal.App):
    def setup(self):
        # Load model
        self.model = load_model()
        
        # Wrap compilation + warmup in cache context
        with synchronized_inductor_cache("my-model/v1"):
            self.model = torch.compile(self.model)
            self.warmup()
```

That's it! The first worker compiles and saves to `/data/inductor-caches/<GPU_TYPE>/<cache_key>.zip` (on the shared `/data` filesystem accessible to all workers), while subsequent workers load the pre-compiled kernels.

## API Reference

### `synchronized_inductor_cache(cache_key: str)`

A context manager that handles both loading and syncing of Inductor caches automatically.

**Parameters:**

* `cache_key` (str): A unique identifier for this cache. Use a descriptive name with versioning (e.g., `"my-model/v1"`).

**Usage:**

```python theme={null}
with synchronized_inductor_cache("my-model/v1"):
    # Any torch.compile() calls and warmup inside this block
    # will use the shared cache
    model = torch.compile(model)
    warmup()
```

**Behavior:**

* Loads existing cache from `/data/inductor-caches/` if available
* After the context exits, syncs any newly compiled kernels back to shared storage
* Handles GPU-specific cache organization automatically

### `load_inductor_cache(cache_key: str) -> str`

Explicitly loads an Inductor cache from shared storage.

**Parameters:**

* `cache_key` (str): The cache identifier to load.

**Returns:**

* `str`: A directory hash representing the cache state. Pass this to `sync_inductor_cache()` later.

**Usage:**

```python theme={null}
dir_hash = load_inductor_cache("my-model/v1")
# ... compilation and warmup ...
sync_inductor_cache("my-model/v1", dir_hash)
```

### `sync_inductor_cache(cache_key: str, dir_hash: str) -> None`

Syncs the local Inductor cache back to shared storage.

**Parameters:**

* `cache_key` (str): The cache identifier to sync.
* `dir_hash` (str): The directory hash returned by `load_inductor_cache()`.

**Behavior:**

* Compares local cache with the hash to detect new compiled kernels
* If changes detected, re-packs and uploads entire cache to `/data/inductor-caches/`
* If no changes, skips upload (no-op)

## Complete Working Example

Here's a complete, runnable example using Stable Diffusion Turbo that demonstrates the actual speedup:

```python theme={null}
import fal
from fal.toolkit import Image, synchronized_inductor_cache
from pydantic import BaseModel, Field

class Input(BaseModel):
    prompt: str = Field(
        description="Text prompt for image generation",
        examples=["A serene lake at sunset with mountains"],
    )
    width: int = Field(
        default=512,
        description="Image width",
    )
    height: int = Field(
        default=512,
        description="Image height",
    )

class Output(BaseModel):
    image: Image

class SDTurbo(fal.App):
    machine_type = "GPU-H100"
    keep_alive = 300  # 5 minutes - keep warm between requests
    startup_timeout = 900  # 15 minutes - allow time for compilation
    requirements = [
        "torch==2.5.0",
        "diffusers==0.31.0",
        "transformers",
        "accelerate",
        "nvidia-cuda-nvrtc-cu12",
    ]

    def setup(self) -> None:
        # Workaround for cuDNN SDPA on CUDA 12.x
        # This makes the NVRTC library globally available for cuDNN kernel compilation
        import ctypes
        import os
        from nvidia.cuda_nvrtc import lib as nvrtc_lib
        
        nvrtc_lib_path = os.path.dirname(nvrtc_lib.__file__)
        nvrtc_lib_so = os.path.join(nvrtc_lib_path, "libnvrtc.so.12")
        ctypes.CDLL(nvrtc_lib_so, mode=ctypes.RTLD_GLOBAL)

        import torch
        from diffusers import AutoPipelineForText2Image

        print("Loading SD-Turbo model...")
        self.pipeline = AutoPipelineForText2Image.from_pretrained(
            "stabilityai/sd-turbo",
            torch_dtype=torch.float16,
            variant="fp16",
        ).to("cuda")
        print("Model loaded!")

        # Share compiled kernels across workers
        with synchronized_inductor_cache("sd-turbo/v1"):
            print("Compiling UNet with torch.compile()...")
            self.pipeline.unet = torch.compile(
                self.pipeline.unet,
                mode="default",  
                dynamic=True,
            )

            # Warmup with common resolutions to trigger compilation
            print("Warming up with common resolutions...")
            for width, height in [(512, 512), (768, 512)]:
                self.pipeline(
                    prompt="warmup",
                    num_inference_steps=1,
                    width=width,
                    height=height,
                    guidance_scale=0.0,  # SD-Turbo doesn't use guidance
                )
            print("Warmup complete!")
            
            # Prevent recompilation and CUDA graphs threading issues
            self.pipeline.unet.forward = torch._dynamo.run(self.pipeline.unet.forward)

    @fal.endpoint("/")
    def generate(self, input: Input) -> Output:
        """Generate an image from a text prompt."""
        result = self.pipeline(
            prompt=input.prompt,
            num_inference_steps=1,
            width=input.width,
            height=input.height,
            guidance_scale=0.0,  # SD-Turbo doesn't use guidance
        )
        return Output(image=Image.from_pil(result.images[0]))
```

**Try it yourself:**

```bash theme={null}
# Save as sd_turbo.py
fal run sd_turbo.py

# First worker: Compiles kernels during warmup
# Subsequent workers: Load pre-compiled kernels (much faster)
```

**What you'll observe:**

* First worker takes longer during warmup (compilation happening)
* Subsequent workers warmup significantly faster (loading cached kernels)
* All workers produce identical outputs - only startup time changes

## Manual Approach (Advanced)

For more control over cache loading and syncing, you can use the explicit API:

```python theme={null}
from fal.toolkit import load_inductor_cache, sync_inductor_cache

class MyApp(fal.App):
    def setup(self):
        # Load existing cache (if available)
        dir_hash = load_inductor_cache("my-model/v1")
        
        # Compile and warmup
        self.model = torch.compile(self.model)
        self.warmup()
        
        # Sync back any new kernels
        sync_inductor_cache("my-model/v1", dir_hash)
```

**When to use the manual approach:**

* Multi-stage warmup processes
* Distributed training with controlled sync timing
* Need explicit control over cache load/sync behavior

## How It Works

### Storage Locations & Connection Mechanism

* **Local cache**: `/tmp/inductor-cache/` - Each worker's temporary cache
* **Shared cache**: `/data/inductor-caches/<GPU_TYPE>/<key>.zip` - Persistent, shared across workers

**How torch.compile() finds the cache:**

When `load_inductor_cache()` is called, it sets the environment variable:

```python theme={null}
os.environ["TORCHINDUCTOR_CACHE_DIR"] = "/tmp/inductor-cache/"
```

PyTorch's `torch.compile()` automatically reads this environment variable to locate compiled kernels. You don't need to configure anything - just call `load_inductor_cache()` before `torch.compile()` and the connection happens automatically.

### GPU Separation

Caches are GPU-specific (H100, H200, A100, etc.) and automatically organized by GPU type using `get_gpu_type()`. This ensures compiled kernels match the hardware they'll run on.

### Process Flow

The behavior differs based on whether a cache already exists:

**Cache Miss (First Worker):**

1. Load attempt → Cache not found
2. Compilation phase → torch.compile() generates CUDA kernels
3. Kernels saved to `/tmp/inductor-cache/`
4. Warmup triggers compilation
5. Sync creates `.zip` and uploads to `/data/inductor-caches/<GPU_TYPE>/<cache_key>.zip`

**Cache Hit (Subsequent Workers):**

1. Load attempt → Cache found
2. Extract `.zip` to `/tmp/inductor-cache/`
3. torch.compile() finds existing kernels
4. Warmup uses cached kernels (no compilation)
5. Sync compares hash → Usually no-op (no changes to upload)

**Key Insight:** The "sync" operation is intelligent - it only uploads if new kernels were generated.

<Note>
  This does **not** change model outputs or behavior - only startup speed changes. The compiled model produces identical results to the uncompiled version.
</Note>

## Best Practices

### Warmup Coverage

Warm up with representative input shapes to maximize cache coverage:

```python theme={null}
with synchronized_inductor_cache("my-model/v1"):
    self.model = torch.compile(
        self.model,
        mode="max-autotune",
        dynamic=True,  # Important! Allows flexibility
    )
    
    # Cover common input sizes
    for width, height in [(512, 512), (768, 512), (1024, 1024)]:
        self.warmup(width, height)
```

**Tips:**

* Use `dynamic=True` for flexibility across input variations
* Cover 3-5 representative sizes
* Focus on your most common use cases
* **Tradeoff**: More warmup shapes = longer startup, but faster inference

### When to Skip

Not all models benefit from Inductor caching:

* **CPU-only models** - No GPU compilation involved
* **Models without torch.compile** - No Inductor caching needed
* **Lightweight models** - Minimal compilation overhead, caching may not be worth it

## Troubleshooting

### Workers Still Compiling (Cache Not Working)?

If you see compilation happening on every worker despite using `synchronized_inductor_cache`:

**1. Verify you're calling warmup inside the cache context**

```python theme={null}
# ❌ Wrong - warmup outside cache context
with synchronized_inductor_cache("model/v1"):
    model = torch.compile(model)
# Warmup after context exits - not cached!
warmup()

# ✅ Correct - warmup inside cache context
with synchronized_inductor_cache("model/v1"):
    model = torch.compile(model)
    warmup()  # Triggers compilation, cache is saved
```

**2. Use `dynamic=True` for flexible input shapes**

```python theme={null}
# ❌ Without dynamic - compiles separately for each shape
model = torch.compile(model, mode="max-autotune")
warmup(512, 512)   # Compiles for 512x512
# Later: different size triggers recompilation
generate(768, 768)  # Recompiles for 768x768!

# ✅ With dynamic - handles shape variations
model = torch.compile(model, mode="max-autotune", dynamic=True)
warmup(512, 512)   # Compiles with dynamic shapes
generate(768, 768)  # Uses cached kernels! ✓
```

**3. Cover common input shapes in warmup**

If you see compilation during inference, you can add those shapes to warmup (note: this increases startup time):

```python theme={null}
with synchronized_inductor_cache("model/v1"):
    model = torch.compile(model, dynamic=True)
    
    # Warmup with all commonly used sizes
    for size in [(512, 512), (768, 512), (1024, 1024)]:
        warmup(*size)
```

### Debugging

Enable verbose logging to see what PyTorch is doing:

```python theme={null}
import os
os.environ["TORCH_LOGS"] = "recompiles"
os.environ["TORCHINDUCTOR_VERBOSE"] = "1"

# Now you'll see detailed compilation messages
```

## See Also

<CardGroup cols={2}>
  <Card title="Optimize Model Performance" icon="rocket" href="/serverless/optimizations/optimize-model-performance">
    Learn about torch.compile and the `optimize()` helper
  </Card>

  <Card title="Use Persistent Storage" icon="database" href="/serverless/development/use-persistent-storage">
    Understand the `/data` directory for persistent storage
  </Card>

  <Card title="Deploy Multi-GPU Inference" icon="server" href="/serverless/tutorials/deploy-multi-gpu-inference">
    Deploy large compiled models across multiple GPUs
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/optimizations/optimizing-costs.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimizing Costs

Since Serverless billing covers the entire runner lifetime, the most effective cost optimizations focus on reducing idle time, maximizing utilization, and minimizing setup duration.

## Reduce Idle Time

Idle time is the single biggest cost lever. Every second a runner is alive but not processing requests is billed.

### Tune `keep_alive`

The `keep_alive` parameter controls how long a runner stays alive after finishing its last request. Lower values reduce idle billing but increase cold starts.

```python theme={null}
class MyApp(fal.App, keep_alive=30):  # 30 seconds (default: 60)
    ...
```

| `keep_alive`    | Trade-off                           |
| --------------- | ----------------------------------- |
| High (300s+)    | Low latency, higher idle costs      |
| Medium (30-60s) | Balanced for moderate traffic       |
| Low (10-30s)    | Cost-efficient for bursty workloads |

### Set `min_concurrency` carefully

Each runner in `min_concurrency` runs continuously and is billed 24/7. Only use it for latency-critical applications that cannot tolerate cold starts.

```python theme={null}
class MyApp(fal.App, min_concurrency=0):  # No always-on runners
    ...
```

## Maximize Runner Utilization

Runners that process one request at a time have idle gaps between sequential requests. Multiplexing eliminates these gaps.

### Use multiplexing

`max_multiplexing` allows a single runner to process multiple requests concurrently, filling idle time while one request waits on I/O.

```python theme={null}
class MyApp(fal.App, max_multiplexing=4):
    ...
```

This is especially effective for workloads with I/O waits (network calls, file downloads) where the GPU would otherwise sit idle between operations.

### Concurrency buffer

`concurrency_buffer` pre-warms runners before existing ones reach capacity. This reduces latency spikes but keeps more runners alive.

```python theme={null}
class MyApp(fal.App, max_multiplexing=4, concurrency_buffer=2):
    ...
```

Use conservatively — each buffered runner is billed while alive.

## Reduce Setup Time

Since `setup()` time is billed, faster initialization directly reduces cost per cold start. This matters most for applications with frequent cold starts (low `keep_alive`, bursty traffic).

<CardGroup cols={2}>
  <Card title="FlashPack" icon="bolt" href="/documentation/serverless/optimizations/flashpack">
    High-throughput tensor loading for faster model initialization.
  </Card>

  <Card title="Optimizing Cold Starts" icon="gauge-high" href="/documentation/serverless/optimizations/optimize-cold-starts">
    Strategies for reducing container startup and setup time.
  </Card>

  <Card title="Compiled Caches" icon="database" href="/documentation/serverless/optimizations/optimize-startup-with-compiled-caches">
    Cache compiled kernels to skip recompilation on startup.
  </Card>

  <Card title="Persistent Storage" icon="hard-drive" href="/documentation/development/file-storage">
    Use /data to cache downloads across runner restarts.
  </Card>
</CardGroup>

## Right-Size Your Machine Type

Don't over-provision GPU resources. A model that runs fine on an A6000 doesn't need an H100.

* Compare inference latency across machine types to find the smallest GPU that meets your requirements
* Consider that a cheaper machine running slightly longer may cost less than a faster, more expensive one
* See [Machine Types](/documentation/deployment/machine-types) for available options

## Use Scaling Parameters Wisely

### `scaling_delay`

Prevents spinning up new runners for short traffic spikes. The platform waits this duration before provisioning additional runners.

```python theme={null}
class MyApp(fal.App, scaling_delay=15):  # Wait 15s before scaling up
    ...
```

Useful for workloads with brief bursts that don't justify new runners.

### `max_concurrency`

Caps the total number of concurrent runners. This sets a hard ceiling on your spend but may increase queue times during traffic spikes.

```python theme={null}
class MyApp(fal.App, max_concurrency=5):  # At most 5 runners
    ...
```

## Monitor and Iterate

Use the platform's observability tools to identify cost optimization opportunities:

* **[App Analytics](/documentation/serverless/observability/app-analytics)**: Identify apps with low utilization (high idle time relative to processing time)
* **[Error Analytics](/documentation/serverless/observability/error-analytics)**: Find apps with high error rates that waste compute on failed requests
* **[Exporting Metrics](/documentation/serverless/observability/exporting-metrics)**: Set up alerts for unusual spending patterns

<Tip>
  Start with the defaults, then monitor your App Analytics for a few days. Look for runners with high idle-to-processing ratios — those are your best candidates for `keep_alive` and `min_concurrency` adjustments.
</Tip>


# https://fal.ai/docs/documentation/serverless/optimizations/parallel-file-loading.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Parallel File Loading

> Speed up model loading by pre-reading files in parallel from /data.

The `/data` filesystem on fal is a distributed, parallel storage system. It performs best when multiple files are read concurrently. Sequential file reads -- loading one weight file at a time -- significantly underutilize the filesystem and result in slower cold starts.

## The Problem

Most model loading libraries (HuggingFace, PyTorch) read weight files **sequentially** -- one shard at a time. On a distributed filesystem, this leaves most of the available bandwidth idle:

```
Sequential:
  time ──────────────────────────────────►
  ┌──file1──┐┌──file2──┐┌──file3──┐┌──file4──┐

Parallel:
  time ──────────────────►
  ┌──file1──┐
  ┌──file2──┐
  ┌──file3──┐
  ┌──file4──┐
```

## The Solution: Pre-Read Files in Parallel

Before loading your model, pre-read all weight files into the OS page cache using parallel I/O. When the model loader then reads the files, they're already cached in memory and load instantly.

```python theme={null}
import subprocess

MODEL_DIR = "/data/models/my-model"

subprocess.check_call(
    f"find '{MODEL_DIR}' -type f | xargs -P 32 -I {{}} cat {{}} > /dev/null",
    shell=True
)
```

This reads up to 32 files simultaneously, pulling them into the page cache. The subsequent `from_pretrained()` call then reads from cache instead of the network.

## Using It in Your App

Add the pre-read step at the beginning of your `setup()` method, before model loading:

```python theme={null}
import fal
import subprocess

class MyModel(fal.App):
    machine_type = "GPU-H100"

    def setup(self):
        import torch
        from diffusers import StableDiffusionXLPipeline

        model_dir = "/data/models/stable-diffusion-xl"

        # Pre-read all model files in parallel
        subprocess.check_call(
            f"find '{model_dir}' -type f | xargs -P 32 -I {{}} cat {{}} > /dev/null",
            shell=True
        )

        # Now load the model -- files are already in page cache
        self.pipe = StableDiffusionXLPipeline.from_pretrained(
            model_dir,
            torch_dtype=torch.float16,
        ).to("cuda")
```

### Python Helper

For a cleaner approach, wrap it in a function:

```python theme={null}
import subprocess
from pathlib import Path

def preload_files(directory: str, parallelism: int = 32):
    """Pre-read all files in a directory into the OS page cache."""
    subprocess.check_call(
        f"find '{directory}' -type f | xargs -P {parallelism} -I {{}} cat {{}} > /dev/null",
        shell=True
    )
```

```python theme={null}
def setup(self):
    preload_files("/data/models/my-model")
    self.model = load_model("/data/models/my-model")
```

## When to Use This

| Scenario                                                     | Recommendation                                                                                                                                |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Loading HuggingFace models from `/data`                      | Use parallel pre-reading                                                                                                                      |
| Loading custom PyTorch checkpoints with multiple shard files | Use parallel pre-reading                                                                                                                      |
| Loading a single large file                                  | Less benefit -- the bottleneck is single-file transfer speed. Consider [FlashPack](/documentation/serverless/optimizations/flashpack) instead |
| Models already in local node cache (warm runners)            | Minimal benefit -- files are already fast to read                                                                                             |

## How It Works

fal's `/data` is a distributed filesystem that can serve many files concurrently at high throughput. When you read files sequentially, you use only a fraction of the available bandwidth. The `xargs -P 32` approach fires off 32 concurrent `cat` commands, each reading a different file. The OS caches the file contents in memory (page cache), so when your model loader reads the same files moments later, it reads from RAM instead of the network.

<Tip>
  Adjust the parallelism (`-P 32`) based on your model. For models with many small files (e.g., 100+ safetensors shards), higher parallelism helps. For models with a few large files, lower parallelism (8-16) is sufficient.
</Tip>

## Comparison with FlashPack

|                         | Parallel Pre-Reading            | FlashPack                                  |
| ----------------------- | ------------------------------- | ------------------------------------------ |
| **What it does**        | Pre-reads files into OS cache   | Streams tensors directly to GPU            |
| **Works with**          | Any files in any format         | PyTorch models (custom format)             |
| **Requires conversion** | No -- works with existing files | Yes -- must convert to `.flashpack` format |
| **Best for**            | Quick win with existing models  | Maximum performance with converted models  |

Both techniques can be combined -- use parallel pre-reading as a quick improvement, then migrate to FlashPack for even faster loading.

<CardGroup cols={2}>
  <Card title="FlashPack" icon="arrow-right" href="/documentation/serverless/optimizations/flashpack">
    High-throughput tensor loading at up to 25 Gbps
  </Card>

  <Card title="Persistent Storage" icon="arrow-right" href="/documentation/development/use-persistent-storage">
    How /data works and caching behavior
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/pricing.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pricing

> How billing works for fal Serverless.

When you deploy your own applications on fal Serverless, you are billed for the **total time your runners are alive**, measured per-second by machine type.

## Billing by runner state

Every runner transitions through the states below during its lifecycle. You are billed for the states marked **Yes** at the per-second rate for your machine type.

| State            | Billed | Description                                                            |
| ---------------- | ------ | ---------------------------------------------------------------------- |
| **PENDING**      | No     | Waiting to be scheduled on available hardware                          |
| **DOCKER\_PULL** | No     | Pulling your container image from the registry                         |
| **SETUP**        | Yes    | Running your `setup()` method — loading models, initializing resources |
| **IDLE**         | Yes    | Runner is ready but waiting for requests (includes `keep_alive` time)  |
| **RUNNING**      | Yes    | Actively processing one or more requests                               |
| **DRAINING**     | Yes    | Finishing in-flight requests before shutdown                           |
| **TERMINATING**  | Yes    | Running your `teardown()` method                                       |
| **TERMINATED**   | No     | Runner has stopped and resources are released                          |

5xx errors (HTTP 500+) are also not charged.

See [Runners](/documentation/deployment/runners) for full details on each state and transitions.

## GPU count multiplier

Multi-GPU instances are billed as `gpu_count x duration`. For example, a runner using 2x A100 GPUs for 60 seconds is billed as 120 GPU-seconds.

## Monitoring your usage

<CardGroup cols={2}>
  <Card title="Dashboard Billing" icon="chart-line" href="https://fal.ai/dashboard/billing">
    View your overall spend, invoices, and payment methods.
  </Card>

  <Card title="App Analytics" icon="chart-bar" href="/documentation/serverless/observability/app-analytics">
    See per-app cost breakdown, request counts, and runner utilization.
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/publishing-to-marketplace.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Publishing to the Marketplace

> Make your serverless app available on the fal Marketplace so anyone can call it with their own API key.

Every model on the [fal Marketplace](https://fal.ai/models) is a `fal.App` running on Serverless. You can publish your own app to the marketplace, making it callable by any fal user who authenticates with their own API key and pays for their own usage.

Publishing involves deploying your app in `shared` auth mode, defining billable units so callers are charged correctly, and working with the fal team to get listed. Before publishing, your app should be [deployed](/documentation/deployment/deploy-to-production) and stable, [scaled](/documentation/deployment/scaling-configuration) for your expected traffic, and have [health checks](/documentation/development/add-health-check-endpoint) and [analytics](/documentation/serverless/observability/app-analytics) enabled.

## Set your app to shared mode

Shared mode means callers must authenticate with their own fal API key. Each caller is billed for their own usage — the app owner is not charged for caller compute.

```python theme={null}
class MyModel(fal.App):
    app_auth = "shared"
```

Or via the CLI:

```bash theme={null}
fal deploy my_app.py::MyModel --auth shared
```

<Note>
  Shared mode requires admin enablement on your account. Contact the fal team to get it enabled before deploying with `app_auth = "shared"`.
</Note>

## Define billable units

When your app runs in shared mode, you control how callers are charged by setting the `x-fal-billable-units` response header. This tells the platform how many billing units to charge for each request.

```python theme={null}
response.headers["x-fal-billable-units"] = str(units)
```

The cost per unit is configured separately by the fal team in the billing system — your code only reports **how many units** each request consumed. If you don't set the header, the platform falls back to per-second billing based on the GPU machine type used.

### Common patterns

**Per image (flat rate)**

Charge one unit per generated image, regardless of resolution:

```python theme={null}
response.headers["x-fal-billable-units"] = str(input.num_images)
```

**Per megapixel**

Scale the charge with output resolution. Higher resolutions cost proportionally more:

```python theme={null}
resolution_factor = math.ceil(
    (image_size.width * image_size.height) / (1024 * 1024)
)
response.headers["x-fal-billable-units"] = str(
    resolution_factor * input.num_images
)
```

**Per video second**

Charge based on the duration of generated video:

```python theme={null}
response.headers["x-fal-billable-units"] = str(video_duration_seconds)
```

**Per text chunk**

For text-based models (TTS, LLMs), scale with input length:

```python theme={null}
response.headers["x-fal-billable-units"] = str(max(1, len(prompt) // 1000))
```

**Flat per request**

Charge a fixed amount regardless of input or output:

```python theme={null}
response.headers["x-fal-billable-units"] = "1"
```

## Get listed on the Marketplace

Once your app is deployed in shared mode with billable units configured, contact the fal team to get listed on [fal.ai/models](https://fal.ai/models). The team will configure:

* **Model card** — name, description, category, and example inputs/outputs
* **Pricing** — the cost per billable unit, visible on your model's page and at [fal.ai/pricing](https://fal.ai/pricing)
* **Visibility** — when and how your model appears in the marketplace

After listing, callers see your model's pricing on its page and the `X-Fal-Billable-Units` header in every response, so they can track their usage programmatically.

<CardGroup cols={2}>
  <Card title="Deploy to Production" href="/documentation/deployment/deploy-to-production">
    Deployment strategies and authentication modes.
  </Card>

  <Card title="Model APIs Pricing" href="/documentation/model-apis/pricing">
    How marketplace model pricing works from the caller's perspective.
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/reliability/gpu-health.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# GPU Health

> How fal monitors GPU health, detects failures, and gives you control over runner health through custom health checks.

GPU hardware can degrade or fail during operation. Thermal throttling, memory errors, driver issues, and hardware faults can all cause a runner to produce incorrect results or hang silently. fal monitors GPU health at the platform level and provides tools for you to add application-level health checks that detect problems specific to your workload.

Platform-level monitoring runs continuously across all runners and reacts to hardware problems without any configuration on your part. Application-level [health checks](/documentation/development/add-health-check-endpoint) are optional but recommended for production apps, especially those that hold state or are sensitive to GPU degradation. Together, these ensure that unhealthy runners are replaced before they affect your users.

## Platform GPU Monitoring

fal continuously monitors GPU metrics across all runners, including temperature, clock frequencies, and throttling events. When issues are detected, the operations team is alerted and can cordon the node (preventing new runners from being scheduled), drain existing runners, and perform GPU resets. If the issue persists, the node is escalated for hardware replacement.

This monitoring runs automatically and requires no configuration. You benefit from it regardless of whether you have custom health checks enabled.

## Application Health Checks

Platform monitoring catches hardware-level failures, but it cannot detect application-level problems like a corrupted model state, a leaked GPU memory allocation, or an external dependency that went down. For these, you can define a [health check endpoint](/documentation/development/add-health-check-endpoint) that fal calls periodically to verify your runner is functioning correctly.

```python theme={null}
import fal

class MyApp(fal.App):
    def setup(self):
        self.model = load_model()
        self.db = connect_to_database()

    @fal.endpoint("/health", health_check=fal.HealthCheck(
        failure_threshold=3,
        call_regularly=True,
    ))
    def health(self) -> dict:
        if not self.db.is_alive():
            raise RuntimeError("Database connection lost")
        return {"status": "ok"}
```

When a health check fails for `failure_threshold` consecutive calls (default 3), the runner is terminated and replaced. Health checks run every 15 seconds when `call_regularly=True`.

### Non-Invasive vs Invasive Checks

Health checks with `call_regularly=True` run in parallel with request processing. Keep these lightweight since they share GPU and CPU resources with active requests. Check connection status, memory usage, or simple assertions rather than running inference.

For more thorough checks that need exclusive GPU access (e.g., running a test inference), set `call_regularly=False`. In this mode, the health check only runs when the gateway sends an `x-fal-runner-health-check` header, which happens between requests or after specific error conditions.

```python theme={null}
@fal.endpoint("/health", health_check=fal.HealthCheck(
    call_regularly=False,
    timeout_seconds=10,
))
def health(self) -> dict:
    test_result = self.model.run(self.test_input)
    if not validate(test_result):
        raise RuntimeError("Model producing invalid output")
    return {"status": "ok"}
```

## Handling GPU Errors in Your Code

If your code detects a GPU-level error during request processing (such as an out-of-memory condition or CUDA error), return a [503 status code](/documentation/serverless/reliability/retries#status-code-reference) to signal that the runner should be terminated and replaced. This is the appropriate response when the runner's GPU state is corrupted and it cannot reliably serve further requests.

```python theme={null}
@fal.endpoint("/")
def predict(self, input: dict) -> dict:
    try:
        return self.model.run(input)
    except RuntimeError as e:
        if "out of memory" in str(e).lower() or "CUDA" in str(e):
            from fastapi.responses import JSONResponse
            return JSONResponse(status_code=503, content={"detail": "GPU error"})
        raise
```

For errors where the runner is still functional (e.g., bad input, model inference failure), use [500 instead](/documentation/deployment/readiness-liveness#which-status-code-to-use).

<CardGroup cols={2}>
  <Card title="Health Check Endpoint" icon="heart-pulse" href="/documentation/development/add-health-check-endpoint">
    Full configuration reference for health checks
  </Card>

  <Card title="Status Codes" icon="list-ol" href="/documentation/serverless/reliability/retries#status-code-reference">
    How each HTTP status code affects runners and retries
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/serverless/reliability/retries.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Retries and Error Handling

> How fal retries failed requests, what each status code does to runners, and how to control behavior with response headers.

When a request fails while being processed through the [queue](/documentation/model-apis/inference/queue), fal automatically retries it on a new runner. This covers infrastructure-level failures like runner crashes, network issues, and timeouts. Retries happen transparently, up to 10 attempts, before the request is marked as failed. Direct calls via `run()` and `stream()` (without the queue) are never retried.

The status code your endpoint returns determines whether the runner stays alive, whether the request is retried, and how the platform reacts. Returning the wrong code can kill a healthy runner or prevent a retry that should happen. When a request does fail, the response includes an `error_type` field and `X-Fal-Error-Type` header with a machine-readable category (e.g. `request_timeout`, `runner_disconnected`) that you can use for programmatic retry logic and monitoring. See [Request Error Types](/documentation/model-apis/request-errors) for the full reference.

This page is the complete reference for understanding failures on fal: what triggers retries, what each status code does, how timeouts interact, and how to override default behavior with response headers. For a broader view of how retries fit into the request lifecycle, see [Understanding Requests](/documentation/deployment/requests).

## Status Code Reference

The status code your endpoint returns determines what happens to the [runner](/documentation/deployment/runners) and whether queue-based requests are retried.

| Status Code | Runner Impact              | Retried (queue only) |
| ----------- | -------------------------- | -------------------- |
| **2XX**     | Healthy                    | N/A                  |
| **4XX**     | Healthy                    | No                   |
| **500**     | TCP health check triggered | No                   |
| **502**     | TCP health check triggered | No                   |
| **503**     | Immediately terminated     | Yes                  |
| **504**     | TCP health check triggered | Yes                  |

**2XX and 4XX** -- The runner remains healthy and continues serving requests. 4XX responses are treated as client errors and are never retried.

**500 and 502** -- The platform runs a TCP health check on the runner. If the check passes, the runner stays alive and continues serving requests. If it fails, the runner is terminated and replaced. The request is not automatically retried.

**503** -- The runner is immediately terminated after a single 503 response. Queue-based requests are automatically retried on a new runner (up to 10 times). Use this only when the runner is genuinely broken (e.g., GPU OOM, corrupted state).

**504** -- The platform runs a TCP health check and automatically requeues the request for retry. The runner is not immediately terminated but may be replaced if the health check fails.

<Warning>
  **Never return 503 for normal application errors.** A single 503 immediately kills your runner. Use 500 for application-level errors where the runner is still functional.
</Warning>

### Which Status Code to Use

| Situation                                     | Recommended Code   | Why                                          |
| --------------------------------------------- | ------------------ | -------------------------------------------- |
| Bad user input, validation failure            | **422** or **400** | Client error, runner stays healthy           |
| Model inference failed but runner is fine     | **500**            | Health check runs, runner likely survives    |
| External API or dependency timed out          | **504**            | Request retried, runner not killed           |
| GPU OOM, corrupted model state, runner broken | **503**            | Runner terminated and replaced               |
| Rate limiting the caller                      | **429**            | Client error, runner stays healthy, no retry |

```python theme={null}
import fal
from fastapi.responses import JSONResponse

class MyApp(fal.App):
    @fal.endpoint("/")
    def predict(self, input: dict) -> dict:
        try:
            result = self.model.run(input)
            return result
        except ValueError as e:
            return JSONResponse(
                status_code=422,
                content={"detail": str(e)},
            )
        except RuntimeError as e:
            if "out of memory" in str(e).lower():
                return JSONResponse(
                    status_code=503,
                    content={"detail": "GPU out of memory"},
                )
            return JSONResponse(
                status_code=500,
                content={"detail": "Inference failed"},
            )
```

### Connection Errors and Timeouts

Beyond status codes, two additional scenarios affect runner lifecycle:

| Scenario                            | What happens      | Queue requests        | Direct requests |
| ----------------------------------- | ----------------- | --------------------- | --------------- |
| **App crashes** (connection breaks) | Runner terminated | Retried on new runner | Returns 503     |
| **Request timeout** exceeded        | Runner terminated | Retried on new runner | Returns 504     |

In both cases the runner is shut down because it may be in a faulty state. The platform spins up a replacement.

## When Retries Happen

fal retries queue-based requests under three conditions. Each corresponds to a value you can use in `skip_retry_conditions` to disable it.

| Condition            | Value                | What triggers it                                                                                                                      | Runner impact                                        |
| -------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| **Server error**     | `"server_error"`     | Runner returned HTTP 503, runner disconnected, runner sent an incomplete response, or runner returned HTTP 504                        | 503: runner terminated. 504: health check triggered. |
| **Timeout**          | `"timeout"`          | Request exceeded the app's [request\_timeout](/documentation/deployment/scale-your-application) and the gateway killed the connection | Runner terminated                                    |
| **Connection error** | `"connection_error"` | The HTTP session between the gateway and the runner was unexpectedly closed                                                           | Runner terminated                                    |

Each condition maps to a different failure mode. Server errors indicate the runner is in a bad state. Timeouts indicate the request took too long. Connection errors indicate a network-level failure between the gateway and the runner.

## Controlling Retry Behavior

### App-Level: skip\_retry\_conditions

Configure your app to skip retries for specific conditions. Pass one or more of the condition values from the table above.

```python theme={null}
class MyApp(fal.App):
    skip_retry_conditions = ["timeout"]
```

This is useful when your model has long-running requests that exceed `request_timeout` for legitimate reasons. Without this setting, fal would retry the request on a new runner, which wastes compute and delays the final failure response.

You can combine multiple conditions:

```python theme={null}
class MyApp(fal.App):
    skip_retry_conditions = ["timeout", "server_error"]
```

### Per-Response: X-Fal-Needs-Retry

Override the default retry behavior on a per-response basis by returning the `X-Fal-Needs-Retry` header from your endpoint. This takes precedence over both the status-code-based retry logic and `skip_retry_conditions`.

| Header Value | Behavior                                                              |
| ------------ | --------------------------------------------------------------------- |
| `1`          | Force a retry, even if the status code would not normally trigger one |
| `0`          | Prevent a retry, even if the status code would normally trigger one   |

```python theme={null}
import fal
from fastapi.responses import JSONResponse

class MyApp(fal.App):
    @fal.endpoint("/")
    def run(self, input: Input) -> Output:
        try:
            result = self.model.run(input)
            return result
        except TransientError:
            return JSONResponse(
                status_code=500,
                headers={"X-Fal-Needs-Retry": "1"},
                content={"detail": "Transient error, please retry"},
            )
        except NonRetryableError:
            return JSONResponse(
                status_code=503,
                headers={"X-Fal-Needs-Retry": "0"},
                content={"detail": "Non-retryable error"},
            )
```

### Per-Response: x-fal-stop-runner

Control whether the runner is terminated after a response, independent of the status code. This header is stripped from the response before it reaches the caller.

| Header Value  | Behavior                                                                               |
| ------------- | -------------------------------------------------------------------------------------- |
| `1` / `true`  | Force runner termination (same effect as a 503, but works with any status code)        |
| `0` / `false` | Prevent runner termination (allows returning 503 for retry without killing the runner) |

Use this when you want to decouple retry behavior from runner termination. For example, you might want to trigger a retry (`X-Fal-Needs-Retry: 1`) but keep the runner alive (`x-fal-stop-runner: false`), or terminate a runner (`x-fal-stop-runner: true`) without triggering a retry (`X-Fal-Needs-Retry: 0`).

```python theme={null}
from fastapi.responses import JSONResponse

@fal.endpoint("/")
def predict(self, input: dict) -> dict:
    try:
        return self.model.run(input)
    except CorruptedStateError:
        return JSONResponse(
            status_code=500,
            headers={
                "x-fal-stop-runner": "true",
                "X-Fal-Needs-Retry": "1",
            },
            content={"detail": "Runner state corrupted, retrying on fresh runner"},
        )
```

### Per-Request: Client-Side Control

When calling your app (or any model) from client code, you can control retry behavior per-request using headers.

Pass the `x-fal-no-retry` header to prevent fal from retrying a specific request:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import fal_client

    result = fal_client.subscribe(
        "your-username/your-app-name",
        arguments={"prompt": "a sunset"},
        headers={"x-fal-no-retry": "1"},
    )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { fal } from "@fal-ai/client";

    const result = await fal.subscribe("your-username/your-app-name", {
      input: { prompt: "a sunset" },
      headers: { "x-fal-no-retry": "1" },
    });
    ```
  </Tab>
</Tabs>

For supported models, fal may route failed requests to equivalent fallback endpoints. To disable this per-request, pass `x-app-fal-disable-fallback`:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    result = fal_client.subscribe(
        "your-username/your-app-name",
        arguments={"prompt": "a sunset"},
        headers={"x-app-fal-disable-fallback": "1"},
    )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const result = await fal.subscribe("your-username/your-app-name", {
      input: { prompt: "a sunset" },
      headers: { "x-app-fal-disable-fallback": "1" },
    });
    ```
  </Tab>
</Tabs>

## Timeouts and Retries

fal has four timeout mechanisms, each operating at a different stage of the request lifecycle. They interact with retries differently.

The **app-level `request_timeout`** controls how long a single request can execute on a runner. If your endpoint handler exceeds this limit, the gateway kills the connection, terminates the runner, and retries the request (unless you set `skip_retry_conditions = ["timeout"]`).

```python theme={null}
class MyApp(fal.App):
    request_timeout = 600  # 10 minutes per request
```

The **app-level `startup_timeout`** controls how long a new runner has to complete `setup()` and open its HTTP port. If setup takes longer, the runner is terminated and replaced. This is not a retry condition because the request has not started processing yet. The request stays in the queue and waits for a healthy runner.

```python theme={null}
class MyApp(fal.App):
    startup_timeout = 600  # 10 minutes for setup
```

The **caller-level `start_timeout`** (sent as `X-Fal-Request-Timeout`) is set by the caller and defines an absolute wall-clock deadline for the request. The server checks this deadline before processing begins -- if it has passed, fal returns a 504 with no retry and the runner is not terminated. Once a runner begins processing, the deadline is not enforced and the request runs to completion. However, if processing fails and triggers a retry, all elapsed time (including the failed attempt) counts against the same original deadline.

```python theme={null}
result = fal_client.subscribe(
    "fal-ai/nano-banana-2",
    arguments={"prompt": "a sunset"},
    start_timeout=30,
)
```

The **client-level `client_timeout`** (Python SDK only) is enforced entirely on the client side. The client stops polling and raises an exception locally. The request may still be processing on the server.

```python theme={null}
result = fal_client.subscribe(
    "fal-ai/nano-banana-2",
    arguments={"prompt": "a sunset"},
    client_timeout=60,
)
```

| Timeout                                   | Set by               | When it applies                                            | Retries                      | Runner impact           |
| ----------------------------------------- | -------------------- | ---------------------------------------------------------- | ---------------------------- | ----------------------- |
| `request_timeout`                         | App developer        | During request processing                                  | Yes (condition: `"timeout"`) | Terminated              |
| `startup_timeout`                         | App developer        | During runner startup / `setup()`                          | No (request stays queued)    | Terminated and replaced |
| `start_timeout` / `X-Fal-Request-Timeout` | Caller (server-side) | Entire request lifecycle (enforced before processing only) | Never                        | Not affected            |
| `client_timeout`                          | Caller (client-side) | Total time client waits                                    | N/A (client stops polling)   | Not affected            |

See [Scale Your Application](/documentation/deployment/scale-your-application) for configuring `request_timeout` and `startup_timeout`. The caller-level parameters are documented on the [Async Inference](/documentation/model-apis/inference/queue#submit-parameters) page.

## Request Error Types

When a request fails, the response body includes a `detail` string and an `error_type` field identifying the failure category. The same value is available in the `X-Fal-Error-Type` response header.

```json theme={null}
{
  "detail": "Request timed out",
  "error_type": "request_timeout"
}
```

Use `error_type` to build programmatic retry logic and monitor failure patterns. Runner and timeout errors are typically transient and worth retrying. Client errors (`client_disconnected`, `bad_request`) should not be retried.

| Error Type                   | Description                                                    | Typical Status Code |
| :--------------------------- | :------------------------------------------------------------- | :------------------ |
| `request_timeout`            | The request exceeded the allowed processing time.              | 504                 |
| `startup_timeout`            | The runner did not start within the allowed time.              | 504                 |
| `runner_scheduling_failure`  | No runner could be allocated to handle the request.            | 503                 |
| `runner_connection_timeout`  | The connection to the runner timed out.                        | 503                 |
| `runner_disconnected`        | The runner disconnected unexpectedly during processing.        | 503                 |
| `runner_connection_refused`  | The runner refused the connection.                             | 503                 |
| `runner_connection_error`    | A general connection error occurred with the runner.           | 503                 |
| `runner_incomplete_response` | The runner sent an incomplete response payload.                | 502                 |
| `runner_server_error`        | The runner encountered an internal server error.               | 500                 |
| `client_disconnected`        | The client closed the connection before the response was sent. | 499                 |
| `client_cancelled`           | The request was cancelled by the client.                       | 499                 |
| `bad_request`                | The request was malformed (e.g., invalid timeout header).      | 400                 |
| `internal_error`             | An unexpected internal error occurred.                         | 500                 |

<Note>
  This error format is different from [model validation errors](/documentation/model-apis/errors), which return a `detail` array of typed error objects. Request errors return a flat object with `detail` as a string.
</Note>


# https://fal.ai/docs/documentation/setting-up/accounts-and-identity.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Accounts and Identity

> Set up your fal account, choose between personal and team workspaces, and understand how identity works on the platform.

The first step to using fal is setting up your account. When you sign up, you get a personal account that comes with its own [API keys](/documentation/model-apis/authentication), deployed apps, and billing. If you're working with others, you can create a [team](/documentation/setting-up/teams) so everyone shares a single set of API keys, deployments, and billing instead of managing their own. This is useful whether you are consuming [Model APIs](/documentation/model-apis/overview) together or deploying your own models with [Serverless](/documentation/serverless).

Your identity on fal is separate from the accounts you operate under. You log in as yourself, then choose which account context to work in, whether that's your personal account or a team you belong to. This means one person can switch between multiple accounts without logging out.

## Account Types

| Account type     | What it is                                                                                           |
| ---------------- | ---------------------------------------------------------------------------------------------------- |
| **Personal**     | Created when you sign up. Your individual account.                                                   |
| **Team**         | A shared workspace with its own API keys, apps, and billing. Members are invited and assigned roles. |
| **Organization** | An enterprise parent that manages multiple teams with centralized policies and SSO.                  |

Teams can exist on their own (standalone) or as children of an [organization](/documentation/organizations/index). Standalone teams work well for small groups. Organizations add centralized policies, SSO, and cross-team visibility. Each team maintains its own API keys, secrets, deployed apps, and billing, completely separate from your personal account.

## Sign In

fal supports GitHub OAuth, Google OAuth, and SSO/SAML. If your company has SSO configured, you'll use that automatically. Otherwise, sign in with GitHub or Google. All methods are browser-based and take you straight to the [dashboard](https://fal.ai/dashboard).

<Warning>
  **Each login method creates a separate account.** If you sign in with Google and later sign in with SSO using the same email, you will have two separate personal accounts with separate API keys, credits, and deployed apps. Social logins (Google + GitHub) with the same email are merged into one account, but SSO and social logins are always kept separate. If you have SSO enabled for your organization, use SSO consistently to avoid duplicate accounts.
</Warning>

## Get Your API Key

All requests to fal require authentication. Create an API key in the [dashboard](https://fal.ai/dashboard/keys), then set it as an environment variable:

```bash theme={null}
export FAL_KEY="your-api-key-here"
```

When creating a key, you'll choose a scope:

| Scope     | Use case                                                                                                                                                                                                                           |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **API**   | Calling any model on fal, including [Model APIs](/documentation/model-apis/overview) and your own deployed endpoints.                                                                                                              |
| **ADMIN** | Everything in API, plus CLI operations (`fal deploy`, `fal run`), managing apps, and accessing admin-scoped [Platform APIs](/api-reference/platform-apis/index). Use this for [Serverless](/documentation/serverless) deployments. |

<Warning>
  API keys belong to **accounts**, not people. A team's API key is shared by all team members and accesses that team's resources. When creating a key, make sure the correct account is selected in the top-left corner of the dashboard.
</Warning>

## Switching Between Accounts

All operations, including API calls, deployments, and billing, happen under whichever account is active. You can switch accounts in two ways depending on how you interact with fal.

In the [dashboard](https://fal.ai/dashboard), select the account in the top-left corner. This controls which account's resources you see and which account new API keys are scoped to.

If you're using the fal CLI, you have two options. The recommended approach is [`fal auth login`](/api-reference/cli/auth), which opens a browser-based login flow and lets you select your team account interactively. Alternatively, use [`fal teams set`](/api-reference/cli/teams) to switch the active account for all subsequent commands, or pass `--team` on any command.

```bash theme={null}
# Browser-based login (recommended for SSO users)
fal auth login

# Switch your CLI context to a team
fal teams set my-company

# Or target a team for a single command
fal deploy my_app.py::MyApp --team my-company
```

You can also use [`fal profile`](/api-reference/cli/profile) to manage multiple named profiles, each with its own API key and host. This is useful if you work across multiple accounts or environments and want to switch between them without re-authenticating.

```bash theme={null}
fal profile create staging
fal profile key  # set API key for this profile
fal profile set staging  # switch to this profile
fal profile unset  # go back to default
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Teams" icon="users" href="/documentation/setting-up/teams">
    Create shared workspaces with roles, API keys, and request attribution
  </Card>

  <Card title="Organizations" icon="building" href="/documentation/organizations/index">
    Enterprise policies, SSO, and multi-team management
  </Card>

  <Card title="Data Retention & Storage" icon="clock" href="/documentation/model-apis/media-expiration">
    How generated media is stored and how to control file expiration
  </Card>

  <Card title="Resources" icon="book" href="/documentation/setting-up/resources">
    Client libraries, API references, and community links
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/setting-up/authentication/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Your API Key

> Create an API key to authenticate your requests to fal

Most requests to fal require authentication. You need an API key to call any model on the [Model APIs](/documentation/model-apis/overview), deploy your own with [Serverless](/documentation/serverless), or access any private or shared endpoint. The only exception is endpoints deployed with `app_auth = "public"`, which accept unauthenticated requests.

API keys are tied to accounts, not people. If you are working under a [team](/documentation/setting-up/teams), the key belongs to that team and all members share it. The [fal client libraries](/documentation/model-apis/inference/client-setup) read your key automatically from the `FAL_KEY` environment variable, so once it is set, every SDK call and CLI command authenticates without extra configuration.

## Create Your API Key

<Steps>
  <Step title="Go to the Dashboard">
    Navigate to [fal.ai/dashboard/keys](https://fal.ai/dashboard/keys)
  </Step>

  <Step title="Generate a Key">
    Click **Create Key** and give it a name you'll remember
  </Step>

  <Step title="Copy Your Key">
    Copy the key immediately. You will not be able to see it again
  </Step>
</Steps>

## Set Your API Key

Set your key as an environment variable:

<CodeGroup>
  ```bash macOS/Linux theme={null}
  export FAL_KEY="your-api-key-here"
  ```

  ```bash Windows (PowerShell) theme={null}
  $env:FAL_KEY="your-api-key-here"
  ```

  ```bash .env file theme={null}
  FAL_KEY=your-api-key-here
  ```
</CodeGroup>

Or configure it directly in code:

<CodeGroup>
  ```python Python theme={null}
  import fal_client

  # The client automatically reads FAL_KEY from environment
  # Or you can set it explicitly:
  import os
  os.environ["FAL_KEY"] = "your-api-key-here"
  ```

  ```javascript JavaScript theme={null}
  import { fal } from "@fal-ai/client";

  fal.config({
    credentials: "your-api-key-here",
  });
  ```
</CodeGroup>

<Tip>
  **Best practice**: Use environment variables instead of hardcoding keys in your code. This keeps your keys secure and makes it easy to use different keys for development and production.
</Tip>

## Key Scopes

When creating a key, you'll choose a scope that controls what the key can access:

| Scope     | Use Case                                                                                                                                                                                                                           |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **API**   | Calling any model on fal, including Model APIs and your own deployed endpoints. Also grants access to API-scoped [Platform APIs](/api-reference/platform-apis/index).                                                              |
| **ADMIN** | Everything in API, plus CLI operations (`fal deploy`, `fal run`), managing apps, and accessing admin-scoped [Platform APIs](/api-reference/platform-apis/index). Use this for [Serverless](/documentation/serverless) deployments. |

<Note>
  If you're not sure which to choose, start with **API** scope. You can always create an additional **ADMIN** key later if you need to deploy models.
</Note>

## Test Your Key

Verify your key works by making a simple API call:

```bash theme={null}
curl -X POST "https://fal.run/fal-ai/flux/schnell" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "a cute cat"}'
```

If you see a response with an image URL, your key is working correctly.

## Team Keys

If you're part of a team, make sure to select your team in the top-left corner of the dashboard before creating a key. Keys are scoped to the account (personal or team) that created them.


# https://fal.ai/docs/documentation/setting-up/mcp.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Tools

> Connect AI coding assistants to fal's 1,000+ models via the Model Context Protocol

fal provides an [MCP](https://modelcontextprotocol.io) server that gives any compatible AI assistant direct access to the full fal platform: search models, check schemas, run inference, upload files, and browse documentation — all without leaving your editor. Your assistant becomes an expert in every fal model and can generate working code on the first try.

The server is hosted at `mcp.fal.ai/mcp` and works with any client that supports the [Model Context Protocol](https://modelcontextprotocol.io), including Claude Code, Claude Desktop, Cursor, Windsurf, and more. Every request uses your own [API key](/documentation/setting-up/authentication/index) — nothing is stored on the server.

<video src="https://v3b.fal.media/files/b/0a92d4b8/L7L_neuq7UyBerLwvPJGI_videodonemcpfull.mp4" controls playsinline style={{width: '100%', borderRadius: '8px', margin: '20px 0'}} />

<Note>
  You need a fal API key to use the MCP server. If you don't have one yet, [create one here](https://fal.ai/dashboard/keys).
</Note>

## Setup

<Tabs>
  <Tab title="Claude Code">
    Run this command in your terminal:

    ```bash theme={null}
    claude mcp add --transport http fal-ai \
      https://mcp.fal.ai/mcp \
      --header "Authorization: Bearer YOUR_FAL_KEY"
    ```

    That's it. Claude Code will now have access to all fal tools.

    ![Claude Code MCP setup](https://v3b.fal.media/files/b/0a92d4b8/BBV-rMYye2QM8VRO0AER8_gif02.gif)
  </Tab>

  <Tab title="Claude Desktop">
    <Note>
      Claude Desktop and claude.ai Custom Connectors require OAuth 2.0 authentication, which is not yet supported by the fal MCP server. OAuth support is coming soon. In the meantime, use **Claude Code**, **Cursor**, or **Windsurf** to connect.
    </Note>
  </Tab>

  <Tab title="Cursor">
    <Steps>
      <Step title="Open MCP Settings">
        Use `Cmd+Shift+P` (`Ctrl+Shift+P` on Windows) and search for **"Open MCP settings"**.
      </Step>

      <Step title="Add the fal server">
        Add the following to your `mcp.json` file:

        ```json theme={null}
        {
          "mcpServers": {
            "fal-ai": {
              "url": "https://mcp.fal.ai/mcp",
              "headers": {
                "Authorization": "Bearer YOUR_FAL_KEY"
              }
            }
          }
        }
        ```
      </Step>

      <Step title="Restart Cursor">
        Save the file and restart Cursor to activate the connection.
      </Step>
    </Steps>

    ![Cursor MCP setup](https://v3b.fal.media/files/b/0a92d4b8/cKhQPgvoGw3B3m376BK0o_gif01.gif)
  </Tab>

  <Tab title="Windsurf">
    Open **Settings → MCP** and add a new server:

    ```json theme={null}
    {
      "mcpServers": {
        "fal-ai": {
          "serverUrl": "https://mcp.fal.ai/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_FAL_KEY"
          }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Other MCP Clients">
    The fal MCP server uses the **Streamable HTTP** transport at:

    ```
    https://mcp.fal.ai/mcp
    ```

    Authentication is via the `Authorization` header:

    ```
    Authorization: Bearer YOUR_FAL_KEY
    ```

    Any MCP client that supports Streamable HTTP transport can connect. Refer to your client's documentation for the exact configuration format.
  </Tab>
</Tabs>

***

## Available Tools

The MCP server exposes 9 tools organized in three categories. Your AI assistant picks the right tool automatically based on what you ask.

### Discovery

| Tool                   | What it does                                                          |
| ---------------------- | --------------------------------------------------------------------- |
| **`search_models`**    | Search fal's catalog of 1,000+ models by keyword or category          |
| **`get_model_schema`** | Get the full input/output parameters for any model                    |
| **`get_pricing`**      | Check the cost of running a model before you use it                   |
| **`search_docs`**      | Search the fal documentation for guides, examples, and API references |

### Execution

| Tool             | What it does                                                       |
| ---------------- | ------------------------------------------------------------------ |
| **`run_model`**  | Run any model and wait for the result (images, video, audio, etc.) |
| **`submit_job`** | Submit a long-running job and return immediately with a request ID |
| **`check_job`**  | Check job status, fetch results, or cancel a running job           |

### Utility

| Tool                  | What it does                                                          |
| --------------------- | --------------------------------------------------------------------- |
| **`upload_file`**     | Upload a file (local path or URL) to fal's CDN for use as model input |
| **`recommend_model`** | Describe what you want to build and get model recommendations         |

***

## Examples

Here are concrete examples of what you can ask your AI assistant once the MCP server is connected.

### Generate an image

> "Generate a photorealistic image of a mountain lake at golden hour using fal"

The assistant will:

1. Use `search_models` to find image generation models
2. Use `get_model_schema` to check the parameters for the chosen model
3. Use `run_model` to generate the image
4. Return the image URL

### Generate a video from an image

> "Take this image and turn it into a 5-second cinematic video"

The assistant will:

1. Use `upload_file` to upload your image to fal's CDN
2. Use `recommend_model` to find the best image-to-video model
3. Use `submit_job` (since video generation takes longer)
4. Use `check_job` to poll for the result

### Check pricing before running

> "How much does it cost to generate a video with Kling 3.0?"

The assistant will call `get_pricing` with `fal-ai/kling-video/v3/pro/image-to-video` and return the per-run cost.

### Find the right model

> "What's the best model for removing backgrounds from product photos?"

The assistant will call `recommend_model` with your task description and return a ranked list of models with tips on how to use them.

### Search the docs

> "How do I set up webhooks with fal?"

The assistant will call `search_docs` and return relevant guides and code examples from the fal documentation.

***

## How It Works

The MCP server is a stateless API hosted on Vercel. Each request is fully isolated:

1. Your AI assistant sends a request to `mcp.fal.ai/mcp` with your API key
2. The server calls the [fal Platform API](https://fal.ai/docs) on your behalf
3. Results are returned to your assistant, which formats them for you

Your API key is sent per-request in the `Authorization` header and is never stored. The server has no sessions, no state, and no access to anything beyond what the fal public API provides with your key.

<Tip>
  The MCP server uses the same [Model APIs](/documentation/model-apis/overview) you would call directly with the fal client SDK. Anything you can do with the SDK, your AI assistant can do through MCP.
</Tip>

***

## Tool Reference

### search\_models

Search fal's model catalog by keyword, category, or both.

**Parameters:**

| Parameter  | Type              | Description                                                                                                                               |
| ---------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `query`    | string (optional) | Free-text search, e.g. `"flux"`, `"video generation"`, `"upscale"`                                                                        |
| `category` | string (optional) | Filter by category: `text-to-image`, `image-to-video`, `text-to-video`, `text-to-speech`, `image-to-3d`, `image-editing`, `llm`, and more |
| `limit`    | number (optional) | Max results to return (default 20, max 100)                                                                                               |

**Example response:**

```json theme={null}
{
  "models": [
    {
      "endpoint_id": "fal-ai/flux/dev",
      "name": "FLUX.1 [dev]",
      "category": "text-to-image",
      "description": "State-of-the-art text-to-image model"
    }
  ],
  "total_shown": 1,
  "has_more": true
}
```

***

### get\_model\_schema

Get the full input/output schema for a specific model. Use this before `run_model` to understand what parameters are accepted.

**Parameters:**

| Parameter     | Type   | Description                            |
| ------------- | ------ | -------------------------------------- |
| `endpoint_id` | string | The model ID, e.g. `"fal-ai/flux/dev"` |

***

### run\_model

Run any fal model. Submits to the queue, polls until complete, and returns the result.

**Parameters:**

| Parameter     | Type   | Description                                                              |
| ------------- | ------ | ------------------------------------------------------------------------ |
| `endpoint_id` | string | The model ID, e.g. `"fal-ai/flux/dev"`                                   |
| `input`       | object | Model parameters as JSON. Use `get_model_schema` to see accepted fields. |

**Example:**

```json theme={null}
{
  "endpoint_id": "fal-ai/flux/dev",
  "input": {
    "prompt": "a photorealistic mountain landscape at sunset",
    "image_size": "landscape_16_9"
  }
}
```

<Note>
  For long-running models (video, 3D, training), use `submit_job` + `check_job` instead to avoid timeouts.
</Note>

***

### submit\_job

Submit a job without waiting for the result. Returns immediately with a `request_id` you can use with `check_job`.

**Parameters:**

| Parameter     | Type   | Description              |
| ------------- | ------ | ------------------------ |
| `endpoint_id` | string | The model ID             |
| `input`       | object | Model parameters as JSON |

***

### check\_job

Check the status of a running job, fetch the result, or cancel it.

**Parameters:**

| Parameter     | Type              | Description                                     |
| ------------- | ----------------- | ----------------------------------------------- |
| `endpoint_id` | string            | The model ID                                    |
| `request_id`  | string            | The request ID from `run_model` or `submit_job` |
| `action`      | string (optional) | `"status"` (default), `"result"`, or `"cancel"` |

***

### upload\_file

Upload a file to fal's CDN so it can be used as input to models. Accepts a URL to a remote file.

**Parameters:**

| Parameter   | Type              | Description                    |
| ----------- | ----------------- | ------------------------------ |
| `url`       | string            | URL of a remote file to upload |
| `file_name` | string (optional) | Custom filename for the upload |

Returns a `cdn_url` that you can pass to any model parameter that accepts a URL (e.g. `image_url`, `audio_url`).

***

### get\_pricing

Get the cost of running a model.

**Parameters:**

| Parameter     | Type   | Description                       |
| ------------- | ------ | --------------------------------- |
| `endpoint_id` | string | The model ID to check pricing for |

***

### recommend\_model

Describe what you want to create and get model recommendations ranked by popularity.

**Parameters:**

| Parameter | Type   | Description                                                                                                                             |
| --------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `task`    | string | What you want to do, e.g. `"generate a photorealistic portrait"`, `"create a 10s cinematic video"`, `"remove background from an image"` |

***

### search\_docs

Search the fal documentation for guides, API references, and code examples.

**Parameters:**

| Parameter | Type   | Description                                                                              |
| --------- | ------ | ---------------------------------------------------------------------------------------- |
| `query`   | string | What you're looking for, e.g. `"how to upload a file"`, `"queue API"`, `"LoRA training"` |

***

## FAQ

<Tabs>
  <Tab title="What models can I use?">
    All 1,000+ models in the [fal catalog](https://fal.ai/models) — image generation, video, audio, speech, 3D, LLMs, and more. Use `search_models` or `recommend_model` to find what you need.
  </Tab>

  <Tab title="Is my API key stored?">
    No. The hosted server is fully stateless. Your key is sent per-request in the `Authorization` header and is never stored or logged.
  </Tab>

  <Tab title="Does it cost extra?">
    No. The MCP server is free. You only pay for the fal model runs you trigger, at the same [pricing](https://fal.ai/pricing) as direct API calls.
  </Tab>

  <Tab title="What about rate limits?">
    The MCP server respects the same [concurrency limits](/documentation/model-apis/concurrency-limits) as direct API calls. There are no additional rate limits on the MCP endpoint itself.
  </Tab>
</Tabs>


# https://fal.ai/docs/documentation/setting-up/resources.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Libraries, APIs, and Community

> Client libraries, open-source packages, API references, and community links for building with fal.

This page collects everything you need beyond the core documentation: the open-source libraries you install, the API references you look up, and the community channels where you can get help. Whether you are calling models from Python or JavaScript, deploying your own with the [CLI](/api-reference/cli/index), or integrating fal into a larger system with the [Platform APIs](/api-reference/platform-apis/index), the links below will get you there.

All fal libraries are open source and available on GitHub. The platform itself offers a [model gallery](https://fal.ai/models), a [dashboard](https://fal.ai/dashboard) for managing your account, and a [sandbox](https://fal.ai/sandbox) for comparing models side by side. If you get stuck, the [Discord](https://discord.gg/fal-ai) community and [blog](https://blog.fal.ai) are good places to start.

## Open-Source Packages

| Package                | Install                            | What it does                                                                                                             | Source                                                                                 |
| ---------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| `fal`                  | `pip install fal`                  | Deploy models with the serverless runtime, CLI (`fal deploy`, `fal run`), and toolkit (`Image`, `File`, `download_file`) | [fal-ai/fal](https://github.com/fal-ai/fal) (Apache-2.0)                               |
| `fal-client`           | `pip install fal-client`           | Call models from Python with `subscribe`, `submit`, `upload_file`                                                        | [fal-ai/fal](https://github.com/fal-ai/fal/tree/main/projects/fal_client) (Apache-2.0) |
| `@fal-ai/client`       | `npm install @fal-ai/client`       | Call models from JavaScript with the same API as the Python client, with TypeScript types                                | [fal-ai/fal-js](https://github.com/fal-ai/fal-js) (MIT)                                |
| `@fal-ai/server-proxy` | `npm install @fal-ai/server-proxy` | Server-side proxy for web apps that keeps your API key off the client (Next.js, Express)                                 | [fal-ai/fal-js](https://github.com/fal-ai/fal-js) (MIT)                                |
| `flashpack`            | `pip install flashpack`            | Fast model loading with high-throughput tensor loading for PyTorch (up to 25 Gbps)                                       | [fal-ai/flashpack](https://github.com/fal-ai/flashpack) (MIT)                          |

## Platform

<CardGroup cols={2}>
  <Card title="Model Gallery" icon="cube" href="https://fal.ai/models">
    Browse 1,000+ production-ready AI models ([docs](/documentation/model-apis/overview))
  </Card>

  <Card title="Dashboard" icon="gauge" href="https://fal.ai/dashboard">
    Manage apps, keys, billing, and monitoring ([analytics](/documentation/serverless/observability/app-analytics), [events](/documentation/serverless/observability/app-events), [errors](/documentation/serverless/observability/error-analytics))
  </Card>

  <Card title="Sandbox" icon="flask" href="https://fal.ai/sandbox">
    Compare models side by side in your browser ([docs](/documentation/model-apis/sandbox))
  </Card>

  <Card title="Status Page" icon="signal" href="https://status.fal.ai">
    Real-time platform health and incident history
  </Card>
</CardGroup>

## Documentation

The docs are organized into three main areas depending on how you use fal. Model APIs covers calling existing models, Serverless covers deploying your own, and Compute covers dedicated GPU instances for training or custom workloads.

<CardGroup cols={2}>
  <Card title="Model APIs" icon="cube" href="/documentation/model-apis/overview">
    Call 1,000+ models with simple API calls: inference, streaming, real-time
  </Card>

  <Card title="Serverless" icon="server" href="/documentation/serverless/index">
    Deploy your own models: environment setup, endpoints, scaling, observability
  </Card>

  <Card title="Compute" icon="microchip" href="/documentation/compute/index">
    Dedicated GPU instances with SSH access for training and custom workloads
  </Card>

  <Card title="Examples" icon="code" href="/examples/index">
    Step-by-step tutorials for image, video, and audio generation
  </Card>

  <Card title="Changelog" icon="clock" href="/changelog">
    Platform updates and new features
  </Card>

  <Card title="OpenAPI Spec" icon="file-code" href="/api-reference/platform-apis/openapi-schema">
    Machine-readable API specification for building custom integrations
  </Card>
</CardGroup>

## API References

For programmatic access beyond the client libraries, fal exposes a REST API for managing apps, files, and keys, a full CLI reference, and the Python SDK docs.

<CardGroup cols={3}>
  <Card title="Platform APIs" icon="rectangle-terminal" href="/api-reference/platform-apis/index">
    REST API for managing apps, files, metrics, and keys
  </Card>

  <Card title="CLI Reference" icon="terminal" href="/api-reference/cli/index">
    Full command reference for the fal CLI
  </Card>

  <Card title="Python SDK" icon="python" href="/api-reference/python-sdk/index">
    Python SDK API reference
  </Card>
</CardGroup>

## Client Libraries

fal has official client libraries for Python and JavaScript, plus community-maintained clients for Swift, Kotlin, and Dart. Each library handles authentication, request queuing, and file uploads so you can focus on your application.

<CardGroup cols={3}>
  <Card title="Python" icon="python" href="/api-reference/client-libraries/python/index">
    pip install fal-client
  </Card>

  <Card title="JavaScript" icon="js" href="/api-reference/client-libraries/javascript/index">
    npm install @fal-ai/client
  </Card>

  <Card title="Swift" icon="swift" href="/api-reference/client-libraries/swift/index">
    iOS client
  </Card>

  <Card title="Kotlin" icon="code" href="/api-reference/client-libraries/kotlin/index">
    Android / JVM client
  </Card>

  <Card title="Dart" icon="code" href="/api-reference/client-libraries/dart/index">
    Flutter client
  </Card>
</CardGroup>

## Community and Support

The fal community is active on Discord, where you can ask questions, share projects, and get help from the team and other developers. The blog covers product updates and engineering deep dives.

<CardGroup cols={3}>
  <Card title="Discord" icon="discord" href="https://discord.gg/fal-ai">
    Join the community, ask questions, share what you're building
  </Card>

  <Card title="Blog" icon="newspaper" href="https://blog.fal.ai">
    Product updates, tutorials, and engineering deep dives
  </Card>

  <Card title="Contact Sales" icon="building" href="https://fal.ai/enterprise#contact-sales">
    Enterprise plans, dedicated support, and custom solutions
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/setting-up/teams.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Teams

> Create shared workspaces with their own API keys, deployments, and billing. Manage members, roles, and understand how request attribution works.

Teams let multiple people share a single set of API keys, deployed apps, and billing on fal. Instead of each person managing their own [personal account](/documentation/setting-up/accounts-and-identity), a team acts as a shared workspace where everyone operates under the same identity. This is useful whether you are calling [Model APIs](/documentation/model-apis/overview) together or deploying your own models with [Serverless](/documentation/serverless).

Teams can exist on their own (standalone) or as children of an [organization](/documentation/organizations/index). Standalone teams work well for small groups. Organizations add centralized policies, SSO, and cross-team visibility. Each team maintains its own API keys, secrets, deployed apps, and billing, completely separate from any member's personal account. For switching between your personal account and a team, see [Switching Between Accounts](/documentation/setting-up/accounts-and-identity#switching-between-accounts).

## Creating a Team

<Steps>
  <Step title="Open the team menu">
    Click your account name in the top-left of the [Dashboard](https://fal.ai/dashboard) and select **Create Team**.
  </Step>

  <Step title="Name your team">
    Enter a team name. This will be visible to all members.
  </Step>

  <Step title="Start using it">
    You'll be switched to the new team automatically. Create API keys and invite members from here.
  </Step>
</Steps>

## Inviting Members

<Steps>
  <Step title="Go to Members">
    Navigate to [**Dashboard > Members**](https://fal.ai/dashboard/members)
  </Step>

  <Step title="Click Invite">
    Enter the member's email address and select their role.
  </Step>

  <Step title="They accept">
    The invited user receives an email with a link to join your team.
  </Step>
</Steps>

For larger teams, use the bulk invite feature at [**Dashboard > Members > Bulk**](https://fal.ai/dashboard/members/bulk). Upload a CSV with columns:

```
email,role
alice@company.com,admin
bob@company.com,developer
carol@company.com,billing
```

Up to 50 invites can be sent per batch.

## Roles

Each team member is assigned one of three roles that control what they can do in the dashboard. Roles govern dashboard and management access. All team members, regardless of role, can use the team's API keys to call models, deploy apps, and run workloads.

| Role          | What they can do                                                                                                                                |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **Admin**     | Full team management: create and delete API keys, view billing and invoices, invite members, and change roles.                                  |
| **Developer** | Standard access to team resources. Cannot manage API keys, billing, members, or roles.                                                          |
| **Billing**   | View and manage billing: invoices, payment methods, credit purchases, and usage. Can also view API keys. Cannot invite members or change roles. |

<Tip>
  Start with **Admin** for team leads who need to manage keys and members. Use **Developer** for engineers who only need to deploy and monitor apps. Use **Billing** for finance team members who need usage and invoice access.
</Tip>

## API Keys and Request Attribution

Roles and key scopes are independent concepts. Roles control what a person can do in the dashboard (manage keys, billing, members). Key scopes control what the key itself can do programmatically (call models, deploy apps). A Developer-role member cannot create keys in the dashboard, but they can use the team's ADMIN-scoped key to run `fal deploy`.

API keys are scoped to the team, not to individual members. Any team member can use a team API key, but only Admins can create or delete them. When creating a key, make sure you have the correct team selected in the top-left of the dashboard. See [Get Your API Key](/documentation/setting-up/accounts-and-identity#get-your-api-key) for the available scopes.

How you authenticate affects how requests are attributed and what you see in the dashboard. When you use `fal auth login` and select a team, each request carries your individual identity within the team. This means the dashboard shows which team member made each request. When you use a team API key directly, requests are attributed to the team as a whole rather than to a specific member. Both methods access the same team resources and billing, but login-based authentication provides better per-user visibility in the dashboard and request history.

The fal client SDKs (`fal_client` in Python, `@fal-ai/client` in JavaScript) support both methods automatically. The SDK checks for credentials in this order:

1. `FAL_KEY` environment variable (sends `Authorization: Key ...`)
2. Tokens saved by `fal auth login` (sends `Authorization: Bearer ...`)

Login tokens are stored on disk at `~/.fal/auth0_token`, so they persist across terminal sessions and reboots. You run `fal auth login` once, and any Python script on the same machine picks up the credentials automatically, even from a completely different process or terminal. This works the same way as `gcloud auth login` or `aws sso login`.

```bash theme={null}
# Run once from any terminal -- persists to disk
fal auth login
fal teams set my-team
```

```python theme={null}
# Any Python script, any terminal session, any process
# Automatically uses your login-based identity (no FAL_KEY needed)
import fal_client

result = fal_client.subscribe("fal-ai/flux/schnell", arguments={
    "prompt": "a sunset"
})
```

If `FAL_KEY` is set, it takes priority over login tokens. To force login-based auth even when `FAL_KEY` is present, set `FAL_FORCE_AUTH_BY_USER=1`.

For production apps and CI pipelines, API keys are recommended because they don't expire and don't require interactive login. For development, testing, and any workflow where per-user attribution matters, `fal auth login` is preferred.

## Managing Your Team

Team management happens on the [Members page](https://fal.ai/dashboard/members) and is restricted to Admins. From there you can change a member's role using the dropdown next to their name, remove members to revoke their access, or cancel pending invites that haven't been accepted yet. If a team is no longer needed, Admins can archive it permanently from the same page.

## Next Steps

<CardGroup cols={2}>
  <Card title="Organizations" icon="building" href="/documentation/organizations/index">
    Enterprise policies, SSO, and multi-team management
  </Card>

  <Card title="Access Controls" icon="shield" href="/documentation/organizations/access-controls">
    Control which models your teams can access
  </Card>
</CardGroup>


# https://fal.ai/docs/documentation/why-fal.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Why fal?

> Industry-leading inference speed for generative AI, trusted by top AI applications

## Model APIs

**Unified API, 1,000+ models.** One API to access every model on fal. Switch between FLUX, Nano Banana 2, Kling 3.0, Sora 2, Whisper, and more with a single parameter change. No need to integrate separate providers or manage different SDKs. fal moves fast on new model launches too, with day-0 availability the moment a model drops, so you're never waiting to integrate the latest generation.

```python theme={null}
import fal_client

# Switch models by changing one string
result = fal_client.subscribe("fal-ai/flux/schnell", arguments={"prompt": "a sunset over mountains"})
result = fal_client.subscribe("fal-ai/nano-banana-2", arguments={"prompt": "a sunset over mountains"})
```

**Fastest inference for generative media.** Speed is where fal started and where it continues to invest the most. Proprietary optimizations, including custom CUDA kernels, optimized attention layers, and inference engine tuning, consistently deliver the fastest inference for diffusion and generative media workloads. Reliability matches the speed: 99.99% historical uptime, fault tolerance, and intelligent request queuing are built in.

**Test and compare before you commit.** [Sandbox](https://fal.ai/sandbox) lets you run the same prompt across multiple models side by side, estimate costs before running, and share results with your team. Instead of guessing which model fits your use case, you can see the differences visually and make model selection concrete.

***

## Serverless

**Deploy your own models on battle-tested infrastructure.** Every endpoint on the [fal Marketplace](https://fal.ai/models) runs on [fal Serverless](/documentation/serverless), the same infrastructure you deploy your own models on. fal has been running this system for over 3 years, serving tens of millions of requests daily. If fal Serverless breaks, fal's own products break. That alignment means the engine your code runs on is constantly being optimized.

**Scale automatically, or reserve capacity.** fal scales from zero to thousands of GPUs across H100s, H200s, A100s, and more. For teams that need guaranteed capacity, fal also offers reserved GPU allocations.

**Dedicated engineering support.** Every customer gets a dedicated Slack channel with engineers across timezones. For enterprise contracts, fal's ML specialists work directly with your team, optimizing your code, tuning cold starts, and iterating from development through production. Migration is straightforward too: bring your existing [container images](/documentation/development/use-custom-container-image), use the [quickstart](/documentation/development/getting-started/quick-start) to deploy in minutes, or connect to the [MCP](/documentation/serverless/mcp) and migrate in one shot.

***

<CardGroup cols={2}>
  <Card title="Model APIs" icon="cube" href="/documentation/model-apis/overview">
    Start calling 1,000+ models with a single API
  </Card>

  <Card title="Serverless" icon="rocket" href="/documentation/serverless">
    Deploy your own models on fal's infrastructure
  </Card>
</CardGroup>


# https://fal.ai/docs/examples/audio-speech/convert-speech-to-text.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Convert Speech to Text Tutorial

## How to Convert Speeches using the fal API

To convert speeches to text using the fal API, you need to send a request to the appropriate endpoint with the desired input parameters. The API uses pre-trained models to convert speeches to text based on the provided audio file. This allows you to convert speeches to text by simply providing the audio file.

Here is an example of how to convert speeches to text using the fal API:

```js theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/whisper", {
  input: {
    audio_url: "https://storage.googleapis.com/falserverless/model_tests/whisper/dinner_conversation.mp3"
  },
});
```

## How to select the model to use

fal offers a variety of speech-to-text models. You can select the model that best fits your needs based on the quality and accuracy of the speech-to-text conversion. Here are some of the available models:

* [fal-ai/whisper](https://fal.ai/models/fal-ai/whisper): Whisper is a model for speech transcription and translation.
* [fal-ai/wizper](https://fal.ai/models/fal-ai/wizper): Wizper is Whisper v3 Large — but optimized by our inference wizards. Same WER, double the performance!

To select a model, simply specify the model ID in the subscribe method as shown in the example above. You can find more models and their descriptions in the [Text to Image Models](https://fal.ai/models?categories=text-to-image) page.


# https://fal.ai/docs/examples/audio-speech/deploy-text-to-music-model.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a Text-to-Music Model

> This example demonstrates how to build a sophisticated text-to-music generation service using DiffRhythm, showcasing advanced fal features including custom Docker images, repository cloning, file downloading, and complex audio processing workflows.

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/blob/main/fal_demos/audio/diffrhythm.py).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate (if not already done):

```bash theme={null}
fal auth login
```

3. Copy the code below into `diffrhythm.py`

<CodeGroup>
  ```python diffrhythm.py wrap theme={null}
  import math
  import os
  import tempfile
  from typing import Literal

  import fal
  from fal.exceptions import FieldException
  from fal.toolkit import File, clone_repository, download_file
  from fastapi import Response
  from pydantic import BaseModel, Field


  class TextToMusicInput(BaseModel):
      lyrics: str = Field(
          title="Lyrics",
          description="The prompt to generate the song from. Must have two sections. Sections start with either [chorus] or a [verse].",
          examples=[
              """[00:10.00]Moonlight spills through broken blinds
  [00:13.20]Your shadow dances on the dashboard shrine
  [00:16.85]Neon ghosts in gasoline rain
  [00:20.40]I hear your laughter down the midnight train
  [00:24.15]Static whispers through frayed wires
  [00:27.65]Guitar strings hum our cathedral choirs
  [00:31.30]Flicker screens show reruns of June
  [00:34.90]I'm drowning in this mercury lagoon
  [00:38.55]Electric veins pulse through concrete skies
  [00:42.10]Your name echoes in the hollow where my heartbeat lies
  [00:45.75]We're satellites trapped in parallel light
  [00:49.25]Burning through the atmosphere of endless night
  [01:00.00]Dusty vinyl spins reverse
  [01:03.45]Our polaroid timeline bleeds through the verse
  [01:07.10]Telescope aimed at dead stars
  [01:10.65]Still tracing constellations through prison bars
  [01:14.30]Electric veins pulse through concrete skies
  [01:17.85]Your name echoes in the hollow where my heartbeat lies
  [01:21.50]We're satellites trapped in parallel light
  [01:25.05]Burning through the atmosphere of endless night
  [02:10.00]Clockwork gears grind moonbeams to rust
  [02:13.50]Our fingerprint smudged by interstellar dust
  [02:17.15]Velvet thunder rolls through my veins
  [02:20.70]Chasing phantom trains through solar plane
  [02:24.35]Electric veins pulse through concrete skies
  [02:27.90]Your name echoes in the hollow where my heartbeat lies
  """,
          ],
          ui={
              "field": "textarea", # Set the input field to textarea for better user experience
          },
      )
      reference_audio_url: str = Field(
          title="Reference Audio URL",
          description="The URL of the reference audio to use for the music generation.",
          default=None,
          examples=[
              "https://storage.googleapis.com/falserverless/model_tests/diffrythm/rock_en.wav",
          ],
          ui={"important": True}, # Mark as important to not list it in the advanced options section
      )
      style_prompt: str = Field(
          title="Style Prompt",
          description="The style prompt to use for the music generation.",
          default=None,
          examples=[
              "pop",
          ],
      )
      music_duration: Literal["95s", "285s"] = Field(
          title="Music Duration",
          description="The duration of the music to generate.",
          default="95s",
      )
      cfg_strength: float = Field(
          title="CFG Strength",
          description="The CFG strength to use for the music generation.",
          default=4.0,
          le=10.0,
          ge=1.0,
      )
      scheduler: Literal["euler", "midpoint", "rk4", "implicit_adams"] = Field(
          title="Scheduler",
          description="The scheduler to use for the music generation.",
          default="euler",
      )
      num_inference_steps: int = Field(
          title="Number of Inference Steps",
          description="The number of inference steps to use for the music generation.",
          le=100,
          ge=10,
          default=32,
      )
      max_frames: int = Field(
          title="Max Frames",
          description="The maximum number of frames to use for the music generation.",
          default=2048,
          le=8192,
          ge=100,
      )


  class Output(BaseModel):
      audio: File = Field(
          description="Generated music file.",
          examples=[
              File(
                  **{
                      "url": "https://v3.fal.media/files/elephant/VV4wtKXBpZL1bNv6en36t_output.wav",
                      "content_type": "application/octet-stream",
                      "file_name": "output.wav",
                      "file_size": 33554520,
                  }
              ),
          ],
      )


  def extract_segments(text):
      result = []
      pos = 0
      while pos < len(text):
          # Find the opening '['
          start = text.find("[", pos)
          if start == -1:
              break

          # Find the closing ']'
          end = text.find("]", start)
          if end == -1:
              break

          # Extract the key inside the brackets
          key = text[start + 1 : end]

          # Find the next '[' or end of the text
          next_start = text.find("[", end)
          if next_start == -1:
              next_start = len(text)

          # Extract the content associated with the key
          content = text[end + 1 : next_start].rstrip()
          result.append((key, content))

          # Update the position
          pos = next_start

      return result

  # Custom Docker Image to install apt packages like espeak-ng
  DOCKER_STRING = """
  FROM pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel

  # Install system dependencies
  RUN apt-get update && \
      apt-get install -y git espeak-ng ffmpeg curl && \
      rm -rf /var/lib/apt/lists/*

  # Install Python dependencies
  RUN pip install accelerate==1.4.0 \
      inflect==7.5.0 \
      torchdiffeq==0.2.5 \
      torchaudio==2.6.0 \
      x-transformers==2.1.2 \
      transformers==4.49.0 \
      numba==0.61.0 \
      llvmlite==0.44.0 \
      librosa==0.10.2.post1 \
      pyarrow==19.0.1 \
      pandas==2.2.3 \
      pylance==0.23.2 \
      ema-pytorch==0.7.7 \
      prefigure==0.0.10 \
      bitsandbytes==0.45.3 \
      muq==0.1.0 \
      mutagen==1.47.0 \
      pyopenjtalk==0.4.1 \
      pykakasi==2.3.0 \
      jieba==0.42.1 \
      cn2an==0.5.23 \
      pypinyin==0.53.0 \
      onnxruntime==1.20.1 \
      Unidecode==1.3.8 \
      phonemizer==3.3.0 \
      liger_kernel==0.5.4 \
      openai==1.65.2 \
      pydantic==2.10.6 \
      einops==0.8.1 \
      lazy_loader==0.4 \
      scipy==1.15.2 \
      ftfy==6.3.1 \
      torchdiffeq==0.2.5 \
      ffmpeg-python \
      LangSegment==0.2.0 \
      hydra-core==1.3.2

  """


  class DiffRhythm(fal.App):
      keep_alive = 600
      min_concurrency = 1
      max_concurrency = 2
      app_name = "diffrhythm"
      image = fal.ContainerImage.from_dockerfile_str(DOCKER_STRING)  # Use the custom Docker image
      machine_type = "GPU-H100"

      def setup(self):
          import numpy as np
          import torch

          # Clone the DiffRhythm repository
          repo_path = clone_repository(
              "https://huggingface.co/spaces/ASLP-lab/DiffRhythm",
              commit_hash="f0f1b621ff31d0da9539c0495e034051af9c4179",
              include_to_path=True,
              target_dir="/app",
              repo_name="diffrythm",
          )
          os.chdir(repo_path)

          # Download the negative prompt file with download_fike utility
          download_file(
              "https://huggingface.co/spaces/ASLP-lab/DiffRhythm/resolve/main/src/negative_prompt.npy",
              target_dir=f"{repo_path}/src",
          )

          download_file(
              "https://huggingface.co/spaces/ASLP-lab/DiffRhythm/resolve/main/diffrhythm/g2p/sources/g2p_chinese_model/poly_bert_model.onnx",
              target_dir=f"{repo_path}/diffrhythm/g2p/sources/g2p_chinese_model",
          )
          
          # Download eval model files required by prepare_model
          download_file(
              "https://huggingface.co/spaces/ASLP-lab/DiffRhythm/resolve/main/pretrained/eval.yaml",
              target_dir=f"{repo_path}/pretrained",
          )
          download_file(
              "https://huggingface.co/spaces/ASLP-lab/DiffRhythm/resolve/main/pretrained/eval.safetensors",
              target_dir=f"{repo_path}/pretrained",
          )
          
          from diffrhythm.infer.infer_utils import prepare_model

          device = "cuda"
          # Load model with max_frames=6144 (supports both 95s and 285s durations)
          self.cfm, self.tokenizer, self.muq, self.vae, self.eval_model, self.eval_muq = prepare_model(
              max_frames=6144, device=device
          )
          # Compile the model for better performance
          self.cfm = torch.compile(self.cfm)
          self.warmup()

      def warmup(self):
          self._generate(
              TextToMusicInput(
                  lyrics="""[00:10.00]Moonlight spills through broken blinds
  [00:13.20]Your shadow dances on the dashboard shrine
  [00:16.85]Neon ghosts in gasoline rain
  [00:20.40]I hear your laughter down the midnight train
  [00:24.15]Static whispers through frayed wires
  [00:27.65]Guitar strings hum our cathedral choirs
  """,
                  reference_audio_url="https://storage.googleapis.com/falserverless/model_tests/diffrythm/rock_en.wav",
                  num_inference_steps=32,
              ),
              Response(),
          )

      def _generate(
          self,
          input: TextToMusicInput,
          response: Response,
      ) -> Output:
          if not input.style_prompt and not input.reference_audio_url:
              raise FieldException(
                  "style_prompt",
                  "Either style prompt or reference audio URL must be provided.",
              )
          import torch
          import torchaudio
          from diffrhythm.infer.infer import inference
          from diffrhythm.infer.infer_utils import (
              get_audio_style_prompt,
              get_lrc_token,
              get_reference_latent,
              get_text_style_prompt,
          )

          # Create a temporary directory to save the intermediates along with the output file
          with tempfile.TemporaryDirectory() as output_dir:
              output_path = os.path.join(output_dir, "output.wav")

              # Set max_frames based on duration (model supports both)
              if input.music_duration == "95s":
                  max_frames = 2048
              else:
                  max_frames = 6144
              cfm_model = self.cfm

              sway_sampling_coef = -1 if input.num_inference_steps < 32 else None
              max_secs = 95 if input.music_duration == "95s" else 285
              try:
                  lrc_prompt, start_time, end_frame, song_duration = get_lrc_token(
                      max_frames, input.lyrics, self.tokenizer, max_secs, "cuda"
                  )
              except Exception as e:
                  print("Error in lrc prompt", e)
                  if "Unknown language" in str(e):
                      raise FieldException("lyrics", "Unsupported language in lyrics.")

              vocal_flag = False
              ref_audio_path = None
              if input.reference_audio_url:
                  try:
                      ref_audio_path = download_file(
                          input.reference_audio_url, target_dir=output_dir
                      )
                      style_prompt, vocal_flag = get_audio_style_prompt(
                          self.muq, ref_audio_path
                      )
                  except Exception as e:
                      raise FieldException(
                          "reference_audio_url",
                          "The reference audio could not be processed.",
                      )
              else:
                  try:
                      style_prompt = get_text_style_prompt(self.muq, input.style_prompt)
                  except Exception as e:
                      raise FieldException(
                          "style_prompt", "The style prompt could not be processed."
                      )
              
              # Import and call get_negative_style_prompt
              from diffrhythm.infer.infer_utils import get_negative_style_prompt
              negative_style_prompt = get_negative_style_prompt("cuda")

              latent_prompt, pred_frames = get_reference_latent(
                  "cuda", max_frames, edit=False, pred_segments=None, ref_song=ref_audio_path, vae_model=self.vae
              )
              batch_infer_num = 3  # Number of songs to generate for selection
              # inference returns (sample_rate, audio_array) when file_type='wav'
              sample_rate, generated_song = inference(
                  cfm_model=cfm_model,
                  vae_model=self.vae,
                  eval_model=self.eval_model,
                  eval_muq=self.eval_muq,
                  cond=latent_prompt,
                  text=lrc_prompt,
                  duration=end_frame,
                  style_prompt=style_prompt,
                  negative_style_prompt=negative_style_prompt,
                  steps=input.num_inference_steps,
                  cfg_strength=input.cfg_strength,
                  sway_sampling_coef=sway_sampling_coef,
                  start_time=start_time,
                  file_type="wav",
                  vocal_flag=vocal_flag,
                  odeint_method=input.scheduler,
                  pred_frames=pred_frames,
                  batch_infer_num=batch_infer_num,
                  song_duration=song_duration,
              )
              # generated_song is numpy array with shape [num_samples, num_channels]
              # torchaudio.save expects [num_channels, num_samples], so we transpose
              audio_tensor = torch.from_numpy(generated_song).T
              torchaudio.save(
                  output_path,
                  audio_tensor,
                  sample_rate=sample_rate,
              )
              response.headers["x-fal-billable-units"] = str(
                  max(math.ceil(generated_song.shape[0] // 441000), 1)
              )
              return Output(audio=File.from_path(output_path))

      @fal.endpoint("/")
      def generate(
          self,
          input: TextToMusicInput,
          response: Response,
      ) -> Output:
          return self._generate(input, response)
  ```

  ```toml pyproject.toml wrap theme={null}
  [project]
  name = "diffrhythm-demo"
  version = "0.1.0"
  description = "DiffRhythm text-to-music generation demo"
  requires-python = ">=3.11"
  dependencies = [
      "pydantic>=2.0",
      "fal @ git+https://github.com/fal-ai/fal.git#subdirectory=projects/fal"
  ]

  [tool.fal.apps]
  diffrhythm = { auth = "shared", ref = "diffrhythm.py::DiffRhythm", no_scale=true }
  ```
</CodeGroup>

4. Run the app:

```bash theme={null}
fal run diffrhythm.py
```

<Info>
  **Or clone this repository**:

  ```bash theme={null}
  git clone https://github.com/fal-ai-community/fal-demos.git
  cd fal-demos
  pip install -e .
  # Use the app name (defined in pyproject.toml)
  fal run diffrhythm
  # Or use the full file path:
  # fal run fal_demos/audio/diffrhythm.py::DiffRhythm
  ```
</Info>

<Tip>
  **Before you run**, make sure you have:

  * Authenticated with fal: `fal auth login`
  * Activated your virtual environment (recommended): `python -m venv venv && source venv/bin/activate` (macOS/Linux) or `venv\Scripts\activate` (Windows)
</Tip>

## Key Features

* **Custom Docker Images**: Build containers with system dependencies
* **Repository Cloning**: Clone and integrate external repositories
* **File Management**: Download models and handle temporary files
* **Audio Processing**: Generate music from lyrics and style prompts
* **Complex Validation**: Advanced input validation with custom error handling
* **Warmup Procedures**: Optimize model loading for better performance
* **Billing Integration**: Usage-based pricing tied to audio duration

## When to Use Custom Docker Images

Custom Docker images are essential when you need:

* System-level dependencies (apt packages, libraries)
* Complex installation procedures
* External tools or binaries
* Custom build processes

## Project Setup

```python theme={null}
import math
import os
import tempfile
from typing import Literal

import fal
from fal.exceptions import FieldException
from fal.toolkit import File, clone_repository, download_file
from fastapi import Response
from pydantic import BaseModel, Field
```

## Input Model with Advanced Validation

Define comprehensive input schemas with custom UI elements:

```python theme={null}
class TextToMusicInput(BaseModel):
    lyrics: str = Field(
        title="Lyrics",
        description="The prompt to generate the song from. Must have two sections. Sections start with either [chorus] or a [verse].",
        examples=[
            """[00:10.00]Moonlight spills through broken blinds
[00:13.20]Your shadow dances on the dashboard shrine
[00:16.85]Neon ghosts in gasoline rain
[00:20.40]I hear your laughter down the midnight train
[00:24.15]Static whispers through frayed wires
[00:27.65]Guitar strings hum our cathedral choirs
[00:31.30]Flicker screens show reruns of June
[00:34.90]I'm drowning in this mercury lagoon
[00:38.55]Electric veins pulse through concrete skies
[00:42.10]Your name echoes in the hollow where my heartbeat lies
[00:45.75]We're satellites trapped in parallel light
[00:49.25]Burning through the atmosphere of endless night""",
        ],
        ui={
            "field": "textarea",  # Custom UI field type
        },
    )
    reference_audio_url: str = Field(
        title="Reference Audio URL",
        description="The URL of the reference audio to use for the music generation.",
        default=None,
        examples=[
            "https://storage.googleapis.com/falserverless/model_tests/diffrythm/rock_en.wav",
        ],
        ui={"important": True},  # Mark as important in UI
    )
    style_prompt: str = Field(
        title="Style Prompt",
        description="The style prompt to use for the music generation.",
        default=None,
        examples=["pop"],
    )
    music_duration: Literal["95s", "285s"] = Field(
        title="Music Duration",
        description="The duration of the music to generate.",
        default="95s",
    )
    cfg_strength: float = Field(
        title="CFG Strength",
        description="The CFG strength to use for the music generation.",
        default=4.0,
        le=10.0,
        ge=1.0,
    )
    scheduler: Literal["euler", "midpoint", "rk4", "implicit_adams"] = Field(
        title="Scheduler",
        description="The scheduler to use for the music generation.",
        default="euler",
    )
    num_inference_steps: int = Field(
        title="Number of Inference Steps",
        description="The number of inference steps to use for the music generation.",
        le=100,
        ge=10,
        default=32,
    )
    max_frames: int = Field(
        title="Max Frames",
        description="The maximum number of frames to use for the music generation.",
        default=2048,
        le=8192,
        ge=100,
    )
```

## Output Model for Audio Files

```python theme={null}
class Output(BaseModel):
    audio: File = Field(
        description="Generated music file.",
        examples=[
            File(
                url="https://v3.fal.media/files/elephant/VV4wtKXBpZL1bNv6en36t_output.wav",
                content_type="application/octet-stream",
                file_name="output.wav",
                file_size=33554520,
            ),
        ],
    )
```

## Custom Docker Image Configuration

Create a Dockerfile string with all necessary dependencies:

```python theme={null}
DOCKER_STRING = """
FROM pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel

# Install system dependencies
RUN apt-get update && \
    apt-get install -y git espeak-ng ffmpeg && \
    rm -rf /var/lib/apt/lists/*

# Install Python dependencies
RUN pip install accelerate==1.4.0 \
    inflect==7.5.0 \
    torchdiffeq==0.2.5 \
    torchaudio==2.6.0 \
    x-transformers==2.1.2 \
    transformers==4.49.0 \
    numba==0.61.0 \
    llvmlite==0.44.0 \
    librosa==0.10.2.post1 \
    pyarrow==19.0.1 \
    pandas==2.2.3 \
    pylance==0.23.2 \
    ema-pytorch==0.7.7 \
    prefigure==0.0.10 \
    bitsandbytes==0.45.3 \
    muq==0.1.0 \
    mutagen==1.47.0 \
    pyopenjtalk==0.4.1 \
    pykakasi==2.3.0 \
    jieba==0.42.1 \
    cn2an==0.5.23 \
    pypinyin==0.53.0 \
    onnxruntime==1.20.1 \
    Unidecode==1.3.8 \
    phonemizer==3.3.0 \
    LangSegment==0.2.0 \
    liger_kernel==0.5.4 \
    openai==1.65.2 \
    pydantic==2.10.6 \
    einops==0.8.1 \
    lazy_loader==0.4 \
    scipy==1.15.2 \
    ftfy==6.3.1 \
    torchdiffeq==0.2.5 \
    ffmpeg-python
"""
```

## Application Configuration with Container Image

```python theme={null}
class DiffRhythm(fal.App):
    image = fal.ContainerImage.from_dockerfile_str(DOCKER_STRING)  # Custom image
    keep_alive = 60
    min_concurrency = 1
    max_concurrency = 2
    app_name = "diffrhythm"
    machine_type = "GPU-H100"
```

## Model Setup with Repository Cloning

The setup method handles complex initialization including repository cloning:

```python theme={null}
def setup(self):
    import numpy as np
    import torch

    # Clone the DiffRhythm repository
    repo_path = clone_repository(
        "https://huggingface.co/spaces/ASLP-lab/DiffRhythm",
        commit_hash="0d355fb2211e3f4f04112d8ed30cc9211a79c974",
        include_to_path=True,
        target_dir="/app",
        repo_name="diffrythm",
    )
    os.chdir(repo_path)

    # Download required model files
    download_file(
        "https://huggingface.co/spaces/ASLP-lab/DiffRhythm/resolve/main/src/negative_prompt.npy",
        target_dir=f"{repo_path}/src",
    )
    self.negative_style_prompt = (
        torch.from_numpy(np.load("./src/negative_prompt.npy")).to("cuda").half()
    )

    download_file(
        "https://huggingface.co/spaces/ASLP-lab/DiffRhythm/resolve/main/diffrhythm/g2p/sources/g2p_chinese_model/poly_bert_model.onnx",
        target_dir=f"{repo_path}/diffrhythm/g2p/sources/g2p_chinese_model",
    )

    # Initialize models
    from diffrhythm.infer.infer_utils import prepare_model

    device = "cuda"
    self.cfm, self.cfm_full, self.tokenizer, self.muq, self.vae = prepare_model(device)

    # Perform warmup
    self.warmup()
```

## Warmup Strategy

Implement warmup to improve cold start performance:

```python theme={null}
def warmup(self):
    self._generate(
        TextToMusicInput(
            lyrics="""[00:10.00]Moonlight spills through broken blinds
[00:13.20]Your shadow dances on the dashboard shrine
[00:16.85]Neon ghosts in gasoline rain
[00:20.40]I hear your laughter down the midnight train
[00:24.15]Static whispers through frayed wires
[00:27.65]Guitar strings hum our cathedral choirs""",
            reference_audio_url="https://storage.googleapis.com/falserverless/model_tests/diffrythm/rock_en.wav",
            num_inference_steps=32,
        ),
        Response(),
    )
```

## Core Generation Logic

The generation method handles complex audio processing workflows:

```python theme={null}
def _generate(self, input: TextToMusicInput, response: Response) -> Output:
    # Custom validation logic
    if not input.style_prompt and not input.reference_audio_url:
        raise FieldException(
            "style_prompt",
            "Either style prompt or reference audio URL must be provided.",
        )

    import torch
    import torchaudio
    from diffrhythm.infer.infer import inference
    from diffrhythm.infer.infer_utils import (
        get_audio_style_prompt,
        get_lrc_token,
        get_reference_latent,
        get_text_style_prompt,
    )

    # Use temporary directory for file handling
    with tempfile.TemporaryDirectory() as output_dir:
        output_path = os.path.join(output_dir, "output.wav")

        # Configure model based on duration
        if input.music_duration == "95s":
            max_frames = 2048
            cfm_model = self.cfm
        else:
            max_frames = 6144
            cfm_model = self.cfm_full

        sway_sampling_coef = -1 if input.num_inference_steps < 32 else None

        # Process lyrics with error handling
        try:
            lrc_prompt, start_time = get_lrc_token(
                max_frames, input.lyrics, self.tokenizer, "cuda"
            )
        except Exception as e:
            print("Error in lrc prompt", e)
            if "Unknown language" in str(e):
                raise FieldException("lyrics", "Unsupported language in lyrics.")

        # Handle reference audio or style prompt
        vocal_flag = False
        if input.reference_audio_url:
            try:
                ref_audio_path = download_file(
                    input.reference_audio_url, target_dir=output_dir
                )
                style_prompt, vocal_flag = get_audio_style_prompt(
                    self.muq, ref_audio_path
                )
            except Exception as e:
                raise FieldException(
                    "reference_audio_url",
                    "The reference audio could not be processed.",
                )
        else:
            try:
                style_prompt = get_text_style_prompt(self.muq, input.style_prompt)
            except Exception as e:
                raise FieldException(
                    "style_prompt", "The style prompt could not be processed."
                )

        # Generate music
        latent_prompt = get_reference_latent("cuda", max_frames)
        sample_rate, generated_song = inference(
            cfm_model=cfm_model,
            vae_model=self.vae,
            cond=latent_prompt,
            text=lrc_prompt,
            duration=max_frames,
            style_prompt=style_prompt,
            negative_style_prompt=self.negative_style_prompt,
            steps=input.num_inference_steps,
            sway_sampling_coef=sway_sampling_coef,
            start_time=start_time,
            file_type="wav",
            cfg_strength=input.cfg_strength,
            vocal_flag=vocal_flag,
            odeint_method=input.scheduler,
        )

        # Save audio file
        torchaudio.save(
            output_path,
            torch.from_numpy(generated_song).transpose(0, 1),
            sample_rate=sample_rate,
        )

        # Calculate billing based on audio duration
        response.headers["x-fal-billable-units"] = str(
            max(math.ceil(generated_song.shape[0] // 441000), 1)
        )

        return Output(audio=File.from_path(output_path))

@fal.endpoint("/")
def generate(self, input: TextToMusicInput, response: Response) -> Output:
    return self._generate(input, response)
```

## Key Concepts and Best Practices

### Custom Docker Images

**When to use:**

* System dependencies required (espeak-ng, ffmpeg)
* Complex installation procedures
* External tools or binaries

**Best practices:**

```python theme={null}
# Pin all versions for reproducibility
FROM pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel

# Clean up after installations
RUN apt-get update && \
    apt-get install -y git espeak-ng ffmpeg && \
    rm -rf /var/lib/apt/lists/*

```

### Repository Cloning

```python theme={null}
repo_path = clone_repository(
    "https://huggingface.co/spaces/ASLP-lab/DiffRhythm",
    commit_hash="0d355fb2211e3f4f04112d8ed30cc9211a79c974",  # Pin commit
    include_to_path=True,  # Add to Python path
    target_dir="/app",
    repo_name="diffrythm",
)
```

### File Management

```python theme={null}
# Download external files
download_file(
    "https://example.com/model.bin",
    target_dir="/path/to/target"
)

# Use temporary directories for processing
with tempfile.TemporaryDirectory() as output_dir:
    output_path = os.path.join(output_dir, "output.wav")
    # Process files...
    return Output(audio=File.from_path(output_path))
```

### Custom Validation

```python theme={null}
# Implement business logic validation
if not input.style_prompt and not input.reference_audio_url:
    raise FieldException(
        "style_prompt",
        "Either style prompt or reference audio URL must be provided.",
    )
```

### Error Handling for External Dependencies

```python theme={null}
try:
    lrc_prompt, start_time = get_lrc_token(
        max_frames, input.lyrics, self.tokenizer, "cuda"
    )
except Exception as e:
    if "Unknown language" in str(e):
        raise FieldException("lyrics", "Unsupported language in lyrics.")
```

### Audio-Specific Billing

```python theme={null}
# Calculate billing based on audio duration
audio_duration_seconds = generated_song.shape[0] / sample_rate
billable_units = max(math.ceil(audio_duration_seconds / 10), 1)  # Per 10-second blocks
response.headers["x-fal-billable-units"] = str(billable_units)
```

## Deployment and Usage

### Running the Service

```bash theme={null}
# Development
fal run fal_demos/audio/diffrhythm.py::DiffRhythm

# Production deployment
fal deploy diffrhythm
```

### Making Requests

```python theme={null}
import fal_client

result = await fal_client.submit_async(
    "your-username/diffrhythm",
    arguments={
        "lyrics": """[00:10.00]Moonlight spills through broken blinds
[00:13.20]Your shadow dances on the dashboard shrine""",
        "reference_audio_url": "https://example.com/reference.wav",
        "music_duration": "95s",
        "num_inference_steps": 32,
    }
)

# Download the generated audio
audio_url = result["audio"]["url"]
```

## Advanced Features Demonstrated

1. **Multi-Model Architecture**: Different models for different durations
2. **Conditional Logic**: Dynamic parameter adjustment based on input
3. **File Processing**: Audio file handling and format conversion
4. **Custom UI Elements**: Textarea fields and importance markers
5. **Comprehensive Validation**: Multiple validation layers with clear error messages
6. **Resource Optimization**: Warmup procedures and efficient model loading

## Use Cases

* **Music Production**: Generate backing tracks from lyrics
* **Content Creation**: Create custom music for videos or podcasts
* **Prototyping**: Quick musical sketches and demos
* **Education**: Teaching music composition and arrangement
* **Game Development**: Dynamic music generation for games

## Key Takeaways

* **Container deployment** enables complex system dependencies
* **Repository cloning** integrates external codebases seamlessly
* **File management utilities** simplify model and data downloading
* **Custom validation** provides better user experience
* **Temporary directories** handle file processing safely
* **Warmup procedures** improve cold start performance
* **Audio-specific billing** aligns costs with resource usage

This pattern is ideal for sophisticated AI applications that require complex dependencies, external repositories, and custom processing workflows while maintaining the scalability and ease of deployment that fal provides.


# https://fal.ai/docs/examples/audio-speech/deploy-text-to-speech-model.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a Text-to-Speech Model

> This example demonstrates how to build a comprehensive text-to-speech service using Kokoro, showcasing CPU-efficient deployment, multi-language support, multiple endpoints with shared logic, and advanced audio processing techniques.

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/blob/main/fal_demos/tts/kokoro.py).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate (if not already done):

```bash theme={null}
fal auth login
```

3. Copy the code below into `kokoro.py`

<CodeGroup>
  ```python kokoro.py wrap theme={null}
  from typing import Literal

  import fal
  from fal.exceptions import FieldException
  from fal.toolkit import File
  from fastapi import Response
  from pydantic import BaseModel, Field


  class AmEnglishRequest(BaseModel):
      prompt: str = Field(
          default="",
          examples=[
              "The future belongs to those who believe in the beauty of their dreams. So, dream big, work hard, and make it happen!"
          ],
          ui={"important": True},
      )
      text: str = Field(
          default="",
          examples=[
              "The future belongs to those who believe in the beauty of their dreams. So, dream big, work hard, and make it happen!"
          ],
      )
      # Use Literal for voice to restrict to specific enum values
      voice: Literal[
          "af_heart",
          "af_alloy",
          "af_aoede",
          "af_bella",
          "af_jessica",
          "af_kore",
          "af_nicole",
          "af_nova",
          "af_river",
          "af_sarah",
          "af_sky",
          "am_adam",
          "am_echo",
          "am_eric",
          "am_fenrir",
          "am_liam",
          "am_michael",
          "am_onyx",
          "am_puck",
          "am_santa",
      ] = Field(
          examples=["af_heart"],
          default="af_heart",
          description="Voice ID for the desired voice.",
      )
      speed: float = Field(
          default=1.0,
          ge=0.1,
          le=5.0,
          description="Speed of the generated audio. Default is 1.0.",
      )


  class BrEnglishRequest(BaseModel):
      prompt: str = Field(
          examples=[
              "Ladies and gentlemen, welcome aboard. Please ensure your seatbelt is fastened and your tray table is stowed as we prepare for takeoff."
          ]
      )
      voice: Literal[
          "bf_alice",
          "bf_emma",
          "bf_isabella",
          "bf_lily",
          "bm_daniel",
          "bm_fable",
          "bm_george",
          "bm_lewis",
      ] = Field(
          examples=["bf_alice"],
          description="Voice ID for the desired voice.",
      )
      speed: float = Field(
          default=1.0,
          ge=0.1,
          le=5.0,
          description="Speed of the generated audio. Default is 1.0.",
      )


  class JapaneseRequest(BaseModel):
      prompt: str = Field(examples=["夢を追いかけることを恐れないでください。努力すれば、必ず道は開けます！"])
      voice: Literal[
          "jf_alpha",
          "jf_gongitsune",
          "jf_nezumi",
          "jf_tebukuro",
          "jm_kumo",
      ] = Field(
          examples=["jf_alpha"],
          description="Voice ID for the desired voice.",
      )
      speed: float = Field(
          default=1.0,
          ge=0.1,
          le=5.0,
          description="Speed of the generated audio. Default is 1.0.",
      )


  class AmEngOutput(BaseModel):
      audio: File = Field(
          description="The generated music",
          examples=[
              File._from_url(
                  "https://fal.media/files/elephant/dXVMqWsBDG9yan3kaOT0Z_tmp0vvkha3s.wav"
              )
          ],
      )


  class BrEngOutput(BaseModel):
      audio: File = Field(
          description="The generated music",
          examples=[
              File._from_url(
                  "https://fal.media/files/kangaroo/4wpA60Kum6UjOVBKJoNyL_tmpxfrkn95k.wav"
              )
          ],
      )


  class JapaneseOutput(BaseModel):
      audio: File = Field(
          description="The generated music",
          examples=[
              File._from_url(
                  "https://fal.media/files/lion/piLhqKO8LJxrWaNg2dVUv_tmpp6eff6zl.wav"
              )
          ],
      )


  class Kokoro(fal.App):
      min_concurrency = 0
      max_concurrency = 1
      keep_alive = 3000
      app_name = "kokoro"
      requirements = [
          "kokoro==0.8.4",
          "soundfile==0.13.1",
          "misaki[en]==0.8.4",
          "misaki[ja]==0.8.4",
          "misaki[zh]==0.8.4",
          "numpy==1.26.4",
          "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl",
      ]
      machine_type = "L"  # Use a CPU machine type since Kokoro is only 82M parameters and runs efficiently on CPU

      async def setup(self):
          from kokoro import KPipeline

          self.pipelines = {}
          self.pipelines["American English"] = KPipeline(lang_code="a")
          self.pipelines["British English"] = KPipeline(lang_code="b")
          self.pipelines["Japanese"] = KPipeline(lang_code="j")

      async def _generate(
          self,
          request: AmEnglishRequest,
          response: Response,
          language: str = "American English",
      ):
          prompt = request.prompt or request.text
          if len(prompt) >= 20000:
              # Use fieldexception to nicely render the error in the UI
              raise FieldException(
                  field="prompt",
                  message="Prompt must be less than 20000 characters.",
              )

          import tempfile

          import numpy as np
          import soundfile as sf

          pipeline = self.pipelines[language]
          generator = pipeline(
              prompt,
              voice=request.voice,
              speed=request.speed,
              split_pattern=r"\n+",
          )
          for i, (gs, ps, audio) in enumerate(generator):
              if i == 0:
                  final_audio = audio.detach().cpu().numpy()
              else:
                  audio = audio.detach().cpu().numpy()
                  final_audio = np.concatenate((final_audio, audio), axis=0)

          # Set the billing units to be a minimum of 1 and scale with 1000 characters
          response.headers["x-fal-billable-units"] = str(max(1, len(prompt) // 1000))

          # Use a temporary file to save the audio and then send it via the cdn through the File object
          with tempfile.NamedTemporaryFile(suffix=".wav") as f:
              sf.write(f.name, final_audio, 24000)
              return AmEngOutput(
                  audio=File.from_path(f.name, content_type="audio/wav", repository="cdn")
              )

      @fal.endpoint("/")
      async def generate(
          self, request: AmEnglishRequest, response: Response
      ) -> AmEngOutput:
          return await self._generate(request, response, language="American English")

      @fal.endpoint("/american-english")
      async def generate_am_english(
          self, request: AmEnglishRequest, response: Response
      ) -> AmEngOutput:
          return await self._generate(request, response, language="American English")

      @fal.endpoint("/british-english")
      async def generate_br_english(
          self, request: BrEnglishRequest, response: Response
      ) -> BrEngOutput:
          return await self._generate(request, response, language="British English")

      @fal.endpoint("/japanese")
      async def generate_japanese(
          self, request: JapaneseRequest, response: Response
      ) -> JapaneseOutput:
          return await self._generate(request, response, language="Japanese")


  ...  # Define the rest of the languages as endpoints similarly
  ```

  ```toml pyproject.toml wrap theme={null}
  [project]
  name = "kokoro-demo"
  version = "0.1.0"
  description = "Kokoro text-to-speech demo"
  requires-python = ">=3.11"
  dependencies = [
      "pydantic>=2.0",
      "fal @ git+https://github.com/fal-ai/fal.git#subdirectory=projects/fal"
  ]

  [tool.fal.apps]
  kokoro = { auth = "shared", ref = "kokoro.py::Kokoro", no_scale=true }
  ```
</CodeGroup>

4. Run the app:

```bash theme={null}
fal run kokoro.py
```

<Info>
  **Or clone this repository**:

  ```bash theme={null}
  git clone https://github.com/fal-ai-community/fal-demos.git
  cd fal-demos
  pip install -e .
  # Use the app name (defined in pyproject.toml)
  fal run kokoro
  # Or use the full file path:
  # fal run fal_demos/tts/kokoro.py::Kokoro
  ```
</Info>

<Tip>
  **Before you run**, make sure you have:

  * Authenticated with fal: `fal auth login`
  * Activated your virtual environment (recommended): `python -m venv venv && source venv/bin/activate` (macOS/Linux) or `venv\Scripts\activate` (Windows)
</Tip>

## Key Features

* **Multi-Language Support**: American English, British English, Japanese with native voices
* **CPU-Efficient Deployment**: Lightweight 82M parameter model runs efficiently on CPU
* **Multiple Endpoints**: Language-specific endpoints with shared generation logic
* **Voice Variety**: Multiple voice options for each supported language
* **Audio Streaming**: Generator-based audio processing for memory efficiency
* **Character-Based Billing**: Usage-based pricing tied to text length
* **Advanced Validation**: Custom error handling with user-friendly messages
* **Audio File Management**: Temporary file handling and CDN integration

## When to Use CPU Deployment

CPU deployment is ideal when:

* Models are lightweight (\< 100M parameters)
* Inference is fast enough on CPU
* Cost optimization is important
* GPU resources are not required
* Multiple concurrent requests can share CPU resources efficiently

## Project Setup

```python theme={null}
from typing import Literal

import fal
from fal.exceptions import FieldException
from fal.toolkit import File
from fastapi import Response
from pydantic import BaseModel, Field
```

## Language-Specific Input Models

Define input models for each supported language with appropriate voice options:

```python theme={null}
class AmEnglishRequest(BaseModel):
    prompt: str = Field(
        default="",
        examples=[
            "The future belongs to those who believe in the beauty of their dreams. So, dream big, work hard, and make it happen!"
        ],
        ui={"important": True},
    )
    text: str = Field(
        default="",
        examples=[
            "The future belongs to those who believe in the beauty of their dreams. So, dream big, work hard, and make it happen!"
        ],
    )
    voice: Literal[
        "af_heart",    # American Female voices
        "af_alloy",
        "af_aoede",
        "af_bella",
        "af_jessica",
        "af_kore",
        "af_nicole",
        "af_nova",
        "af_river",
        "af_sarah",
        "af_sky",
        "am_adam",     # American Male voices
        "am_echo",
        "am_eric",
        "am_fenrir",
        "am_liam",
        "am_michael",
        "am_onyx",
        "am_puck",
        "am_santa",
    ] = Field(
        examples=["af_heart"],
        default="af_heart",
        description="Voice ID for the desired voice.",
    )
    speed: float = Field(
        default=1.0,
        ge=0.1,
        le=5.0,
        description="Speed of the generated audio. Default is 1.0.",
    )

class BrEnglishRequest(BaseModel):
    prompt: str = Field(
        examples=[
            "Ladies and gentlemen, welcome aboard. Please ensure your seatbelt is fastened and your tray table is stowed as we prepare for takeoff."
        ]
    )
    voice: Literal[
        "bf_alice",    # British Female voices
        "bf_emma",
        "bf_isabella",
        "bf_lily",
        "bm_daniel",   # British Male voices
        "bm_fable",
        "bm_george",
        "bm_lewis",
    ] = Field(
        examples=["bf_alice"],
        description="Voice ID for the desired voice.",
    )
    speed: float = Field(
        default=1.0,
        ge=0.1,
        le=5.0,
        description="Speed of the generated audio. Default is 1.0.",
    )

class JapaneseRequest(BaseModel):
    prompt: str = Field(
        examples=["夢を追いかけることを恐れないでください。努力すれば、必ず道は開けます！"]
    )
    voice: Literal[
        "jf_alpha",    # Japanese Female voices
        "jf_gongitsune",
        "jf_nezumi",
        "jf_tebukuro",
        "jm_kumo",     # Japanese Male voices
    ] = Field(
        examples=["jf_alpha"],
        description="Voice ID for the desired voice.",
    )
    speed: float = Field(
        default=1.0,
        ge=0.1,
        le=5.0,
        description="Speed of the generated audio. Default is 1.0.",
    )
```

## Language-Specific Output Models

```python theme={null}
class AmEngOutput(BaseModel):
    audio: File = Field(
        description="The generated audio",
        examples=[
            File._from_url(
                "https://fal.media/files/elephant/dXVMqWsBDG9yan3kaOT0Z_tmp0vvkha3s.wav"
            )
        ],
    )

class BrEngOutput(BaseModel):
    audio: File = Field(
        description="The generated audio",
        examples=[
            File._from_url(
                "https://fal.media/files/kangaroo/4wpA60Kum6UjOVBKJoNyL_tmpxfrkn95k.wav"
            )
        ],
    )

class JapaneseOutput(BaseModel):
    audio: File = Field(
        description="The generated audio",
        examples=[
            File._from_url(
                "https://fal.media/files/lion/piLhqKO8LJxrWaNg2dVUv_tmpp6eff6zl.wav"
            )
        ],
    )
```

## Application Configuration for CPU Deployment

```python theme={null}
class Kokoro(fal.App):
    min_concurrency = 0
    max_concurrency = 1
    keep_alive = 3000  # Longer keep-alive for TTS services
    app_name = "kokoro"
    requirements = [
        "kokoro==0.8.4",
        "soundfile==0.13.1",
        "misaki[en]==0.8.4",  # English language support
        "misaki[ja]==0.8.4",  # Japanese language support
        "misaki[zh]==0.8.4",  # Chinese language support
        "numpy==1.26.4",
        # Spacy model for English NLP
        "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl",
    ]
    machine_type = "L"  # CPU machine - efficient for lightweight models

    async def setup(self):
        from kokoro import KPipeline

        # Initialize pipelines for each supported language
        self.pipelines = {}
        self.pipelines["American English"] = KPipeline(lang_code="a")
        self.pipelines["British English"] = KPipeline(lang_code="b")
        self.pipelines["Japanese"] = KPipeline(lang_code="j")
```

## Shared Generation Logic

Create a reusable generation method that handles all languages:

```python theme={null}
async def _generate(
    self,
    request: AmEnglishRequest,
    response: Response,
    language: str = "American English",
):
    # Handle both 'prompt' and 'text' fields for backwards compatibility
    prompt = request.prompt or request.text

    # Custom validation with user-friendly error messages
    if len(prompt) >= 20000:
        raise FieldException(
            field="prompt",
            message="Prompt must be less than 20000 characters.",
        )

    import tempfile
    import numpy as np
    import soundfile as sf

    # Get the appropriate pipeline for the language
    pipeline = self.pipelines[language]

    # Generate audio using streaming approach
    generator = pipeline(
        prompt,
        voice=request.voice,
        speed=request.speed,
        split_pattern=r"\n+",  # Split on line breaks for better pacing
    )

    # Process audio chunks and concatenate
    for i, (gs, ps, audio) in enumerate(generator):
        if i == 0:
            final_audio = audio.detach().cpu().numpy()
        else:
            audio = audio.detach().cpu().numpy()
            final_audio = np.concatenate((final_audio, audio), axis=0)

    # Character-based billing calculation
    response.headers["x-fal-billable-units"] = str(max(1, len(prompt) // 1000))

    # Save audio to temporary file and upload to CDN
    with tempfile.NamedTemporaryFile(suffix=".wav") as f:
        sf.write(f.name, final_audio, 24000)  # 24kHz sample rate
        return AmEngOutput(
            audio=File.from_path(
                f.name,
                content_type="audio/wav",
                repository="cdn"  # Upload to CDN for fast access
            )
        )
```

## Multiple Endpoint Definitions

Define language-specific endpoints using the shared generation logic:

```python theme={null}
@fal.endpoint("/")
async def generate(
    self, request: AmEnglishRequest, response: Response
) -> AmEngOutput:
    return await self._generate(request, response, language="American English")

@fal.endpoint("/american-english")
async def generate_am_english(
    self, request: AmEnglishRequest, response: Response
) -> AmEngOutput:
    return await self._generate(request, response, language="American English")

@fal.endpoint("/british-english")
async def generate_br_english(
    self, request: BrEnglishRequest, response: Response
) -> BrEngOutput:
    return await self._generate(request, response, language="British English")

@fal.endpoint("/japanese")
async def generate_japanese(
    self, request: JapaneseRequest, response: Response
) -> JapaneseOutput:
    return await self._generate(request, response, language="Japanese")
```

## Key Concepts and Best Practices

### CPU-Efficient Deployment

**Why CPU for TTS:**

* Kokoro is only 82M parameters - runs efficiently on CPU
* Lower cost compared to GPU instances
* Sufficient performance for real-time TTS
* Better resource utilization for multiple concurrent requests

### Audio Streaming and Memory Management

**Generator-based processing:**

```python theme={null}
# Stream audio generation to handle long texts efficiently
generator = pipeline(prompt, voice=request.voice, speed=request.speed)

# Process chunks incrementally
for i, (gs, ps, audio) in enumerate(generator):
    if i == 0:
        final_audio = audio.detach().cpu().numpy()
    else:
        final_audio = np.concatenate((final_audio, audio), axis=0)
```

### Character-Based Billing

```python theme={null}
# Scale billing with text length (per 1000 characters)
response.headers["x-fal-billable-units"] = str(max(1, len(prompt) // 1000))
```

### Audio File Handling

```python theme={null}
# Use temporary files for audio processing
with tempfile.NamedTemporaryFile(suffix=".wav") as f:
    sf.write(f.name, final_audio, 24000)  # Save with proper sample rate
    return Output(
        audio=File.from_path(
            f.name,
            content_type="audio/wav",
            repository="cdn"  # Auto-upload to CDN
        )
    )
```

### Multi-Language Architecture

**Pipeline initialization:**

```python theme={null}
self.pipelines = {
    "American English": KPipeline(lang_code="a"),
    "British English": KPipeline(lang_code="b"),
    "Japanese": KPipeline(lang_code="j"),
}
```

**Language-specific voice options:**

```python theme={null}
# American English voices
voice: Literal[
    "af_heart", "af_alloy", "af_aoede",  # Female
    "am_adam", "am_echo", "am_eric",     # Male
]

# British English voices
voice: Literal[
    "bf_alice", "bf_emma", "bf_lily",    # Female
    "bm_daniel", "bm_george", "bm_lewis" # Male
]
```

## Advanced Features

### Custom Validation

```python theme={null}
if len(prompt) >= 20000:
    raise FieldException(
        field="prompt",
        message="Prompt must be less than 20000 characters.",
    )
```

### Backwards Compatibility

```python theme={null}
# Support both 'prompt' and 'text' field names
prompt = request.prompt or request.text
```

### Flexible Text Processing

```python theme={null}
generator = pipeline(
    prompt,
    voice=request.voice,
    speed=request.speed,
    split_pattern=r"\n+",  # Split on paragraphs for natural pacing
)
```

## Deployment and Usage

### Running the Service

```bash theme={null}
# Development
fal run fal_demos/tts/kokoro.py::Kokoro

# Production deployment
fal deploy kokoro
```

### Making Requests

**American English:**

```python theme={null}
import fal_client

result = await fal_client.submit_async(
    "your-username/kokoro/american-english",
    arguments={
        "prompt": "Hello, this is a test of American English text-to-speech!",
        "voice": "af_heart",
        "speed": 1.2
    }
)
```

**British English:**

```python theme={null}
result = await fal_client.submit_async(
    "your-username/kokoro/british-english",
    arguments={
        "prompt": "Cheerio! This is British English text-to-speech.",
        "voice": "bf_alice",
        "speed": 1.0
    }
)
```

**Japanese:**

```python theme={null}
result = await fal_client.submit_async(
    "your-username/kokoro/japanese",
    arguments={
        "prompt": "こんにちは、これは日本語の音声合成です。",
        "voice": "jf_alpha",
        "speed": 0.9
    }
)
```

## Use Cases

* **Content Creation**: Generate voiceovers for videos and podcasts
* **Accessibility**: Convert text content to audio for visually impaired users
* **E-Learning**: Create educational content with natural-sounding narration
* **Customer Service**: Generate dynamic audio responses for chatbots
* **Multilingual Applications**: Support global audiences with native-sounding voices
* **Book Reading**: Convert written content to audiobooks

## Performance Optimizations

### Memory Efficiency

```python theme={null}
# Stream processing prevents memory buildup for long texts
for i, (gs, ps, audio) in enumerate(generator):
    # Process incrementally rather than loading all at once
```

### Cost Optimization

```python theme={null}
machine_type = "L"  # CPU is sufficient and cost-effective
keep_alive=3000     # Longer keep-alive reduces cold starts
```

## Key Takeaways

* **CPU deployment** is ideal for lightweight models like Kokoro (82M parameters)
* **Multi-language support** requires separate pipelines and voice models
* **Character-based billing** aligns costs with resource usage
* **Audio streaming** handles long texts efficiently without memory issues
* **Temporary file handling** with CDN upload provides fast, reliable audio delivery
* **Multiple endpoints** with shared logic offer flexibility while maintaining DRY principles
* **Custom validation** provides better user experience with clear error messages

This pattern is perfect for building production-ready TTS services that need to support multiple languages and voices while maintaining cost efficiency and high performance through CPU-optimized deployment.


# https://fal.ai/docs/examples/deploy-models-with-custom-containers.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Models with Custom Containers

> fal now supports running apps within custom Docker containers, providing greater flexibility and control over your environment.

### Example: Using Custom Containers with fal Apps

Here's a complete example demonstrating how to use custom containers with `fal`.

```python theme={null}
import fal

from fal.container import ContainerImage

dockerfile_str = """
FROM python:3.11

RUN apt-get update && apt-get install -y ffmpeg
RUN pip install pyjokes ffmpeg-python
"""

custom_image = ContainerImage.from_dockerfile_str(
    dockerfile_str,
    registries={
        "https://my.registry.io/": {
            "username": <username>,
            "password": <password>,
        },
    },
)

class Test(fal.App):
    image = custom_image
    machine_type = "GPU"

    requirements = ["torch"]

    def setup(self):
        import subprocess
        subprocess.run(["nvidia-smi"])

    @fal.endpoint("/")
    def index(self):
        return "Hello, World!"
```

#### Detailed Explanation

1. **Importing fal and ContainerImage**:

```python theme={null}
import fal
from fal.container import ContainerImage
```

2. **Creating a Dockerfile String**:
   A multi-line string (`dockerfile_str`) is defined, specifying the base image as `python:3.11`, and installing `ffmpeg` and `pyjokes` packages.

```python theme={null}
dockerfile_str = """
FROM python:3.11

RUN apt-get update && apt-get install -y ffmpeg
RUN pip install pyjokes ffmpeg-python
"""
```

<Note>
  **Version mismatch**

  Ensure that the Python version in the Dockerfile matches the Python version in
  your local environment that you use to run the app.

  This is required to avoid any compatibility issues. We use `pickle` to serialize
  the app under the hood, and the Python versions must match to avoid any
  serialization issues.

  That being said, we are constantly working on improving this experience.
</Note>

Alternatively, you can use a Dockerfile path to specify the Dockerfile location:

```python theme={null}
import pathlib
PWD = Path(__file__).resolve().parent

class Test(fal.App):
    image = ContainerImage.from_dockerfile(f"{PWD}/Dockerfile")
```

#### Running the App

To run the app, save the code to a file (e.g., `test_container.py`) and execute it using the `fal run` command:

```bash theme={null}
fal run test_container.py
```

This example demonstrates how to leverage Docker containers in fal, enabling customized execution environments for your apps. For more details and advanced usage, refer to the [fal Container Documentation](/serverless/development/use-custom-container-image).


# https://fal.ai/docs/examples/image-generation/deploy-comfyui-server.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a ComfyUI SDXL Turbo App

> Build a serverless image generation API using ComfyUI and SDXL Turbo on fal.

This tutorial shows how to deploy [ComfyUI](https://github.com/comfyanonymous/ComfyUI) with SDXL Turbo on fal. We'll create a proxy app that wraps ComfyUI with a clean REST API, complete with Pydantic validation and automatic CDN uploads.

SDXL Turbo generates high-quality images in just 1-4 inference steps, making it ideal for fast serverless inference.

## 🚀 Try this Example

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate:

```bash theme={null}
fal auth login
```

3. Create the workflow file `sdxl_turbo_workflow.json`:

```json theme={null}
{
  "5": {
    "inputs": {"width": 512, "height": 512, "batch_size": 1},
    "class_type": "EmptyLatentImage",
    "_meta": {"title": "Empty Latent Image"}
  },
  "6": {
    "inputs": {"text": "beautiful landscape", "clip": ["20", 1]},
    "class_type": "CLIPTextEncode",
    "_meta": {"title": "CLIP Text Encode (Positive)"}
  },
  "7": {
    "inputs": {"text": "text, watermark", "clip": ["20", 1]},
    "class_type": "CLIPTextEncode",
    "_meta": {"title": "CLIP Text Encode (Negative)"}
  },
  "8": {
    "inputs": {"samples": ["13", 0], "vae": ["20", 2]},
    "class_type": "VAEDecode",
    "_meta": {"title": "VAE Decode"}
  },
  "13": {
    "inputs": {
      "add_noise": true,
      "noise_seed": 0,
      "cfg": 1,
      "model": ["20", 0],
      "positive": ["6", 0],
      "negative": ["7", 0],
      "sampler": ["14", 0],
      "sigmas": ["22", 0],
      "latent_image": ["5", 0]
    },
    "class_type": "SamplerCustom",
    "_meta": {"title": "SamplerCustom"}
  },
  "14": {
    "inputs": {"sampler_name": "euler_ancestral"},
    "class_type": "KSamplerSelect",
    "_meta": {"title": "KSamplerSelect"}
  },
  "20": {
    "inputs": {"ckpt_name": "sd_xl_turbo_1.0_fp16.safetensors"},
    "class_type": "CheckpointLoaderSimple",
    "_meta": {"title": "Load Checkpoint"}
  },
  "22": {
    "inputs": {"steps": 1, "denoise": 1, "model": ["20", 0]},
    "class_type": "SDTurboScheduler",
    "_meta": {"title": "SDTurboScheduler"}
  },
  "27": {
    "inputs": {"filename_prefix": "ComfyUI", "images": ["8", 0]},
    "class_type": "SaveImage",
    "_meta": {"title": "Save Image"}
  }
}
```

4. Copy the code below into `comfyui_sdxl_turbo.py`:

```python theme={null}
import json
import random
import subprocess
import time
from copy import deepcopy
from pathlib import Path

import fal
import requests
from fal.container import ContainerImage
from fal.toolkit import File, Image, download_model_weights
from fastapi import Request
from pydantic import BaseModel, Field


# =============================================================================
# UPLOAD WORKFLOW TO FAL CDN (happens at module load time)
# =============================================================================

WORKFLOW_PATH = Path(__file__).parent / "sdxl_turbo_workflow.json"
WORKFLOW_URL = File.from_path(str(WORKFLOW_PATH), repository="cdn").url


# =============================================================================
# PYDANTIC MODELS
# =============================================================================

class ImageRequest(BaseModel):
    prompt: str = Field(
        description="The text prompt describing the image to generate.",
        examples=["beautiful landscape scenery glass bottle with a galaxy inside"],
    )
    negative_prompt: str = Field(
        default="text, watermark, blurry, low quality",
        description="Negative prompt to guide what to avoid in generation.",
    )
    width: int = Field(default=512, ge=256, le=1024)
    height: int = Field(default=512, ge=256, le=1024)
    num_inference_steps: int = Field(default=1, ge=1, le=4)
    seed: int = Field(default_factory=lambda: random.randint(0, 2**31 - 1))


class ImageResponse(BaseModel):
    image: Image = Field(description="The generated image.")
    seed: int = Field(description="The seed used for generation.")


# =============================================================================
# DOCKERFILE - Uses ADD to download workflow.json from fal CDN during build
# =============================================================================

DOCKERFILE_STR = f"""
FROM falai/base:3.11-12.1.0

USER root

RUN apt-get update && apt-get install -y --no-install-recommends \\
    git wget libgl1-mesa-glx libglib2.0-0 && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/comfyanonymous/ComfyUI /app/ComfyUI
WORKDIR /app/ComfyUI
RUN pip install --no-cache-dir -r requirements.txt
RUN mkdir -p models/checkpoints

# Download workflow from fal CDN
ADD {WORKFLOW_URL} /app/workflow.json

# Install fal packages LAST
RUN pip install --no-cache-dir boto3==1.35.74 protobuf==4.25.1 pydantic==2.10.6
"""


# =============================================================================
# MODEL CONFIGURATION - Downloaded to /data at runtime
# =============================================================================

MODELS = {
    "checkpoints/sd_xl_turbo_1.0_fp16.safetensors": 
        "https://huggingface.co/stabilityai/sdxl-turbo/resolve/main/sd_xl_turbo_1.0_fp16.safetensors",
}


# =============================================================================
# FAL APP
# =============================================================================

class ComfyUISDXLTurbo(fal.App, keep_alive=300, max_concurrency=1):
    machine_type = "GPU-A100"
    image = ContainerImage.from_dockerfile_str(DOCKERFILE_STR)
    
    COMFYUI_HOST = "127.0.0.1"
    COMFYUI_PORT = 8188
    COMFYUI_DIR = Path("/app/ComfyUI")
    
    def setup(self):
        self.process = None
        self.workflow_template = None
        
        # Download models to persistent /data storage
        self._download_models()
        self._link_models()
        
        # Start ComfyUI server in background (non-blocking)
        self.process = subprocess.Popen(
            ["python", "main.py", "--listen", self.COMFYUI_HOST, "--port", str(self.COMFYUI_PORT)],
            cwd=str(self.COMFYUI_DIR),
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )
        self._wait_for_server(timeout=120)
        
        # Load workflow template
        with open("/app/workflow.json", encoding="utf-8") as f:
            self.workflow_template = json.load(f)
    
    def _download_models(self):
        """Download models using fal toolkit (handles atomic writes automatically)."""
        self._downloaded_paths = {}
        for model_path, url in MODELS.items():
            # download_model_weights handles caching and atomic writes
            downloaded_path = download_model_weights(url)
            self._downloaded_paths[model_path] = downloaded_path
    
    def _link_models(self):
        """Symlink models from downloaded paths to ComfyUI's models directory."""
        for model_path in MODELS:
            downloaded_path = self._downloaded_paths[model_path]
            comfy_path = self.COMFYUI_DIR / "models" / model_path
            comfy_path.parent.mkdir(parents=True, exist_ok=True)
            if comfy_path.exists() or comfy_path.is_symlink():
                comfy_path.unlink()
            comfy_path.symlink_to(downloaded_path)
    
    def _wait_for_server(self, timeout: int = 120):
        start = time.time()
        while time.time() - start < timeout:
            try:
                resp = requests.get(f"http://{self.COMFYUI_HOST}:{self.COMFYUI_PORT}/system_stats", timeout=5)
                if resp.status_code == 200:
                    return
            except requests.ConnectionError:
                pass
            time.sleep(1)
        raise TimeoutError("ComfyUI server did not start")
    
    def _build_workflow(self, request: ImageRequest) -> dict:
        workflow = deepcopy(self.workflow_template)
        workflow["6"]["inputs"]["text"] = request.prompt
        workflow["7"]["inputs"]["text"] = request.negative_prompt
        workflow["5"]["inputs"]["width"] = request.width
        workflow["5"]["inputs"]["height"] = request.height
        workflow["13"]["inputs"]["noise_seed"] = request.seed
        workflow["22"]["inputs"]["steps"] = request.num_inference_steps
        return workflow
    
    def _queue_prompt(self, prompt: dict) -> str:
        resp = requests.post(
            f"http://{self.COMFYUI_HOST}:{self.COMFYUI_PORT}/prompt",
            json={"prompt": prompt},
            timeout=30,
        )
        resp.raise_for_status()
        return resp.json()["prompt_id"]
    
    def _poll_for_completion(self, prompt_id: str, timeout: int = 120) -> dict:
        start = time.time()
        while time.time() - start < timeout:
            resp = requests.get(
                f"http://{self.COMFYUI_HOST}:{self.COMFYUI_PORT}/history/{prompt_id}",
                timeout=30,
            )
            resp.raise_for_status()
            history = resp.json()
            if prompt_id in history:
                prompt_history = history[prompt_id]
                if prompt_history.get("status", {}).get("completed", False):
                    return prompt_history
            time.sleep(0.5)
        raise TimeoutError("Generation did not complete")
    
    def _get_output_image(self, history: dict) -> str | None:
        for node_output in history.get("outputs", {}).values():
            if "images" in node_output and node_output["images"]:
                filename = node_output["images"][0].get("filename")
                subfolder = node_output["images"][0].get("subfolder", "")
                if filename:
                    if subfolder:
                        return f"{self.COMFYUI_DIR}/output/{subfolder}/{filename}"
                    return f"{self.COMFYUI_DIR}/output/{filename}"
        return None
    
    @fal.endpoint("/generate")
    def generate_image(self, input: ImageRequest, request: Request) -> ImageResponse:
        workflow = self._build_workflow(input)
        prompt_id = self._queue_prompt(workflow)
        history = self._poll_for_completion(prompt_id)
        
        image_path = self._get_output_image(history)
        if not image_path:
            raise RuntimeError("No image output found")
        
        image = Image.from_path(image_path, request=request)
        return ImageResponse(image=image, seed=input.seed)
```

5. Run the app:

```bash theme={null}
fal run comfyui_sdxl_turbo.py
```

<Tip>
  **Before you run**, make sure you have:

  * Authenticated with fal: `fal auth login`
  * Created the `sdxl_turbo_workflow.json` file in the same directory
</Tip>

## Architecture Overview

The app runs ComfyUI as a background process and communicates with it via HTTP:

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant fal Gateway
    participant fal.App
    participant ComfyUI Server

    Client->>fal Gateway: POST /generate
    fal Gateway->>fal.App: Forward request
    fal.App->>ComfyUI Server: POST /prompt (queue workflow)
    ComfyUI Server-->>fal.App: prompt_id
    loop Poll for completion
        fal.App->>ComfyUI Server: GET /history/{prompt_id}
        ComfyUI Server-->>fal.App: status + outputs
    end
    fal.App->>fal.App: Upload image to CDN
    fal.App-->>fal Gateway: ImageResponse
    fal Gateway-->>Client: JSON response
```

## Key Concepts

### Including the Workflow File

Container apps don't support `COPY` instructions or `app_files` for including local files. Instead, we upload the workflow to fal's CDN and use `ADD` in the Dockerfile:

```python theme={null}
from fal.toolkit import File

WORKFLOW_PATH = Path(__file__).parent / "sdxl_turbo_workflow.json"
WORKFLOW_URL = File.from_path(str(WORKFLOW_PATH), repository="cdn").url

DOCKERFILE_STR = f"""
...
ADD {WORKFLOW_URL} /app/workflow.json
...
"""
```

See [Use Custom Container Images](/serverless/development/use-custom-container-image) for more details.

### Runtime Model Loading

Large model weights are downloaded to `/data` (persistent storage) at runtime using `download_model_weights` from fal's toolkit:

```python theme={null}
from fal.toolkit import download_model_weights

def _download_models(self):
    self._downloaded_paths = {}
    for model_path, url in MODELS.items():
        # download_model_weights handles caching and atomic writes
        downloaded_path = download_model_weights(url)
        self._downloaded_paths[model_path] = downloaded_path
```

The `download_model_weights` function:

* **Atomic writes**: Downloads to a temp file first, then renames (prevents corrupted files if multiple workers start simultaneously)
* **Automatic caching**: Skips download if the file already exists
* **Smart storage**: Saves to `/data/.fal/model_weights/{hash}/{filename}`

<Tip>
  **Why not bake models into Docker?**

  * Docker images must be pulled on cold starts - larger images = slower cold starts
  * `/data` is a distributed filesystem - once downloaded, models are available to all workers
</Tip>

### Symlinking Models

ComfyUI expects models in specific directories. We create symlinks from ComfyUI's model directories to the downloaded paths:

```python theme={null}
def _link_models(self):
    for model_path in MODELS:
        downloaded_path = self._downloaded_paths[model_path]
        comfy_path = self.COMFYUI_DIR / "models" / model_path
        comfy_path.parent.mkdir(parents=True, exist_ok=True)
        if comfy_path.exists() or comfy_path.is_symlink():
            comfy_path.unlink()
        comfy_path.symlink_to(downloaded_path)
```

### Background Server with Popen

ComfyUI runs as a non-blocking background process using `subprocess.Popen`. Unlike `subprocess.run()` which blocks until completion, `Popen` starts the process and returns immediately, allowing your app to continue setup:

```python theme={null}
def setup(self):
    # Popen starts ComfyUI in the background (non-blocking)
    self.process = subprocess.Popen(
        ["python", "main.py", "--listen", "127.0.0.1", "--port", "8188"],
        cwd=str(self.COMFYUI_DIR),
        stdout=subprocess.PIPE,
    )
    
    # Wait for the server to be ready before accepting requests
    self._wait_for_server()
```

The server continues running for the lifetime of the worker, handling multiple requests.

### ComfyUI API Interaction

The app communicates with ComfyUI via its HTTP API:

1. **Queue prompt**: `POST /prompt` with the workflow JSON
2. **Poll for completion**: `GET /history/{prompt_id}` until `completed: true`
3. **Get outputs**: Extract file paths from the history response

```python theme={null}
def _queue_prompt(self, prompt: dict) -> str:
    resp = requests.post(f"http://127.0.0.1:8188/prompt", json={"prompt": prompt})
    return resp.json()["prompt_id"]
```

### Image Output with fal Toolkit

Use `Image.from_path()` to upload generated images to fal's CDN:

```python theme={null}
from fal.toolkit import Image

image = Image.from_path(image_path, request=request)
return ImageResponse(image=image, seed=input.seed)
```

The `request` parameter ensures proper metadata is attached for the fal playground.

## Customizing the Workflow

### Exporting from ComfyUI

1. Build your workflow in ComfyUI's web interface
2. Click **Save (API Format)** to export as JSON
3. Replace the contents of `sdxl_turbo_workflow.json`

### Mapping Node IDs

When you export a workflow, each node has an ID. Update `_build_workflow()` to map your inputs to the correct node IDs:

```python theme={null}
def _build_workflow(self, request: ImageRequest) -> dict:
    workflow = deepcopy(self.workflow_template)
    
    # Find the correct node IDs by inspecting your workflow JSON
    workflow["6"]["inputs"]["text"] = request.prompt      # CLIP Text Encode (Positive)
    workflow["7"]["inputs"]["text"] = request.negative_prompt  # CLIP Text Encode (Negative)
    workflow["5"]["inputs"]["width"] = request.width      # EmptyLatentImage
    # ... etc
    
    return workflow
```

## Best Practices

1. **Use `/data` for model weights**: Download large models to `/data` in `setup()` instead of baking them into the Docker image. This improves cold start times.

2. **Pin your dependencies**: Specify exact versions in the Dockerfile to ensure reproducible builds.

3. **Set appropriate timeouts**: Model loading and generation can take time. Use generous timeouts.

4. **Use `keep_alive`**: Set `keep_alive` to avoid cold starts between requests.

## Troubleshooting

### Model Not Found

Check that:

1. The model is downloaded to the correct path in `/data`
2. The symlink points to the correct file
3. The workflow uses the correct model filename

### Permission Errors in Dockerfile

The `falai/base` image runs as a non-root user. Add `USER root` before `apt-get`:

```dockerfile theme={null}
FROM falai/base:3.11-12.1.0
USER root
RUN apt-get update && apt-get install -y git wget
```

## Using an External Registry?

If you have a ComfyUI Docker image hosted on an external registry (Docker Hub, Google Artifact Registry, Amazon ECR), you can pull it directly instead of building from a Dockerfile. See [Using Private Docker Registries](/serverless/development/use-custom-container-image#using-private-docker-registries) for setup instructions.

## Next Steps

* [Migrate External Docker Servers](/serverless/migrations/migrate-external-docker-server) - Direct port exposure vs. proxy pattern
* [Use Custom Container Images](/serverless/development/use-custom-container-image) - Dockerfile patterns
* [Use Persistent Storage](/serverless/development/use-persistent-storage) - More about `/data` directory
* [Scale Your Application](/serverless/deployment-operations/scale-your-application) - Handle more traffic


# https://fal.ai/docs/examples/image-generation/deploy-text-to-image-model.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a Text-to-Image Model

This example demonstrates how to build a production-ready text-to-image API using the fal SDK with the Sana diffusion models. We'll create two endpoints: a standard endpoint and a faster "sprint" endpoint that shares resources efficiently.

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/blob/main/fal_demos/image/sana.py).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate (if not already done):

```bash theme={null}
fal auth login
```

3. Copy the code below into `sana.py`

<CodeGroup>
  ```python sana.py wrap theme={null}
  # Only import the python bundled packages, fal and fastapi in the global scope, app specific imports must be inside a function
  import math
  from typing import Literal

  import fal
  from fal.toolkit.image import ImageSizeInput, Image, ImageSize, get_image_size
  from fal.toolkit.image.safety_checker import postprocess_images
  from fastapi import Response
  from pydantic import Field, BaseModel

  # Base Output Model, it can be reused for image endpoints
  class Output(BaseModel):
      images: list[Image] = Field(description="The generated image files info.")
      seed: int = Field(
          description="""
              Seed of the generated Image. It will be the same value of the one passed in the
              input or the randomly generated that was used in case none was passed.
          """
      )
      has_nsfw_concepts: list[bool] = Field(
          description="Whether the generated images contain NSFW concepts."
      )
      prompt: str = Field(
          description="The prompt used for generating the image.",
      )


  # The input model for the inference request, make sure to set the title and description for each field
  # and set the examples for the fields that are not optional
  class BaseInput(BaseModel):
      prompt: str = Field(
          title="Prompt",
          description="The prompt to generate an image from.",
          # Set the example to show it on the playground
          examples=[
              "Underwater coral reef ecosystem during peak bioluminescent activity, multiple layers of marine life - from microscopic plankton to massive coral structures, light refracting through crystal-clear tropical waters, creating prismatic color gradients, hyper-detailed texture of marine organisms",
          ],
      )
      negative_prompt: str = Field(
          default="",
          description="""
              The negative prompt to use. Use it to address details that you don't want
              in the image. This could be colors, objects, scenery and even the small details
              (e.g. moustache, blurry, low resolution).
          """,
          examples=[
              "",
          ],
      )
      # Use the ImageSizeInput to set the image size, it will be converted to ImageSize
      image_size: ImageSizeInput = Field(
          default=ImageSize(width=3840, height=2160),
          description="The size of the generated image.",
      )
      num_inference_steps: int = Field(
          default=18,
          description="The number of inference steps to perform.",
          # set the least and max values whenver possible to limit the input values
          ge=1,
          le=50,
      )
      seed: int | None = Field(
          default=None,
          description="""
              The same seed and the same prompt given to the same version of the model
              will output the same image every time.
          """,
      )
      guidance_scale: float = Field(
          default=5.0,
          description="""
              The CFG (Classifier Free Guidance) scale is a measure of how close you want
              the model to stick to your prompt when looking for a related image to show you.
          """,
          ge=0.0,
          le=20.0,
          title="Guidance scale (CFG)",
      )
      enable_safety_checker: bool = Field(
          default=True,
          description="If set to true, the safety checker will be enabled.",
      )
      num_images: int = Field(
          default=1,
          description="The number of images to generate.",
          ge=1,
          le=4,
      )
      output_format: Literal["jpeg", "png"] = Field(
          default="jpeg",
          description="The format of the generated image.",
      )

  # For the base endpoint
  class TextToImageInput(BaseInput):
      pass

  # For the sprint endpoint, we can reuse the base input model and override the fields that we want to change
  class SprintInput(BaseInput):
      num_inference_steps: int = Field(
          default=2,
          description="The number of inference steps to perform.",
          ge=1,
          le=20,
      )


  class SanaOutput(Output):
      images: list[Image] = Field(
          description="The generated image files info.",
          # Set default examples to show a generated image when the user visits the playground
          examples=[
              [
                  Image(
                      url="https://fal.media/files/kangaroo/QAABS8yM6X99WhiMeLcoL.jpeg",
                      width=3840,
                      height=2160,
                      content_type="image/jpeg",
                  )
              ],
          ],
      )

  class SanaSprintOutput(Output):
      images: list[Image] = Field(
          description="The generated image files info.",
          # Set default examples to show a generated image when the user visits the playground
          examples=[
              [
                  Image(
                      url="https://v3.fal.media/files/penguin/Q-i_zCk-Xf5EggWA9OmG2_e753bacc9b324050855f9664deda3618.jpg",
                      width=3840,
                      height=2160,
                      content_type="image/jpeg",
                  )
              ],
          ],
      )


  class Sana(fal.App):
      """
      Specify requirements as follows and make sure to pin the versions of packages and commit hashes to ensure reliability.
      """
      keep_alive = 60  # The worker will be kept alive for 10 minutes after the last request
      min_concurrency = 0  # The minimum number of concurrent workers to keep alive, if set to 0, the app will startup when the first request is received
      max_concurrency = 2  # The maximum number of concurrent workers to acquire, it helps limit the number of concurrent requests to the app
      app_name = "sana"  # set the app name, the endpoint will be served at username/sana
      requirements = [
          "torch==2.6.0",
          "accelerate==1.6.0",
          "transformers==4.51.3",
          "git+https://github.com/huggingface/diffusers.git@f4fa3beee7f49b80ce7a58f9c8002f43299175c9",
          "hf_transfer==0.1.9",
          "peft==0.15.0",
          "sentencepiece==0.2.0",
          "--extra-index-url",
          "https://download.pytorch.org/whl/cu124",
      ]
      machine_type = "GPU-H100" # Choose machine type from https://docs.fal.ai/private-serverless-models/resources/

      def setup(self):
          """
          This method is called once when the app is started. Use it to load your model and cache it for all requests.
          """
          # Import the libraries inside the setup method since these are installed in the worker enviroment as set in the requirements
          import torch
          from diffusers import SanaPipeline, SanaSprintPipeline

          self.pipes = {}
          self.pipes["base"] = SanaPipeline.from_pretrained(
              "Efficient-Large-Model/Sana_1600M_1024px_BF16_diffusers",
              torch_dtype=torch.bfloat16,
          ).to("cuda")
          self.pipes["base"].text_encoder.to(torch.bfloat16)

          self.pipes["sprint"] = SanaSprintPipeline.from_pretrained(
              "Efficient-Large-Model/Sana_Sprint_1.6B_1024px_diffusers",
              text_encoder=self.pipes["base"].text_encoder, # Reuse the text encoder from the base pipeline
              torch_dtype=torch.bfloat16,
          ).to("cuda")

      async def _generate(
          self,
          input: TextToImageInput,
          response: Response,
          model_id: str,
      ) -> Output:
          """
          Reuse the Inference code for both endpoints. Both the base and sprint pipelines have very similar inference code.
          """
          import torch

          # Preprocess the input
          image_size = get_image_size(
              input.image_size,
          )

          seed = input.seed or torch.seed()
          generator = torch.Generator("cuda").manual_seed(seed)

          model_input = {
              "prompt": input.prompt,
              "negative_prompt": input.negative_prompt,
              "num_inference_steps": input.num_inference_steps,
              "guidance_scale": input.guidance_scale,
              "height": image_size.height,
              "width": image_size.width,
              "num_images_per_prompt": input.num_images,
              "generator": generator,
          }
          if model_id == "sprint":
              # Negative prompt is not supported in the sprint pipeline
              model_input.pop("negative_prompt")
          

          # Generate the images
          images = self.pipes[model_id](**model_input).images


          # Perform the safety check
          postprocessed_images = postprocess_images(
                  images,
                  input.enable_safety_checker,
              )

          # Pricing 
          resolution_factor = math.ceil(
              (image_size.width * image_size.height) / (1024 * 1024)
          )
          # The number of billable units is the resolution factor multiplied by the number of images
          response.headers["x-fal-billable-units"] = str(
              resolution_factor * input.num_images
          )
          # The cost is set in the billing dashboard which is calculated as the number of billable units multiplied by the cost per unit

          return Output(
              images=[
                  Image.from_pil(image, input.output_format)
                  for image in postprocessed_images["images"]
              ],
              seed=seed,
              has_nsfw_concepts=postprocessed_images["has_nsfw_concepts"],
              prompt=input.prompt,
          )

      @fal.endpoint("/")
      async def generate(
          self,
          input: TextToImageInput, # This will be used to autgenerate the OpenAPI spec and the playground form
          response: Response, # This is the response object that will be used to set the headers for setting the billing units
      ) -> SanaOutput: # This is the output object that will be used to autgenerate the OpenAPI spec
          return await self._generate(input, response, "base")

      @fal.endpoint("/sprint")
      async def generate_sprint(
          self,
          input: SprintInput, # Use a different input class for the sprint endpoint to change example values and remove the negative prompt
          response: Response,
      ) -> SanaSprintOutput:
          return await self._generate(input, response, "sprint")

  # Run the app with:
  #   cd fal_demos/image
  #   fal run sana
  #
  # Or directly with:
  #   fal run fal_demos/image/sana.py::Sana 
  #
  # The app will be served on an ephemeral URL, example: https://fal.ai/dashboard/sdk/fal-ai/9fe9b6fc-534d-4926-95b1-87b7f15a67de
  # Visit https://fal.ai/dashboard/sdk/fal-ai/9fe9b6fc-534d-4926-95b1-87b7f15a67de to test the root endpoint
  # To test the sprint endpoint, visit https://fal.ai/dashboard/sdk/fal-ai/9fe9b6fc-534d-4926-95b1-87b7f15a67de/sprint
  ```

  ```toml pyproject.toml wrap theme={null}
  [project]
  name = "sana-demo"
  version = "0.1.0"
  description = "Sana text-to-image generation demo"
  requires-python = ">=3.11"
  dependencies = [
      "pydantic>=2.0",
      "fal @ git+https://github.com/fal-ai/fal.git#subdirectory=projects/fal"
  ]

  [tool.fal.apps]
  sana = { auth = "shared", ref = "sana.py::Sana", no_scale=true }
  ```
</CodeGroup>

4. Run the app:

```bash theme={null}
fal run sana.py
```

<Info>
  **Or clone this repository**:

  ```bash theme={null}
  git clone https://github.com/fal-ai-community/fal-demos.git
  cd fal-demos
  pip install -e .
  # Use the app name (defined in pyproject.toml)
  fal run sana
  # Or use the full file path:
  # fal run fal_demos/image/sana.py::Sana
  ```
</Info>

<Tip>
  **Before you run**, make sure you have:

  * Authenticated with fal: `fal auth login`
  * Activated your virtual environment (recommended): `python -m venv venv && source venv/bin/activate` (macOS/Linux) or `venv\Scripts\activate` (Windows)
</Tip>

## Key Features

* **Multiple endpoints** with shared model components
* **Input validation** using Pydantic models
* **Safety checking** for generated content
* **Flexible image generation** with customizable parameters

## Project Structure

```python theme={null}
# Only import the python bundled packages, fal and fastapi in the global scope
import math
from typing import Literal

import fal
from fal.toolkit.image import ImageSizeInput, Image, ImageSize, get_image_size
from fal.toolkit.image.safety_checker import postprocess_images
from fastapi import Response
from pydantic import Field, BaseModel
from fal_demos.image.common import Output
```

## Input Models

Define your input schemas with clear documentation and examples:

```python theme={null}
class BaseInput(BaseModel):
    prompt: str = Field(
        title="Prompt",
        description="The prompt to generate an image from.",
        examples=[
            "Underwater coral reef ecosystem during peak bioluminescent activity, multiple layers of marine life - from microscopic plankton to massive coral structures, light refracting through crystal-clear tropical waters, creating prismatic color gradients, hyper-detailed texture of marine organisms",
        ],
    )
    negative_prompt: str = Field(
        default="",
        description="""
            The negative prompt to use. Use it to address details that you don't want
            in the image. This could be colors, objects, scenery and even the small details
            (e.g. moustache, blurry, low resolution).
        """,
        examples=[""],
    )
    image_size: ImageSizeInput = Field(
        default=ImageSize(width=3840, height=2160),
        description="The size of the generated image.",
    )
    num_inference_steps: int = Field(
        default=18,
        description="The number of inference steps to perform.",
        ge=1,
        le=50,
    )
    seed: int | None = Field(
        default=None,
        description="""
            The same seed and the same prompt given to the same version of the model
            will output the same image every time.
        """,
    )
    guidance_scale: float = Field(
        default=5.0,
        description="""
            The CFG (Classifier Free Guidance) scale is a measure of how close you want
            the model to stick to your prompt when looking for a related image to show you.
        """,
        ge=0.0,
        le=20.0,
        title="Guidance scale (CFG)",
    )
    enable_safety_checker: bool = Field(
        default=True,
        description="If set to true, the safety checker will be enabled.",
    )
    num_images: int = Field(
        default=1,
        description="The number of images to generate.",
        ge=1,
        le=4,
    )
    output_format: Literal["jpeg", "png"] = Field(
        default="jpeg",
        description="The format of the generated image.",
    )

# Endpoint-specific input models
class TextToImageInput(BaseInput):
    pass

class SprintInput(BaseInput):
    # Override settings for the faster endpoint
    num_inference_steps: int = Field(
        default=2,
        description="The number of inference steps to perform.",
        ge=1,
        le=20,
    )
```

## Output Models

Create output models with example data for the playground:

```python theme={null}
class SanaOutput(Output):
    images: list[Image] = Field(
        description="The generated image files info.",
        examples=[
            [
                Image(
                    url="https://fal.media/files/kangaroo/QAABS8yM6X99WhiMeLcoL.jpeg",
                    width=3840,
                    height=2160,
                    content_type="image/jpeg",
                )
            ],
        ],
    )

class SanaSprintOutput(Output):
    images: list[Image] = Field(
        description="The generated image files info.",
        examples=[
            [
                Image(
                    url="https://v3.fal.media/files/penguin/Q-i_zCk-Xf5EggWA9OmG2_e753bacc9b324050855f9664deda3618.jpg",
                    width=3840,
                    height=2160,
                    content_type="image/jpeg",
                )
            ],
        ],
    )
```

## Main Application Class

```python theme={null}
class Sana(fal.App):
    keep_alive = 60  # Keep worker alive for 1 minute
    min_concurrency = 0  # Scale to zero when idle
    max_concurrency = 2  # Limit concurrent requests
    app_name = "sana"  # Endpoint served at username/sana
    requirements = [
        "torch==2.6.0",
        "accelerate==1.6.0",
        "transformers==4.51.3",
        "git+https://github.com/huggingface/diffusers.git@f4fa3beee7f49b80ce7a58f9c8002f43299175c9",
        "hf_transfer==0.1.9",
        "peft==0.15.0",
        "sentencepiece==0.2.0",
        "--extra-index-url",
        "https://download.pytorch.org/whl/cu124",
    ]
    local_python_modules = [
        "fal_demos",
    ]
    machine_type = "GPU-H100"

    def setup(self):
        """Load and cache models for all requests."""
        import torch
        from diffusers import SanaPipeline, SanaSprintPipeline

        self.pipes = {}

        # Load base pipeline
        self.pipes["base"] = SanaPipeline.from_pretrained(
            "Efficient-Large-Model/Sana_1600M_1024px_BF16_diffusers",
            torch_dtype=torch.bfloat16,
        ).to("cuda")
        self.pipes["base"].text_encoder.to(torch.bfloat16)

        # Load sprint pipeline, reusing text encoder for efficiency
        self.pipes["sprint"] = SanaSprintPipeline.from_pretrained(
            "Efficient-Large-Model/Sana_Sprint_1.6B_1024px_diffusers",
            text_encoder=self.pipes["base"].text_encoder,  # Reuse component
            torch_dtype=torch.bfloat16,
        ).to("cuda")
```

## Shared Generation Logic

Create a reusable generation method for both endpoints:

```python theme={null}
    async def _generate(
        self,
        input: TextToImageInput,
        response: Response,
        model_id: str,
    ) -> Output:
        import torch

        # Preprocess input
        image_size = get_image_size(input.image_size)
        seed = input.seed or torch.seed()
        generator = torch.Generator("cuda").manual_seed(seed)

        # Prepare model input
        model_input = {
            "prompt": input.prompt,
            "negative_prompt": input.negative_prompt,
            "num_inference_steps": input.num_inference_steps,
            "guidance_scale": input.guidance_scale,
            "height": image_size.height,
            "width": image_size.width,
            "num_images_per_prompt": input.num_images,
            "generator": generator,
        }

        # Handle model-specific differences
        if model_id == "sprint":
            model_input.pop("negative_prompt")  # Not supported in sprint

        # Generate images
        images = self.pipes[model_id](**model_input).images

        # Apply safety checking
        postprocessed_images = postprocess_images(
            images,
            input.enable_safety_checker,
        )

        # Calculate billing
        resolution_factor = math.ceil(
            (image_size.width * image_size.height) / (1024 * 1024)
        )
        response.headers["x-fal-billable-units"] = str(
            resolution_factor * input.num_images
        )

        return Output(
            images=[
                Image.from_pil(image, input.output_format)
                for image in postprocessed_images["images"]
            ],
            seed=seed,
            has_nsfw_concepts=postprocessed_images["has_nsfw_concepts"],
            prompt=input.prompt,
        )
```

## Endpoint Definitions

Define multiple endpoints using the shared generation logic:

```python theme={null}
    @fal.endpoint("/")
    async def generate(
        self,
        input: TextToImageInput,
        response: Response,
    ) -> SanaOutput:
        return await self._generate(input, response, "base")

    @fal.endpoint("/sprint")
    async def generate_sprint(
        self,
        input: SprintInput,
        response: Response,
    ) -> SanaSprintOutput:
        return await self._generate(input, response, "sprint")
```

## Running the Application

### Development

```bash theme={null}
fal run fal_demos/image/sana.py::Sana
```

### Using pyproject.toml

Add to your `pyproject.toml`:

```toml theme={null}
[tool.fal.apps]
sana = "fal_demos.image.sana:Sana"
```

Then run:

```bash theme={null}
fal run sana
```

## Testing Your Endpoints

Once deployed, your app will be available at URLs like:

* **Base endpoint**: `https://fal.ai/dashboard/sdk/username/app-id`
* **Sprint endpoint**: `https://fal.ai/dashboard/sdk/username/app-id/sprint`

## Best Practices Demonstrated

1. **Resource Sharing**: The text encoder is shared between pipelines to save memory
2. **Input Validation**: Comprehensive Pydantic models with examples and constraints
3. **Error Handling**: Safety checking and proper response formatting
4. **Billing Integration**: Resolution-based pricing
5. **Endpoint Flexibility**: Different configurations for different use cases
6. **Documentation**: Rich field descriptions and examples for auto-generated docs

## Key Takeaways

* Use `setup()` to load models once and cache them
* Share components between models when possible to optimize memory
* Create endpoint-specific input models for different use cases
* Implement proper billing with `x-fal-billable-units`
* Use the fal image toolkit for safety checking and processing
* Pin all dependency versions for reliability

This pattern works well for any multi-model or multi-endpoint image generation service where you want to optimize for both performance and cost efficiency. You can visit [fal\_demos](https://github.com/fal-ai-community/fal_demos/blob/main/fal_demos/image/sana.py) to view the full file and other examples.


# https://fal.ai/docs/examples/image-generation/deploy-wan-lora-training.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy WAN LoRA Training

> Fine-tune WAN (text-to-video) with LoRA using your own short clips and images.

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/blob/main/fal_demos/video/wan_trainer.py).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate (if not already done):

```bash theme={null}
fal auth login
```

3. Clone the demos repo and install dependencies:

```bash theme={null}
git clone https://github.com/fal-ai-community/fal-demos.git
cd fal-demos
pip install -e .
```

4. Run the trainer:

```bash theme={null}
fal run fal_demos/video/wan_trainer.py::WanLoRATrainerDemo
```

<Tip>
  This demo uses a GPU-heavy training stack and can run for a while depending on your step count.
</Tip>

## Deploy to fal

To host the trainer as an API:

```bash theme={null}
fal deploy fal_demos/video/wan_trainer.py::WanLoRATrainerDemo
```

## How it works

* Downloads WAN weights from Hugging Face and a pinned training repo.
* Prepares a dataset from your ZIP file (images and/or short videos).
* Runs LoRA training with DeepSpeed and returns the adapter weights.

## Input format

Your `training_data_url` should point to a ZIP containing:

* Images or videos (`.png`, `.jpg`, `.jpeg`, `.gif`, `.mp4`)
* Optional caption files (`my_clip.txt` next to `my_clip.mp4`)

If you set `auto_scale_input=true`, videos are fit to **81 frames at 16 fps** for WAN training.

## Example request

```python theme={null}
import fal_client

result = fal_client.submit(
    "your-username/wan-lora-trainer-demo",
    arguments={
        "training_data_url": "https://your-bucket/train.zip",
        "rank": 16,
        "number_of_steps": 400,
        "learning_rate": 2e-4,
        "trigger_phrase": "your-style",
        "auto_scale_input": True,
        "video_clip_mode": "single_beginning",
    },
).get()

print(result["lora_file"]["url"])
```


# https://fal.ai/docs/examples/image-generation/fast-flux.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Fastest FLUX Endpoint

> We believe fal has the fastest FLUX endpoint in the planet. If you can find a faster one, we guarantee to beat it within one week. 🤝

<CardGroup>
  <Card title="fal-ai/ flux/schnell" href="https://fal.ai/models/fal-ai/flux/schnell" img="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/image-7.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=63ca3f10d0a6a8ed0b743648881b95a1" width="512" height="384" data-path="images/image-7.png">
    `text-to-image`

    FLUX.1 \[schnell] is a 12 billion parameter flow transformer that generates high-quality images from text in 1 to 4 steps, suitable for personal and commercial use.

    `optimized`
  </Card>

  <Card title="fal-ai/ flux/dev" href="https://fal.ai/models/fal-ai/flux/dev" img="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/image-8.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=77817a3db0b964ce72ac78f06b891404" width="512" height="384" data-path="images/image-8.png">
    `text-to-image`

    FLUX.1 \[dev] is a 12 billion parameter flow transformer that generates high-quality images from text. It is suitable for personal and commercial use.

    `flux`
  </Card>
</CardGroup>

Here is a quick guide on how to use this model from an API in less than 1 minute.

Before we proceed, you need to create an [API key](https://fal.ai/dashboard/keys).

This key secret will be used to authenticate your requests to the fal API.

```js theme={null}
fal.config({
  credentials: "PASTE_YOUR_FAL_KEY_HERE",
});
```

Now you can call our Model API endpoint using the [fal js client](/model-apis/model-endpoints):

```js theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/flux/dev", {
  input: {
    prompt:
      "photo of a rhino dressed suit and tie sitting at a table in a bar with a bar stools, award winning photography, Elke vogelsang",
  },
});
```

<Note>
  **Note:**

  <h4>Image Uploads Should Not Waste GPU Cycles</h4>

  <p>
    We upload the output image in a background thread so we don't charge any GPU
    time for time spent on the GPU that is not directly inference.
  </p>
</Note>


# https://fal.ai/docs/examples/image-generation/fast-sdxl.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Fastest SDXL Endpoint

> We believe fal has the fastest SDXL endpoint in the planet. If you can find a faster one, we guarantee to beat it within one week. 🤝

<CardGroup>
  <Card title="fal-ai/ fast-sdxl" href="https://fal.ai/models/fal-ai/fast-sdxl" img="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/image-9.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=8338fa5c9760a77f4d49345a5d556985" width="1024" height="1024" data-path="images/image-9.png">
    `text-to-image`

    Run SDXL at the speed of light

    `loras` `embeddings`
  </Card>
</CardGroup>

Here is a quick guide on how to use this model from an API in less than 1 minute.

Before we proceed, you need to create an [API key](https://fal.ai/dashboard/keys).

This key secret will be used to authenticate your requests to the fal API.

```js theme={null}
fal.config({
  credentials: "PASTE_YOUR_FAL_KEY_HERE",
});
```

Now you can call our Model API endpoint using the [fal js client](/model-apis/model-endpoints):

```js theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/fast-sdxl", {
  input: {
    prompt:
      "photo of a rhino dressed suit and tie sitting at a table in a bar with a bar stools, award winning photography, Elke vogelsang",
  },
});
```

A typical inference takes 2.3 seconds and will cost \~\$0.0025.

<Note>
  **Image Uploads Should Not Waste GPU Cycles**

  We upload the output image in a background thread so we don't charge any GPU time for time spent on the GPU that is not directly inference.
</Note>


# https://fal.ai/docs/examples/image-generation/generate-images-from-text.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate Images from Text Tutorial

## How to Generate Images using the fal API

To generate images using the fal API, you need to send a request to the appropriate endpoint with the desired input parameters. The API uses pre-trained models to generate images based on the provided text prompt. This allows you to create images by simply describing what you want in natural language.

Here’s an example of how to generate an image using the fal API from text:

```js theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/flux/dev", {
  input: {
    prompt: "a face of a cute puppy, in the style of pixar animation",
  },
});
```

## How to select the model to use

fal offers a variety of image generation models. You can select the model that best fits your needs based on the style and quality of the images you want to generate. Here are some of the available models:

* [fal-ai/flux/dev](https://fal.ai/models/fal-ai/flux/dev): FLUX.1 \[dev] is a 12 billion parameter flow transformer that generates high-quality images from text. It is suitable for personal and commercial use.
* [fal-ai/recraft-v3](https://fal.ai/models/fal-ai/recraft-v3): Recraft V3 is a text-to-image model with the ability to generate long texts, vector art, images in brand style, and much more. As of today, it is SOTA in image generation, proven by Hugging Face’s industry-leading Text-to-Image Benchmark by Artificial Analysis.
* [fal-ai/stable-diffusion-v35-large](https://fal.ai/models/fal-ai/stable-diffusion-v35-large): Stable Diffusion 3.5 Large is a Multimodal Diffusion Transformer (MMDiT) text-to-image model that features improved performance in image quality, typography, complex prompt understanding, and resource-efficiency.

To select a model, simply specify the model ID in the subscribe method as shown in the example above. You can find more models and their descriptions in the [Text to Image Models](https://fal.ai/models?categories=text-to-image) page.


# https://fal.ai/docs/examples/image-generation/run-comfyui-visual.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy ComfyUI on fal — Visual Control

> Edit ComfyUI workflows visually from your laptop with a fal-hosted GPU backend. Two zips, double-click, no code.

Run ComfyUI workflows on fal serverless GPUs while editing them visually from your local machine. Two pre-built packages handle setup so you don't need to write any code:

* **User package** — open the ComfyUI canvas and run workflows on a deployed fal endpoint.
* **Admin package** — add models, custom nodes, and Python deps in a small web UI, then deploy to fal in one click.

Pick the visual editor for prototyping and creative iteration. When you're ready to ship the workflow as an HTTP endpoint, jump to [Deploy a ComfyUI SDXL Turbo App](/examples/image-generation/deploy-comfyui-server) for the production code-first flow.

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/Un5AMpXNKs4_TsjB/images/examples/comfyui-visual-admin.png?fit=max&auto=format&n=Un5AMpXNKs4_TsjB&q=85&s=f1ff2ee1743b99e6711cadf453edfd5c" alt="Admin web UI showing the Models tab — folders, filenames and download URLs in a table" width="2576" height="1470" data-path="images/examples/comfyui-visual-admin.png" />
</Frame>

***

## How it works

```mermaid theme={null}
flowchart LR
    subgraph Local["Your machine"]
        Launcher["Launcher UI<br/>localhost:9998<br/>(or admin UI :9999)"]
        Proxy["ComfyUI proxy<br/>localhost:8188<br/>frontend, uploads,<br/>file storage"]
        Launcher -->|spawns| Proxy
    end
    subgraph Cloud["fal serverless"]
        App["fal.App runner<br/>H100 GPU<br/>your models + nodes"]
    end
    Proxy -->|HTTPS / SSE| App
    style Launcher fill:#ffecd2
    style Proxy fill:#d4f1f4
    style App fill:#e1d7f9
```

The proxy implements ComfyUI's full API locally. Each prompt is streamed to a fal runner — progress, previews, and outputs come back in real time. Nothing about the canvas or upload flow leaves your machine until you queue a prompt.

***

## For users — open the canvas in three steps

<Steps>
  <Step title="Download">
    Get the [user package zip](https://v3b.fal.media/files/b/0a984481/qK6dLV7FWuaEdFa-GfeJ2_fal-comfyui.zip) from your team lead, or directly if they've shared the link with you. Unzip it anywhere.

    The unzipped folder contains a `README.md`, a launcher (`ComfyUI.command` on macOS, `ComfyUI.bat` on Windows), and an `app/` folder with the internals.
  </Step>

  <Step title="Double-click the launcher">
    * **macOS** — right-click `ComfyUI.command` → **Open** → **Open** in the Gatekeeper dialog (only on first launch).
    * **Windows** — double-click `ComfyUI.bat`. If SmartScreen pops up, choose **More info** → **Run anyway**. Requires [Python 3.11](https://www.python.org/downloads/) — check "Add Python to PATH" during install.

    First run installs everything automatically (a tool called `uv`, Python 3.11, the proxy dependencies). Takes 1–3 minutes. Subsequent launches are instant.
  </Step>

  <Step title="Paste your fal API key + endpoint">
    A browser tab opens on `http://localhost:9998`. Enter:

    * **fal API key** — from [fal.ai/dashboard/keys](https://fal.ai/dashboard/keys).
    * **Endpoint** — the slug your admin gave you, in the form `<team>/<app>` (e.g. `acme/comfy`).

    Click **Start ComfyUI**. A second tab opens on `http://localhost:8188` with the full ComfyUI canvas. Build, queue, and iterate as usual — every prompt runs on the fal GPU.
  </Step>
</Steps>

<Note>
  The first prompt of the day takes **5–10 minutes** to warm up — the runner downloads model weights and installs custom nodes. After that, prompts run in seconds while the runner stays warm. "Reconnecting" toasts that occasionally flash in ComfyUI are cosmetic.
</Note>

***

## For admins — configure and deploy

Team leads use the admin package to control which models, custom nodes, and Python packages live in the deployed runtime.

<Steps>
  <Step title="Download the admin package">
    Get the [admin package zip](https://v3b.fal.media/files/b/0a984481/gOJXw81mtatswV1BdCt3O_fal-comfyui-admin.zip) and unzip. Double-click `admin-ui.command` (macOS) or `admin-ui.bat` (Windows). The browser opens on `http://localhost:9999`.
  </Step>

  <Step title="Settings — credentials and tokens">
    Open the **Settings** tab and fill in:

    * **fal API key** — generate at [fal.ai/dashboard/keys](https://fal.ai/dashboard/keys) **after switching to the right team** in the dashboard. The team is encoded in the key, so creating it on the wrong team deploys to the wrong place.
    * **App name** — the slug for your deployment (e.g. `comfy`).
    * **HuggingFace token** *(optional)* — needed for gated models such as Flux 2 Klein. Saved to `.env` and pushed to fal as a runner secret automatically at deploy time.
    * **Civitai token** *(optional)* — same idea, for Civitai-hosted weights.

    The top-right header shows **Deploying as `<team>`** so you can verify the key targets the right account before pushing anything.
  </Step>

  <Step title="Edit Models, Custom Nodes, Python Deps">
    Three tabs in the admin UI mirror the structure of the deployed runtime:

    * **Models** — folder + filename + download URL. Sub-folders are supported (`klein/my-lora.safetensors` saves into `loras/klein/`).
    * **Custom Nodes** — paste a GitHub URL and pin a commit. The UI fetches the repo's `requirements.txt` so you can confirm extra Python deps before saving.
    * **Python Deps** — direct editor over `comfy_server/requirements.txt`.

    Add a fal-trained LoRA the same way: paste its `.safetensors` URL (e.g. `https://v3b.fal.media/...`) and set folder to `loras`.
  </Step>

  <Step title="Click Deploy">
    The **Deploy** button in the top bar runs `fal deploy` end-to-end and streams logs to the bottom drawer. Wait for `[DEPLOY SUCCESSFUL]`.

    Share the resulting `<team>/<app>` slug with your users along with the user zip from the section above.
  </Step>
</Steps>

### What the admin UI gives you on top of `fal deploy`

* **Live runner view** — chip in the header lists current GPU runners for your app, with one-click log streaming and termination. Pulsing green dot when at least one runner is `RUNNING`.
* **Outputs gallery** — every image and video produced by the proxy, with per-file download and a "Download all" zip. Filenames are auto-disambiguated when multiple workflows produce the same base name (`video.mp4` → `video_2.mp4` → …).
* **Run ComfyUI** — starts the bundled local proxy and opens the canvas pointing at your deployed app. The button shows the live runner state (`cold-starting`, `idle · ready`, `processing`).
* **Theme + ComfyUI commit pin** — dark/light toggle, plus a clickable chip to pin a specific upstream ComfyUI commit (validated against `comfyanonymous/ComfyUI`).
* **Undeploy** — confirmation-gated button under Settings → Danger zone if you ever want to retire an app.

***

## Multi-user concurrency

Each user runs the proxy locally, so there's no cross-machine state to worry about. fal itself routes incoming prompts to whichever runner is free, capped by your app's `max_concurrency`. Tune it once via the CLI:

```bash theme={null}
fal apps scale <app> --min-concurrency 1 --max-concurrency 5 --max-multiplexing 1
```

| Setting                | Effect                                                                |
| ---------------------- | --------------------------------------------------------------------- |
| `max_concurrency = 1`  | Only one runner ever — second user's prompt queues. Cheapest.         |
| `max_concurrency = N`  | Up to N runners in parallel. Each cold-starts the first time.         |
| `min_concurrency = 1`  | Keep one runner always warm — no cold-start for the first user.       |
| `max_multiplexing = 1` | One prompt per runner at a time. Recommended for GPU-heavy workflows. |

***

## When to use this vs. the SDXL deploy guide

| Scenario                                                  | Use this page | Use [Deploy SDXL Turbo](/examples/image-generation/deploy-comfyui-server) |
| --------------------------------------------------------- | ------------- | ------------------------------------------------------------------------- |
| Iterating on a workflow visually                          | ✅             |                                                                           |
| Sharing a creative tool with a non-technical team         | ✅             |                                                                           |
| Wrapping a fixed workflow as a REST API for production    |               | ✅                                                                         |
| Custom request/response schemas (Pydantic)                |               | ✅                                                                         |
| Fine control over `fal.App` lifecycle, secrets, multi-GPU |               | ✅                                                                         |

The visual editor is the right starting point. When the workflow is locked and you need a cleanly typed endpoint, the SDXL Turbo guide shows the code-first flow.

***

## Troubleshooting

| Issue                                                     | Fix                                                                                                                                                                  |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| macOS: "can't be opened, unidentified developer"          | Right-click `.command` → **Open** → **Open**.                                                                                                                        |
| Windows: SmartScreen blocks the `.bat`                    | **More info** → **Run anyway**.                                                                                                                                      |
| Launcher fails to install `uv`                            | Install it manually: `curl -LsSf https://astral.sh/uv/install.sh \| sh` (macOS) or `irm https://astral.sh/uv/install.ps1 \| iex` in PowerShell (Windows). Re-launch. |
| Deploy fails with `401 Unauthorized` on a HuggingFace URL | The model is gated. Set the **HuggingFace token** in admin Settings and re-deploy — the admin UI pushes it to fal secrets automatically.                             |
| Runner stuck in `SETUP` for several minutes               | Normal on first cold start while weights download (5–10 min).                                                                                                        |
| Two runners spawn for one user                            | Lower `max_concurrency`: `fal apps scale <app> --max-concurrency 1`.                                                                                                 |
| Port already in use on `:9999`, `:9998`, or `:8188`       | The launcher auto-kills stale instances on next start. If something else is binding the port, close it before relaunching.                                           |
| Stop everything                                           | Close the launcher terminal window. The proxy and admin UI shut down with it.                                                                                        |

***

## Uninstall

Delete the unzipped folder. Everything is self-contained — local Python venv, models cache, env file, logs. Nothing is installed globally.


# https://fal.ai/docs/examples/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Examples

> Step-by-step tutorials and code examples for building with fal

export const ExampleCard = ({title, description, image, href, dateAdded}) => {
  let isNew = false;
  if (dateAdded) {
    const added = new Date(dateAdded);
    const now = new Date();
    const diffTime = Math.abs(now - added);
    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
    isNew = diffDays <= 30;
  }
  return <a href={href} className="group block no-underline" style={{
    border: 'none',
    outline: 'none'
  }}>
      <div className="relative rounded-2xl overflow-hidden transition-all duration-500 ease-out group-hover:scale-[1.03]" style={{
    height: '340px',
    backgroundImage: `url(${image})`,
    backgroundSize: 'cover',
    backgroundPosition: 'center',
    border: 'none',
    boxShadow: '0 4px 20px rgba(0,0,0,0.15)'
  }}>
        <div className="absolute inset-0" style={{
    background: 'linear-gradient(to bottom, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0.25) 50%, rgba(0,0,0,0.5) 100%)'
  }} />
        
        {isNew && <div className="absolute top-4 right-4 z-10 px-3 py-1.5 rounded-full text-xs font-bold uppercase tracking-wider" style={{
    background: 'linear-gradient(135deg, #8553ff 0%, #6366f1 100%)',
    color: 'white',
    fontFamily: 'Public Sans',
    fontSize: '10px',
    letterSpacing: '1px',
    boxShadow: '0 2px 10px rgba(133, 83, 255, 0.4)'
  }}>
            New
          </div>}
        
        <div className="absolute inset-0 transition-all duration-500 group-hover:opacity-90" style={{
    background: 'linear-gradient(to top, rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.6) 35%, transparent 60%)'
  }} />
        
        <div className="absolute bottom-0 left-0 right-0 p-5 transition-all duration-300">
          <h4 className="text-white mb-2 transition-transform duration-300 group-hover:translate-y-[-2px]" style={{
    fontFamily: 'Focal',
    fontSize: '24px',
    fontWeight: 500,
    lineHeight: 1,
    letterSpacing: '-0.48px'
  }}>
            {title}
          </h4>
          <p className="text-white transition-all duration-300 group-hover:translate-y-[-2px]" style={{
    fontFamily: 'Public Sans',
    fontSize: '14px',
    fontWeight: 500,
    lineHeight: 1.5,
    letterSpacing: '-0.28px'
  }}>
            {description}
          </p>
        </div>
      </div>
    </a>;
};

export const MODEL_API_EXAMPLES = [{
  title: "Generate Images from Text",
  description: "Create stunning images using text prompts with FLUX and other models.",
  image: "https://v3b.fal.media/files/b/rabbit/EuI3qlj6YuU0RdL8frhFz_b3f41c0a0a204cedb65fdd422b42f4d5.jpg",
  href: "/examples/image-generation/generate-images-from-text",
  dateAdded: null
}, {
  title: "Generate Videos from Images",
  description: "Transform static images into dynamic videos with AI-powered animation.",
  image: "https://v3b.fal.media/files/b/kangaroo/ytEAu0n1-fdVCtHgm7I9a_89ee87948a774d219c29351b1e4fd4da.jpg",
  href: "/examples/video-generation/generate-videos-from-image",
  dateAdded: null
}, {
  title: "Convert Speech to Text",
  description: "Transcribe audio files with high accuracy using Whisper.",
  image: "https://v3b.fal.media/files/b/zebra/RG5Bvv69wgJv-gbWAliYW_45ae8d4adc8b4b5e926b3c2c28a127d4.jpg",
  href: "/examples/audio-speech/convert-speech-to-text",
  dateAdded: null
}, {
  title: "Use Large Language Models",
  description: "Build powerful AI applications with Llama, Mistral, and other LLMs.",
  image: "https://v3b.fal.media/files/b/zebra/pjq9D101BZainhOpBpdIa_04328ca3afde43e0809d8f471fb52062.jpg",
  href: "/examples/integrations/use-llms",
  dateAdded: null
}, {
  title: "Fast FLUX",
  description: "Ultra-fast image generation with optimized FLUX.",
  image: "/images/image-5.png",
  href: "/examples/image-generation/fast-flux",
  dateAdded: null
}, {
  title: "Fast SDXL",
  description: "High-speed Stable Diffusion XL inference.",
  image: "/images/image-9.png",
  href: "/examples/image-generation/fast-sdxl",
  dateAdded: null
}, {
  title: "Build Custom Workflow UI",
  description: "Create intuitive user interfaces for complex AI workflows.",
  image: "https://v3b.fal.media/files/b/kangaroo/4nMIYfcKpQOoN5Xkxx8Xj_aada02b4749f41839f2f96fc6789ccea.jpg",
  href: "/examples/integrations/custom-workflow-ui",
  dateAdded: null
}, {
  title: "Integrate with n8n",
  description: "Automate workflows by integrating fal AI models with n8n.",
  image: "https://v3b.fal.media/files/b/penguin/nB7rGViPfVhhjB4G2jPJp_73c97f13d0364bc9b912d316c1bb6d07.jpg",
  href: "/examples/integrations/n8n",
  dateAdded: null
}, {
  title: "Next.js Integration",
  description: "Build full-stack AI apps with Next.js and fal.",
  image: "/images/image-8.png",
  href: "/examples/integrations/nextjs",
  dateAdded: null
}, {
  title: "Vercel Integration",
  description: "Deploy AI-powered apps on Vercel with fal.",
  image: "/images/image-7.png",
  href: "/examples/integrations/vercel",
  dateAdded: null
}];

export const SERVERLESS_EXAMPLES = [{
  title: "Deploy Text-to-Image Model",
  description: "Build and deploy your own text-to-image API using Sana or FLUX.",
  image: "https://v3b.fal.media/files/b/zebra/LKfy5G6ZTgDi5kqSK7G6v_16dc6c79476d4d858d8f22b2d77d374f.jpg",
  href: "/examples/image-generation/deploy-text-to-image-model",
  dateAdded: null
}, {
  title: "Deploy Text-to-Video Model",
  description: "Create a production-ready video generation API with WAN.",
  image: "https://v3b.fal.media/files/b/elephant/fVvQzNYZ9vtG3SwxJPhWs_85d586a94ba34c278427459e3f598f05.jpg",
  href: "/examples/video-generation/deploy-text-to-video-model",
  dateAdded: null
}, {
  title: "Deploy WAN LoRA Training",
  description: "Fine-tune WAN video generation with LoRA training.",
  image: "/images/image-6.png",
  href: "/examples/image-generation/deploy-wan-lora-training",
  dateAdded: null
}, {
  title: "Deploy a ComfyUI Server",
  description: "Run ComfyUI with SDXL Turbo as a serverless API.",
  image: "https://v3b.fal.media/files/b/0a876c07/ahOa0bd2Z1_HQFfOl_Uy9_04d7d98840f74acd91ae4628ddd42d9d.jpg",
  href: "/examples/image-generation/deploy-comfyui-server",
  dateAdded: null
}, {
  title: "Deploy Multi-GPU Inference",
  description: "Scale image generation across multiple GPUs with streaming.",
  image: "https://v3b.fal.media/files/b/koala/sxlKoYjz5-pUSPg2KvP4U_5a478c7423a048f89c4c5e90c287b96f.jpg",
  href: "/examples/video-generation/deploy-multi-gpu-inference",
  dateAdded: null
}, {
  title: "Deploy Text-to-Speech Model",
  description: "Build natural-sounding voice synthesis APIs with Kokoro.",
  image: "https://v3b.fal.media/files/b/rabbit/-YOK-ncB-zw8iZu0lGhKx_537ff78d861c44acb7f584623480f464.jpg",
  href: "/examples/audio-speech/deploy-text-to-speech-model",
  dateAdded: null
}, {
  title: "Deploy Text-to-Music Model",
  description: "Generate original music from text descriptions using DiffRhythm.",
  image: "https://v3b.fal.media/files/b/tiger/kBuwc7RF4jOPMisP24Rg0_1684aba74ec14c81a9544e33102c3ec8.jpg",
  href: "/examples/audio-speech/deploy-text-to-music-model",
  dateAdded: null
}, {
  title: "Publish Custom Metrics with Prometheus Pushgateway",
  description: "Publish custom metrics on fal and expose them for scraping.",
  image: "/images/image-1.png",
  href: "/examples/serverless/deploy-prometheus-pushgateway",
  dateAdded: "2026-04-16"
}, {
  title: "Deploy 3D Progressive Rendering",
  description: "Stream real-time text-to-3D reconstruction with live voxel visualization.",
  image: "https://v3b.fal.media/files/b/0a8935fe/Ezbvf27opeW6gEoDS4nlw_da7064399f9c4342b5e118f6875ec389.jpg",
  href: "/examples/video-generation/deploy-3d-progressive-rendering",
  dateAdded: null
}, {
  title: "Deploy Real-time Video-to-Video",
  description: "Run real-time video-to-video with YOLO object detection.",
  image: "https://v3b.fal.media/files/b/0a8d2007/gV_LMXNrguqRaDB9sLqir_b5d36b36de5a40bdb5cb2cd3f8af29d7.jpg",
  href: "/examples/video-generation/deploy-realtime-video-to-video-model",
  dateAdded: null
}, {
  title: "Deploy Real-time World Model",
  description: "Run a real-time world model demo powered by Matrix-Game.",
  image: "https://v3b.fal.media/files/b/tiger/IwzOGSbzp6e8N00QuLtFF_129417bb24f248298e95c3fa2b1b82fb.jpg",
  href: "/examples/video-generation/deploy-realtime-world-model",
  dateAdded: null
}, {
  title: "Deploy with Custom Containers",
  description: "Use custom Docker containers for complex dependencies.",
  image: "https://v3b.fal.media/files/b/zebra/L5WtylOCEW3cb28FVzVH0_49db14e3031b41b9838a267cf8214ef8.jpg",
  href: "/examples/deploy-models-with-custom-containers",
  dateAdded: null
}, {
  title: "Migrate from Replicate",
  description: "Move your models from Replicate to fal.",
  image: "https://v3b.fal.media/files/b/kangaroo/WcNt4yo_7RJaCZa0Og6gE_37660458463d4008959517c59a40aafd.jpg",
  href: "/examples/integrations/migrate-from-replicate",
  dateAdded: null
}, {
  title: "Migrate External Docker Server",
  description: "Migrate your existing Docker-based inference server to fal.",
  image: "https://v3b.fal.media/files/b/panda/LqyVE8NElm_vf-t27Yfkz_6c1dd3323df343e4a3ec968d8f67024c.jpg",
  href: "/examples/integrations/migrate-external-docker-server",
  dateAdded: null
}, {
  title: "Migrate from Modal",
  description: "Move your Modal applications to fal.",
  image: "https://v3b.fal.media/files/b/0a900b9e/ptbZcVWIQ_fXGGHfv8Zez_0ea5ca41bdf143a29e21e30a53120672.jpg",
  href: "/examples/integrations/migrate-from-modal",
  dateAdded: null
}, {
  title: "Migrate from RunPod",
  description: "Move your RunPod Serverless workers to fal.",
  image: "https://v3b.fal.media/files/b/0a8cfd08/Ji4e0i6Afbeql3Wr5UTz6_ab60b14661424612bf19059e97e996a5.jpg",
  href: "/examples/integrations/migrate-from-runpod",
  dateAdded: null
}];

## Using Models

Call fal's ready-to-use models from your application.

<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mt-6 mb-12">
  {MODEL_API_EXAMPLES.map((example, index) => (
      <ExampleCard key={index} {...example} />
    ))}
</div>

<div id="deploying-models" />

## Deploying Models

Deploy your own custom models on fal's serverless infrastructure.

<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mt-6">
  {SERVERLESS_EXAMPLES.map((example, index) => (
      <ExampleCard key={index} {...example} />
    ))}
</div>


# https://fal.ai/docs/examples/integrations/custom-workflow-ui.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Workflow UI Tutorial

## How to create a custom workflow UI

If you want to create your custom workflow and execute it using the fal API, you need to create a json object that describes the workflow. You can use the following template to create your custom workflow. Basically, a workflow definition must have an input node, a fal model node, and an output node. The input node is the request to the fal API. The fal model node is the model that you want to use. You can add as many fal model nodes as you want. The output node is the response from the fal API.

```json theme={null}
{
  // Input node / Request
  "input": {
    "id": "input",
    "type": "input",
    "depends": [],
    "input": {
      "prompt": ""
    }
  },

  // A fal model node
  "node_1": {
    "id": "node_1",
    "type": "run",
    "depends": ["input"],
    // The app is the model endpoint id
    "app": "fal-ai/flux/dev",
    "input": {
      // The prompt value is coming from the Input node
      "prompt": "$input.prompt"
    }
  },

  // Another fal model node
  "node_2": {
    "id": "node_2",
    "type": "run",
    "depends": ["node_1"],
    // The app is the model endpoint id
    "app": "fal-ai/bria/background/remove",
    "input": {
      // The image_url value is coming from the "node_1" node
      "image_url": "$node_1.images.0.url"
    }
  },

  // Output node / Response
  "output": {
    "id": "output",
    "type": "display",
    "depends": ["node_2"],
    "fields": {
      "image": "$node_2.image"
    }
  }
}
```

## How to find model input and output fields

Every fal model has input and output fields. You can find the input and output fields using the following URL:

```bash theme={null}
https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=[endpoint_id]
```

For example:

```bash theme={null}
https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=fal-ai/flux/dev
```

## How to execute a custom workflow

You can execute a custom workflow using `workflows/execute` endpoint.

```js theme={null}
const stream = await fal.stream(`workflows/execute`, {
    input: {
        // The input to the workflow
        input: {
            prompt: "A beautiful sunset over a calm ocean"
        },
        // The workflow definition
        workflow: {
          "input": {
            "id": "input",
            "type": "input",
            "depends": [],
            "input": {
              "prompt": ""
            }
          },
          "node_1": {
            "id": "node_1",
            "type": "run",
            "depends": ["input"],
            "app": "fal-ai/flux/dev",
            "input": {
              "prompt": "$input.prompt"
            }
          },
          "node_2": {
            "id": "node_2",
            "type": "run",
            "depends": ["node_1"],
            "app": "fal-ai/bria/background/remove",
            "input": {
              "image_url": "$node_1.images.0.url"
            }
          },
          "output": {
            "id": "output",
            "type": "display",
            "depends": ["node_2"],
            "fields": {
              "image": "$node_2.image"
            }
          }
        },
    },
});

stream.on("data", (event) => {
  console.log(event);
});

const result = await stream.done();
```


# https://fal.ai/docs/examples/integrations/migrate-external-docker-server.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate an External Docker Server

> Deploy an existing Docker-based server (ComfyUI, custom APIs) to fal's serverless platform.

This guide shows how to migrate an existing Docker container that runs a server to fal. There are two approaches:

* **Direct Server Mode**: Expose your server's port directly
* **Proxy App Mode**: Wrap your server with a custom API layer

## Option 1: Direct Server Mode

Use `exposed_port` to route requests directly to your container's port. The port can be any valid port number — just ensure it matches the port your server listens on.

```mermaid theme={null}
flowchart LR
    Client --> Gateway[fal Gateway]
    Gateway --> Container[Your Container]
    Container --> Server[Server :exposed_port]
```

```python theme={null}
import subprocess
import fal
from fal.container import ContainerImage

DOCKERFILE = """
FROM your-base-image
# ... your setup
"""

@fal.function(
    image=ContainerImage.from_dockerfile_str(DOCKERFILE),
    machine_type="GPU-A100",
    exposed_port=8000,  # Must match your server's port
    keep_alive=300,
)
def run_server():
    subprocess.run(
        ["your-server", "--host", "0.0.0.0", "--port", "8000"],
        check=True,
    )
```

Your server's API is exposed as-is. Requests go directly to `exposed_port`.

<Warning>
  To unlock the full fal dashboard experience—including the playground, analytics, and error tracking—your server must expose an `/openapi.json` endpoint that returns your OpenAPI specification. Without this endpoint, these features will not be available for your deployment.
</Warning>

***

## Option 2: Proxy App Mode

Use `fal.App` to wrap your server with custom endpoints.

```mermaid theme={null}
flowchart LR
    Client --> Gateway[fal Gateway]
    Gateway --> App[fal.App]
    App <--> Server[Internal Server]
    App --> CDN[fal CDN]
```

```python theme={null}
import subprocess
import time
import fal
import requests
from fal.container import ContainerImage
from fal.toolkit import Image
from fastapi import Request
from pydantic import BaseModel, Field

DOCKERFILE = """
FROM your-base-image
# ... your setup
"""

SERVER_PORT = 8000

class GenerateRequest(BaseModel):
    prompt: str = Field(description="Text prompt")
    
class GenerateResponse(BaseModel):
    image: Image


class MyServerProxy(fal.App, keep_alive=300, max_concurrency=1):
    machine_type = "GPU-A100"
    image = ContainerImage.from_dockerfile_str(DOCKERFILE)
    
    def setup(self):
        # Start server in background (non-blocking)
        self.process = subprocess.Popen(
            ["your-server", "--host", "127.0.0.1", "--port", str(SERVER_PORT)],
        )
        self._wait_for_server()
    
    def _wait_for_server(self, timeout=120):
        start = time.time()
        while time.time() - start < timeout:
            try:
                if requests.get(f"http://127.0.0.1:{SERVER_PORT}/", timeout=5).ok:
                    return
            except requests.ConnectionError:
                pass
            time.sleep(1)
        raise TimeoutError("Server did not start")
    
    @fal.endpoint("/generate")
    def generate(self, input: GenerateRequest, request: Request) -> GenerateResponse:
        # Call internal server
        resp = requests.post(
            f"http://127.0.0.1:{SERVER_PORT}/api/generate",
            json={"prompt": input.prompt},
            timeout=300,
        )
        resp.raise_for_status()
        
        # Upload to fal CDN
        image = Image.from_path(resp.json()["path"], request=request)
        return GenerateResponse(image=image)
```

Your `fal.App` controls the API. You can validate inputs, process outputs, and upload to CDN.

## Using an External Registry?

If your image is already hosted on an external registry (Docker Hub, Google Artifact Registry, Amazon ECR), you can pull it directly instead of building from a Dockerfile. See [Using Private Docker Registries](/serverless/development/use-custom-container-image#using-private-docker-registries) for setup instructions.

## Best Practices

1. **Use `/data` for model weights**: Download to persistent storage in `setup()`, not baked into Docker.

2. **Install fal packages last**: Add `boto3`, `protobuf`, `pydantic` at the end of Dockerfile to avoid conflicts.

3. **Set `keep_alive`**: Avoid cold starts between requests.

## Next Steps

* [Deploy a ComfyUI SDXL Turbo App](/serverless/tutorials/deploy-comfyui-server) - Complete tutorial
* [Use Custom Container Images](/serverless/development/use-custom-container-image) - Dockerfile patterns
* [Use Persistent Storage](/serverless/development/use-persistent-storage) - The `/data` directory


# https://fal.ai/docs/examples/integrations/migrate-from-modal.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Modal

> A guide for migrating your Modal applications to fal.

This guide maps Modal concepts to their fal equivalents and shows how to convert your code.

## Concept Mapping

| Modal                                        | fal                                   | Notes                                   |
| -------------------------------------------- | ------------------------------------- | --------------------------------------- |
| `@app.function()`                            | `@fal.function()`                     | Standalone serverless functions         |
| `@app.cls()`                                 | `class MyApp(fal.App)`                | Class-based apps (recommended)          |
| `@modal.method()`                            | `@fal.endpoint("/")`                  | fal uses HTTP endpoints, not RPC        |
| `@modal.enter()`                             | `def setup(self)`                     | Container startup hook                  |
| `@modal.exit()`                              | `def teardown(self)`                  | Container shutdown hook                 |
| `modal.Image.debian_slim().pip_install(...)` | `requirements = [...]`                | Or use `ContainerImage` for Dockerfiles |
| `modal.Image.from_dockerfile(...)`           | `ContainerImage.from_dockerfile(...)` | Custom container support                |
| `gpu="A100"`                                 | `machine_type = "GPU-A100"`           | GPU selection                           |
| `modal.Volume`                               | `/data` persistent storage            | Mounted automatically on all runners    |
| `modal.Secret`                               | `fal secrets set`                     | Secrets exposed as env vars             |
| `modal deploy`                               | `fal deploy`                          | CLI deployment                          |
| `Cls().method.remote(x=123)`                 | `fal_client.subscribe(...)`           | fal uses HTTP + queue, not RPC          |

***

## Migration Path 1: Standalone Functions

If you use `@app.function()` in Modal, the closest fal equivalent is `@fal.function()`.

<Tabs>
  <Tab title="Modal">
    ```python theme={null}
    import modal

    app = modal.App()
    image = modal.Image.debian_slim().pip_install("torch", "transformers")

    @app.function(image=image, gpu="A100")
    def generate(prompt: str):
        from transformers import pipeline
        pipe = pipeline("text-generation", model="gpt2", device="cuda")
        return pipe(prompt)[0]["generated_text"]

    @app.local_entrypoint()
    def main():
        result = generate.remote(prompt="Hello world")
        print(result)
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal

    @fal.function(
        requirements=["torch", "transformers"],
        machine_type="GPU-A100",
    )
    def generate(prompt: str):
        from transformers import pipeline
        pipe = pipeline("text-generation", model="gpt2", device="cuda")
        return pipe(prompt)[0]["generated_text"]
    ```
  </Tab>
</Tabs>

***

## Migration Path 2: Class-Based Apps (Recommended)

If you use `@app.cls()` with `@modal.enter()` and `@modal.method()`, convert to a `fal.App` class.

<Tabs>
  <Tab title="Modal">
    ```python theme={null}
    import modal

    app = modal.App()
    image = (
        modal.Image.debian_slim()
        .pip_install("torch", "diffusers", "transformers", "accelerate")
    )

    @app.cls(image=image, gpu="A100")
    class TextToImage:
        @modal.enter()
        def load_model(self):
            import torch
            from diffusers import StableDiffusionXLPipeline

            self.pipe = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        @modal.method()
        def generate(self, prompt: str):
            image = self.pipe(prompt).images[0]
            return image

        @modal.exit()
        def cleanup(self):
            del self.pipe

    @app.local_entrypoint()
    def main():
        result = TextToImage().generate.remote(prompt="a sunset")
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal
    from fal.toolkit import Image

    class TextToImage(fal.App):
        machine_type = "GPU-A100"
        requirements = ["torch", "diffusers", "transformers", "accelerate"]

        def setup(self):
            import torch
            from diffusers import StableDiffusionXLPipeline

            self.pipe = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        @fal.endpoint("/")
        def generate(self, prompt: str) -> dict:
            image = self.pipe(prompt).images[0]
            return {"image": Image.from_pil(image)}

        def teardown(self):
            del self.pipe
    ```
  </Tab>
</Tabs>

### Deploying

```bash theme={null}
# Modal
modal deploy my_app.py

# fal
fal deploy my_app.py::TextToImage
```

### Calling Your App

```python theme={null}
# Modal
TextToImage().generate.remote(prompt="a sunset")

# fal
import fal_client
result = fal_client.subscribe("your-username/text-to-image", arguments={
    "prompt": "a sunset"
})
```

***

## Key Differences

### HTTP Endpoints vs RPC

Modal uses `.remote()` to invoke functions -- a Python-to-Python RPC call. fal uses **HTTP endpoints** that any language or tool can call. Your fal App exposes a REST API automatically.

This means:

* No `.remote()` calls -- clients use `fal_client.subscribe()` or raw HTTP
* Your endpoints accept and return JSON (use Pydantic models for validation)
* The same endpoint works from Python, JavaScript, cURL, or any HTTP client

### Queue-Based by Default

fal provides a persistent queue that handles retries, scaling, and load balancing automatically. When callers use `subscribe` or `submit`, requests go through this queue by default. Direct calls via `run` bypass the queue for lower overhead.

### Container Images

Modal chains image methods (`Image.debian_slim().pip_install(...).apt_install(...)`). fal offers two approaches:

* **`requirements` list** (simpler): Just list your pip packages
* **`ContainerImage`** (full control): Bring your own Dockerfile

```python theme={null}
# Modal
image = (
    modal.Image.debian_slim()
    .apt_install("ffmpeg")
    .pip_install("torch", "diffusers")
)

# fal (simple)
class MyApp(fal.App):
    requirements = ["torch", "diffusers"]

# fal (Dockerfile)
from fal.container import ContainerImage

class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        FROM python:3.11
        RUN apt-get update && apt-get install -y ffmpeg
        RUN pip install torch diffusers
    """)
```

### Volumes and Storage

Modal uses named `Volume` objects mounted at specific paths. fal provides `/data` -- a persistent filesystem automatically mounted on every runner, shared across all your apps.

```python theme={null}
# Modal
volume = modal.Volume.from_name("model-cache")

@app.cls(volumes={"/cache": volume})
class MyModel:
    ...

# fal -- /data is always available, no configuration needed
class MyModel(fal.App):
    def setup(self):
        model_path = "/data/models/my-model.pt"
        if os.path.exists(model_path):
            self.model = torch.load(model_path)
```

### Secrets

Modal uses `modal.Secret.from_name(...)` and attaches secrets to functions. fal exposes secrets as environment variables:

```bash theme={null}
# Modal
modal secret create my-secret HF_TOKEN=hf_xxx

# fal
fal secrets set HF_TOKEN=hf_xxx
```

Both make secrets available via `os.environ["HF_TOKEN"]` in your code.

<CardGroup cols={2}>
  <Card title="Getting Started" icon="arrow-right" href="/documentation/development/getting-started/quick-start">
    Deploy your first fal app
  </Card>

  <Card title="App Lifecycle" icon="arrow-right" href="/documentation/development/app-lifecycle">
    Learn about runners, scaling, and the fal architecture
  </Card>
</CardGroup>


# https://fal.ai/docs/examples/integrations/migrate-from-replicate.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Replicate

> This guide will help you transition from using [Replicate](https://replicate.com/)'s tools, specifically their [Cog](https://github.com/replicate/cog) tool, to fal's platform. Cog is a tool used to package machine learning models in Docker containers, which simplifies the deployment process.

## Step 1: Generate the Dockerfile with Cog

First, ensure you have Cog installed. If not, follow the instructions on the [Cog GitHub page](https://github.com/replicate/cog).

Navigate to your project directory and run:

```bash theme={null}
cog debug > Dockerfile
```

This command will generate a `Dockerfile` in the root of your project.

## Step 2: Adapt the Dockerfile for fal

With your `Dockerfile` generated, you might need to make a few modifications to ensure compatibility with fal.

First, we need to extract Python dependencies and install them in the Docker image. We can do this by copying the dependencies from the Cog file to the Docker image. Here's an example of how you can do this:

<Warning>
  **Requirements**

  The following command assumes you have `yq` installed. If not, you can install it using `pip install yq`.
  Or follow the instructions on the [yq GitHub page](https://github.com/mikefarah/yq).

  You might also need to install `jq` if you don't have it installed. e.g. You can install it using `sudo apt-get install jq` if you are using a Debian-based system. Alternatively, check out the [jq GitHub page](https://github.com/jqlang/jq).
</Warning>

```bash theme={null}
yq -e '.build.python_packages | map(select(. != null and . != "")) | map("'"'"'" + . + "'"'"'") | join(" ")' cog.yaml
```

This will give you a list of Python packages that you can install in your Docker image. Using `RUN pip install ...` in your Dockerfile.

<Info>
  **e.g.**

  'torch' 'torchvision' 'torchaudio' 'torchsde' 'einops' 'transformers>=4.25.1' ...
</Info>

Alternatively, you can write the contents of the `python_packages` to a `requirements.txt` file and install them in the Dockerfile. See the example in [the containerized application page](/serverless/development/use-custom-container-image).

Here's a basic example of what your `Dockerfile` might look like:

<Info>
  The example Cog project is [https://github.com/fofr/cog-comfyui](https://github.com/fofr/cog-comfyui).
</Info>

```bash theme={null}
FROM python:3.10.6 as deps
COPY .cog/tmp/build4143857248/cog-0.0.1.dev-py3-none-any.whl /tmp/cog-0.0.1.dev-py3-none-any.whl  # [!code --]
RUN --mount=type=cache,target=/root/.cache/pip pip install -t /dep /tmp/cog-0.0.1.dev-py3-none-any.whl # [!code --]
COPY .cog/tmp/build4143857248/requirements.txt /tmp/requirements.txt # [!code --]
RUN --mount=type=cache,target=/root/.cache/pip pip install -t /dep -r /tmp/requirements.txt # [!code --]
RUN --mount=type=cache,target=/root/.cache/pip pip install -t /dep 'torch' 'torchvision' 'torchaudio' 'torchsde' 'einops' 'transformers>=4.25.1' 'safetensors>=0.3.0' 'aiohttp' 'accelerate' 'pyyaml' 'Pillow' 'scipy' 'tqdm' 'psutil' 'spandrel' 'kornia>=0.7.1' 'websocket-client==1.6.3' 'diffusers>=0.25.0' 'albumentations==1.4.3' 'cmake' 'imageio' 'joblib' 'matplotlib' 'pilgram' 'scikit-learn' 'rembg' 'numba' 'pandas' 'numexpr' 'insightface' 'onnx' 'segment-anything' 'piexif' 'ultralytics!=8.0.177' 'timm' 'importlib_metadata' 'opencv-python-headless>=4.0.1.24' 'filelock' 'numpy' 'einops' 'pyyaml' 'scikit-image' 'python-dateutil' 'mediapipe' 'svglib' 'fvcore' 'yapf' 'omegaconf' 'ftfy' 'addict' 'yacs' 'trimesh[easy]' 'librosa' 'color-matcher' 'facexlib' # [!code ++]
FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04
ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu:/usr/local/nvidia/lib64:/usr/local/nvidia/bin
ENV NVIDIA_DRIVER_CAPABILITIES=all
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked set -eux; \
apt-get update -qq && \
apt-get install -qqy --no-install-recommends curl; \
rm -rf /var/lib/apt/lists/*; \
TINI_VERSION=v0.19.0; \
TINI_ARCH="$(dpkg --print-architecture)"; \
curl -sSL -o /sbin/tini "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TINI_ARCH}"; \
chmod +x /sbin/tini
ENTRYPOINT ["/sbin/tini", "--"]
ENV PATH="/root/.pyenv/shims:/root/.pyenv/bin:$PATH"
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked apt-get update -qq && apt-get install -qqy --no-install-recommends \
	make \
	build-essential \
	libssl-dev \
	zlib1g-dev \
	libbz2-dev \
	libreadline-dev \
	libsqlite3-dev \
	wget \
	curl \
	llvm \
	libncurses5-dev \
	libncursesw5-dev \
	xz-utils \
	tk-dev \
	libffi-dev \
	liblzma-dev \
	git \
	ca-certificates \
	&& rm -rf /var/lib/apt/lists/*
RUN curl -s -S -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash && \
	git clone https://github.com/momo-lab/pyenv-install-latest.git "$(pyenv root)"/plugins/pyenv-install-latest && \
	pyenv install-latest "3.10.6" && \
	pyenv global $(pyenv install-latest --print "3.10.6") && \
	pip install "wheel<1"
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked apt-get update -qq && apt-get install -qqy ffmpeg && rm -rf /var/lib/apt/lists/*
RUN --mount=type=bind,from=deps,source=/dep,target=/dep \
    cp -rf /dep/* $(pyenv prefix)/lib/python*/site-packages; \
    cp -rf /dep/bin/* $(pyenv prefix)/bin; \
    pyenv rehash
RUN curl -o /usr/local/bin/pget -L "https://github.com/replicate/pget/releases/download/v0.8.1/pget_linux_x86_64" && chmod +x /usr/local/bin/pget
RUN pip install onnxruntime-gpu --extra-index-url https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/onnxruntime-cuda-12/pypi/simple/
# fal platform will inject the necessary mechanisms to run your application. // [!code ++]
WORKDIR /src # [!code --]
EXPOSE 5000 # [!code --]
CMD ["python", "-m", "cog.server.http"] # [!code --]
COPY . /src # [!code --]
```

And that's it! 🎉

Ensure all dependencies and paths match your project's requirements.

## Step 3: Deploy on fal

fal supports deploying Docker-based applications easily. Follow these steps to deploy your Docker container on fal:

1. **Create an account on fal**: If you haven't already, sign up at [fal](https://fal.ai).

2. **Create a new project**: In your favorite directory, create a new project and move the `Dockerfile` into it. Create a new Python file with the following content:

```python theme={null}
import fal

from fal.container import ContainerImage
from pathlib import Path

PWD = Path(__file__).resolve().parent


class MyApp(fal.App):
	image = ContainerImage.from_dockerfile(f"{PWD}/Dockerfile")

	def setup(self):
		...

	@fal.endpoint("/")
	def predict(self, input: Input) -> Output:
		# Rest is your imagination.
```

<Note>
  **Converting your app/server**

  On a serious note, you need to do a little bit of conversion to run your
  application. But don't get intimidated, it's just a few lines of code. The
  structure is of cog server and fal apps are similar, so you can easily adapt
  your application to run on fal.
</Note>

You can see details documentation on how to use fal SDK [here](/serverless).

More information on how to deploy a containerized application can be found [here](/serverless/development/use-custom-container-image).

## Step 4: Test Your Deployment

Once deployed, ensure that everything is working as expected by accessing your application through the URL provided by fal. Monitor logs and performance to make sure the migration was successful.

## Troubleshooting

If you encounter any issues during the migration, check the following:

* **Dependencies**: Ensure all required dependencies are listed in your `requirements.txt` or equivalent file.
* **Environment Variables and Build Arguments**: Double-check that all necessary environment variables and build arguments are set correctly in your Dockerfile.
* **Logs**: Use the logging features in fal to diagnose any build or runtime issues.

For further assistance, refer to the [fal Documentation](#) or reach out to the fal support team.

## Conclusion

Migrating from Replicate to fal can be smooth with proper preparation and testing. This guide provides a straightforward path, but each project may have unique requirements. Adapt these steps as needed to fit your specific use case.

For additional help, join our community on [Discord](https://discord.com/invite/fal-ai) or contact our support team.


# https://fal.ai/docs/examples/integrations/migrate-from-runpod.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from RunPod

> A guide for migrating your RunPod Serverless workers to fal.

If you have been running serverless GPU workloads on RunPod, this guide maps RunPod concepts to their fal equivalents and shows how to convert your code. The core ideas are similar: both platforms run your code on GPU machines that scale based on demand. The main difference is that RunPod uses a handler function pattern with explicit Docker builds, while fal uses a class-based `fal.App` with automatic container builds.

For a broader overview of deploying existing Docker containers on fal (regardless of where they came from), see [Deploy an Existing Server](/examples/integrations/migrate-external-docker-server). If you are comparing fal to other platforms, see [Migrate from Replicate](/examples/integrations/migrate-from-replicate) or [Migrate from Modal](/examples/integrations/migrate-from-modal).

## Concept Mapping

| RunPod                                          | fal                                        | Notes                                                                          |
| ----------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------ |
| `handler(job)`                                  | `@fal.endpoint("/")`                       | Request handler function                                                       |
| `runpod.serverless.start({"handler": handler})` | `class MyApp(fal.App)`                     | App entrypoint                                                                 |
| `job["input"]`                                  | Pydantic `Input` model                     | fal validates and types inputs automatically                                   |
| `return result`                                 | `return Output(...)`                       | fal validates outputs with Pydantic                                            |
| `yield result` (streaming)                      | `StreamingResponse` or `@fal.realtime()`   | See [Streaming](/documentation/development/streaming)                          |
| Model loading at module level                   | `def setup(self)`                          | Runs once per runner, not per request                                          |
| `refresh_worker: True`                          | Return HTTP 503                            | Terminates the runner and spins up a fresh one                                 |
| `runpod.serverless.progress_update()`           | `print()` (logs visible via SDK)           | Or use [streaming](/documentation/development/streaming) for real-time updates |
| Dockerfile + Docker Hub                         | `requirements = [...]` or `ContainerImage` | fal builds containers for you, or bring your own                               |
| Docker Hub deployment                           | `fal deploy`                               | Single CLI command                                                             |
| `/run` (async)                                  | `fal_client.submit()`                      | Queue-based async                                                              |
| `/runsync` (sync)                               | `fal_client.subscribe()`                   | Blocks until result                                                            |
| `/stream`                                       | `fal_client.stream()`                      | Progressive output                                                             |
| Max workers                                     | `max_concurrency`                          | Maximum runners to scale to                                                    |
| Min workers                                     | `min_concurrency`                          | Minimum runners kept warm                                                      |
| Idle timeout                                    | `keep_alive`                               | Seconds before idle runner shuts down                                          |
| Concurrency per worker                          | `max_multiplexing`                         | Concurrent requests per runner                                                 |
| Network volumes                                 | `/data` persistent storage                 | Mounted automatically on all runners                                           |
| Environment variables                           | `fal secrets set`                          | Secrets exposed as env vars                                                    |

***

## Migration Path: Handler to fal.App

The most common pattern on RunPod is a handler function that loads a model at module level and processes requests. On fal, this maps to a `fal.App` class where model loading moves into `setup()` and the handler becomes an endpoint method.

<Tabs>
  <Tab title="RunPod">
    ```python theme={null}
    import runpod
    import torch
    from diffusers import StableDiffusionXLPipeline

    model = StableDiffusionXLPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        torch_dtype=torch.float16,
    ).to("cuda")

    def handler(job):
        prompt = job["input"]["prompt"]
        image = model(prompt).images[0]
        image.save("/tmp/output.png")
        return {"image_path": "/tmp/output.png"}

    runpod.serverless.start({"handler": handler})
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal
    from pydantic import BaseModel
    from fal.toolkit import Image

    class Input(BaseModel):
        prompt: str

    class Output(BaseModel):
        image: Image

    class MyApp(fal.App):
        machine_type = "GPU-A100"
        requirements = ["torch", "diffusers"]
        keep_alive = 300
        max_concurrency = 5

        def setup(self):
            import torch
            from diffusers import StableDiffusionXLPipeline

            self.model = StableDiffusionXLPipeline.from_pretrained(
                "stabilityai/stable-diffusion-xl-base-1.0",
                torch_dtype=torch.float16,
            ).to("cuda")

        @fal.endpoint("/")
        def generate(self, input: Input) -> Output:
            image = self.model(input.prompt).images[0]
            return Output(image=Image.from_pil(image))
    ```
  </Tab>
</Tabs>

Key differences in the fal version:

The model loading moves from module-level into `setup()`, which runs once per [runner](/documentation/getting-started/runners-and-caching) rather than once per container build. Inputs are validated through a Pydantic model instead of manually extracting from `job["input"]`. Outputs are also typed, and images are automatically uploaded to the [fal CDN](/documentation/model-apis/fal-cdn) rather than saved to a local path. You do not need to write a Dockerfile or push to Docker Hub since fal builds the container from your `requirements` list.

## Calling Your Deployed App

RunPod exposes `/run` (async), `/runsync` (sync), and `/stream` endpoints. fal provides equivalent patterns through the client SDK.

<Tabs>
  <Tab title="RunPod">
    ```python theme={null}
    import runpod

    runpod.api_key = "your_api_key"
    endpoint = runpod.Endpoint("your_endpoint_id")

    # Sync
    result = endpoint.run_sync({"prompt": "a sunset"})

    # Async
    run = endpoint.run({"prompt": "a sunset"})
    status = run.status()
    result = run.output()
    ```
  </Tab>

  <Tab title="fal">
    ```python theme={null}
    import fal_client

    # Sync (subscribe polls automatically)
    result = fal_client.subscribe("your-username/your-app", arguments={
        "prompt": "a sunset"
    })

    # Async
    handler = fal_client.submit("your-username/your-app", arguments={
        "prompt": "a sunset"
    })
    status = handler.status()
    result = handler.get()
    ```
  </Tab>
</Tabs>

For the full range of calling patterns including streaming, real-time WebSockets, and webhooks, see [Calling Your Endpoints](/documentation/development/calling-your-endpoints).

## Deployment Workflow

On RunPod, the deployment unit is a Docker image. Your handler code lives inside the image, and the workflow requires several manual steps: write a Dockerfile that copies your handler and installs dependencies, build the image locally, push it to Docker Hub, then deploy through RunPod's console by pointing it at the image URL.

<Tabs>
  <Tab title="RunPod workflow">
    ```dockerfile theme={null}
    # 1. Write a Dockerfile
    FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
    RUN pip install runpod diffusers transformers
    COPY handler.py /handler.py
    CMD ["python", "/handler.py"]
    ```

    ```bash theme={null}
    # 2. Build locally
    docker build -t myuser/my-model:latest .

    # 3. Push to Docker Hub
    docker push myuser/my-model:latest

    # 4. Deploy via RunPod console (manual step in the UI)
    ```
  </Tab>

  <Tab title="fal workflow">
    ```python theme={null}
    # 1. Write your app (no Dockerfile needed)
    class MyApp(fal.App):
        machine_type = "GPU-A100"
        requirements = ["torch", "diffusers", "transformers"]

        def setup(self):
            ...
    ```

    ```bash theme={null}
    # 2. Deploy (one command, fal builds the container for you)
    fal deploy my_app.py::MyApp
    ```
  </Tab>
</Tabs>

On fal, there is no manual Docker build, no Docker Hub, and no console-based deployment. You run `fal deploy` and fal handles the container build, image storage, and deployment. Your code and your environment definition live in the same Python file.

## Environment and Dependencies

Because fal eliminates the Docker build step for most use cases, you have two options for defining your environment:

**Option 1: pip requirements (recommended).** List your packages in the `requirements` attribute. fal builds the container automatically. This is the simplest migration path since you can copy the `pip install` lines from your RunPod Dockerfile directly into the list.

```python theme={null}
class MyApp(fal.App):
    requirements = ["torch==2.1.0", "diffusers==0.30.0", "transformers"]
```

**Option 2: Custom Docker container.** If you need system packages, a specific CUDA version, or want to reuse your existing RunPod Dockerfile with minimal changes, use [ContainerImage](/documentation/development/use-custom-container-image). You can paste your RunPod Dockerfile almost as-is, just remove the `COPY handler.py` and `CMD` lines since fal handles those.

```python theme={null}
from fal.container import ContainerImage

class MyApp(fal.App):
    image = ContainerImage.from_dockerfile_str("""
        FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
        RUN apt-get update && apt-get install -y ffmpeg
        RUN pip install diffusers transformers
    """)
```

## Model Storage

RunPod offers three approaches for model weights: Hugging Face cache, baked into the Docker image, or network volumes. fal's equivalent is [persistent storage](/documentation/development/use-persistent-storage) at `/data`, which is mounted on every runner and shared across your account. Models downloaded to `/data` are cached automatically and survive runner restarts, similar to RunPod's network volumes but without explicit volume configuration.

```python theme={null}
def setup(self):
    import os
    os.environ["HF_HOME"] = "/data/.cache/huggingface"

    from diffusers import StableDiffusionXLPipeline
    self.model = StableDiffusionXLPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0"
    ).to("cuda")
```

## Next Steps

Once you have migrated your handler, the [App Lifecycle](/documentation/development/app-lifecycle) page explains how the full lifecycle works on fal, from code serialization to runner shutdown. For scaling configuration, see [Scale Your Application](/documentation/deployment/scale-your-application). For monitoring your deployed app, see [App Analytics](/documentation/serverless/observability/app-analytics).


# https://fal.ai/docs/examples/integrations/n8n.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Using fal within an n8n workflow

> This guide will demonstrate, step-by-step, how to use fal within an n8n workflow.

## Prerequisites

* An n8n account ([https://n8n.io/](https://n8n.io/))
* A fal account ([https://fal.ai/dashboard](https://fal.ai/dashboard))
* A fal API key (generated from your account dashboard)

## Workflow Overview

This n8n workflow consists of three main HTTP requests:

<Steps>
  <Step title="Submit Request">
    Send a POST request to initiate content generation
  </Step>

  <Step title="Check Status">
    Poll the status of your request using GET
  </Step>

  <Step title="Retrieve Result">
    Fetch the final generated content
  </Step>
</Steps>

## Step 1: Create Your Workflow

<Steps>
  <Step>
    In n8n, create a new workflow
  </Step>

  <Step>
    Start with a **Manual Trigger** node to initiate the workflow manually
  </Step>
</Steps>

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/01.webp?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=86505fc90245b94c09161f2a1762d388" alt="" width="2266" height="1646" data-path="images/n8n/01.webp" />
</Frame>

## Step 2: Submit Request (POST)

### Add HTTP Request Node

<Steps>
  <Step>
    Add an **HTTP Request** node after your trigger
  </Step>

  <Step>
    Set the **Method** to `POST`
  </Step>
</Steps>

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/02.webp?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=cd7de677bed6fd24446726e7fdfd5999" alt="" width="2266" height="1646" data-path="images/n8n/02.webp" />
</Frame>

### Configure the URL

<Steps>
  <Step>
    Navigate to [fal.ai](https://fal.ai/dashboard) and select your desired model (e.g., `fal-ai/veo3/fast`)

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/03.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=3f36e5adf0e0359186dc049e83546101" alt="" width="2458" height="1912" data-path="images/n8n/03.png" />
    </Frame>
  </Step>

  <Step>
    Click on the **API** tab, select "HTTP (cURL)" and "Submit a request". Copy and save the URL and data JSON as those will be needed for later.

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/04.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=c9b0c680a03dd7291a1457743c8ebb62" alt="" width="2028" height="906" data-path="images/n8n/04.png" />
    </Frame>
  </Step>

  <Step>
    Copy the URL (e.g., `https://queue.fal.run/fal-ai/veo3/fast`) and paste it into the URL field in n8n

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/05.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=c1d3192e62f6b9d6868d2ae32e4004dd" alt="" width="2266" height="1646" data-path="images/n8n/05.png" />
    </Frame>
  </Step>
</Steps>

### Set Up Authentication

<Steps>
  <Step>
    Navigate to [fal.ai API Keys](https://fal.ai/dashboard/keys), create a new key and copy its value.

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/06.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=d2104fe703ca052d8123a24e5f2a85df" alt="" width="2448" height="1420" data-path="images/n8n/06.png" />
    </Frame>
  </Step>

  <Step>
    Back in n8n, in the **Authentication** section, select **Generic Credential Type**
  </Step>

  <Step>
    Choose **Header Auth** from the dropdown
  </Step>

  <Step>
    Click **+ Create new credential**
  </Step>

  <Step>
    Set:

    * **Name**: `Authorization`
    * **Value**: `Key YOUR_FAL_KEY`
  </Step>

  <Step>
    Save the credential and close

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/07.webp?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=7dc459c9cb98b714d5faa0e7950ae1dc" alt="" width="2266" height="1646" data-path="images/n8n/07.webp" />
    </Frame>
  </Step>
</Steps>

### Configure Request Body

<Steps>
  <Step>
    Toggle **Send Body** to `ON`
  </Step>

  <Step>
    Set **Body Content Type** to `JSON`
  </Step>

  <Step>
    Choose **Specify Body** as `USING JSON`

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/08.webp?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=5fc79b5a0908e101aafa7fd35b5d476f" alt="" width="2266" height="1646" data-path="images/n8n/08.webp" />
    </Frame>
  </Step>

  <Step>
    In fal, go again to the model page, select **JSON** from dropdown and copy the payload

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/09.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=6e0c82d5d7c580e9aa49ec9e8ea66ada" alt="" width="2502" height="1646" data-path="images/n8n/09.png" />
    </Frame>
  </Step>

  <Step>
    Copy the JSON payload and paste it into n8n's JSON text box

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/10.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=ad419e143400976fa0a08921b391c968" alt="" width="2266" height="1646" data-path="images/n8n/10.png" />
    </Frame>
  </Step>
</Steps>

### Execute the Node

<Steps>
  <Step>
    Click **Execute Node** to test the request. You should receive a response with a request ID.

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/11.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=c8cdd5bb3f4083774e498441e820dbd9" alt="" width="2266" height="1646" data-path="images/n8n/11.png" />
    </Frame>
  </Step>
</Steps>

## Step 3: Check Status (GET)

### Add Second HTTP Request Node

<Steps>
  <Step>
    Click on the first HTTP Request node and add another **HTTP Request** node
  </Step>

  <Step>
    Set the **Method** to `GET`
  </Step>
</Steps>

### Configure Status Check URL

<Steps>
  <Step>
    In fal, go to your model's **API** section and find the **GET** URL for status checking

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/12.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=d8963881f4ac744d8e40644115f0aeaa" alt="" width="2032" height="542" data-path="images/n8n/12.png" />
    </Frame>
  </Step>

  <Step>
    Copy this URL and paste it into the URL field
  </Step>

  <Step>
    You'll need to replace the request ID from the previous step on this URL, with `{{ $json.request_id }}`

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/13.webp?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=ded90911ad1c72b9f3dd21e580dfdf63" alt="" width="2266" height="1646" data-path="images/n8n/13.webp" />
    </Frame>
  </Step>
</Steps>

### Set Authentication

<Steps>
  <Step>
    Use the same **Header Auth** credential created earlier
  </Step>

  <Step>
    Select your existing **Authorization** credential
  </Step>
</Steps>

### Execute the Node

1. This will check the status of your generation request.

<Frame>
  <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/n8n/14.webp?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=80f6186759e48b38a2512042c4fa2c79" alt="" width="2266" height="1646" data-path="images/n8n/14.webp" />
</Frame>

## Step 4: Retrieve Result (GET)

### Add Third HTTP Request Node

1. Add a final **HTTP Request** node
2. Set the **Method** to `GET`

### Configure Result URL

1. Use the result URL provided in the status response by setting the URL to `{{ $json.request_url }}`

### Set Authentication

1. Use the same **Header Auth** credential

### Execute the Node

This will retrieve your final generated content.

## Testing Your Workflow

<Steps>
  <Step>
    Save your workflow
  </Step>

  <Step>
    Click **Execute Workflow** to run the complete process
  </Step>

  <Step>
    Monitor each node to ensure successful execution
  </Step>

  <Step>
    Check the final node output for your generated content
  </Step>
</Steps>

## Best Practices

* **Error Handling**: Add error handling nodes to manage failed requests
* **Delays**: Consider adding **Wait** nodes between status checks to avoid overwhelming the API
* **Conditional Logic**: Use **IF** nodes to check status before proceeding to result retrieval
* **Data Transformation**: Use **Set** nodes to extract and format specific data from responses

## Troubleshooting

* **401 Unauthorized**: Check that your API key is correctly set in the authentication header
* **Request ID Missing**: Ensure the first POST request completed successfully and returned a request ID
* **Status Still Processing**: Add appropriate delays between status checks
* **Invalid JSON**: Verify your JSON payload matches the model's expected format

## Next Steps

Once you have a working workflow, you can:

* Connect it to external triggers (webhooks, schedules, etc.)
* Integrate with other services in your n8n workflow
* Add data processing and transformation steps
* Set up notifications for completed generations


# https://fal.ai/docs/examples/integrations/nextjs.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Add fal.ai to your Next.js app Integration

## You will learn how to:

<Steps>
  <Step>
    Install the fal.ai libraries
  </Step>

  <Step>
    Add a server proxy to protect your credentials
  </Step>

  <Step>
    Generate an image using SDXL
  </Step>
</Steps>

## Prerequisites

1. Have an existing Next.js app or create a new one using `npx create-next-app`
2. Have a [fal.ai](https://fal.ai) account
3. Have an API Key. You can [create one here](https://fal.ai/dashboard/keys)

## 1. Install the fal.ai libraries

Using your favorite package manager, install both the `@fal-ai/client` and `@fal-ai/server-proxy` libraries.

<CodeGroup>
  ```bash npm icon="npm" theme={null}
  npm install @fal-ai/client @fal-ai/server-proxy
  ```

  ```bash yarn icon="yarn" theme={null}
  yarn add @fal-ai/client @fal-ai/server-proxy
  ```

  ```bash pnpm icon="square-terminal" theme={null}
  pnpm add @fal-ai/client @fal-ai/server-proxy
  ```
</CodeGroup>

## 2. Setup the proxy

The proxy will protect your API Key and prevent it from being exposed to the client. Usually app implementation have to handle that integration themselves, but in order to make the integration as smooth as possible, we provide a drop-in proxy implementation that can be integrated with either the **Page Router** or the **App Router**.

### 2.1. Page Router

If you are using the **Page Router** (i.e. `src/pages/_app.js`), create an API handler in `src/pages/api/fal/proxy.js` (or `.ts` in case of TypeScript), and re-export the built-in proxy handler:

```ts theme={null}
import { createPageRouterHandler } from "@fal-ai/server-proxy/nextjs";

export default createPageRouterHandler();
```

### 2.2. App Router

If you are using the **App Router** (i.e. `src/app/page.jsx`) create a route handler in `src/app/api/fal/proxy/route.js` (or `.ts` in case of TypeScript), and re-export the route handler:

```ts theme={null}
import { createRouteHandler } from "@fal-ai/server-proxy/nextjs";

export const { GET, POST, PUT } = createRouteHandler();
```

### 2.3. Setup the API Key

Make sure you have your API Key available as an environment variable. You can setup in your `.env.local` file for development and also in your hosting provider for production, such as [Vercel](https://vercel.com/docs/projects/environment-variables).

```sh theme={null}
FAL_KEY="key_id:key_secret"
```

### 2.4. Custom proxy logic

It's common for applications to execute custom logic before or after the proxy handler. For example, you may want to add a custom header to the request, or log the request and response, or apply some rate limit. The proxy returns standard Next.js route handlers, which means you can compose them with other handlers.

For example, let's assume you want to add some analytics and apply some rate limit to the proxy handler:

```ts theme={null}
import { createRouteHandler } from "@fal-ai/server-proxy/nextjs";

const falProxy = createRouteHandler();

export const POST = (req) => {
  analytics.track("fal.ai request", {
    targetUrl: req.headers.get("x-fal-target-url"),
    userId: req.user.id,
  });

  if (rateLimiter.shouldLimit(req)) {
    return Response.json({ error: "Too many requests" }, { status: 429 });
  }

  return falProxy.POST(req);
};

export const GET = falProxy.GET;
```

Note that the URL that will be forwarded to server is available as a header named `x-fal-target-url`. Also, keep in mind the example above is just an example, `rateLimiter` and `analytics` are just placeholders.

The example above used the app router, but the same logic can be applied to the page router and its `handler` function.

## 3. Configure the client

On your main file (i.e. `src/pages/_app.jsx` or `src/app/page.jsx`), configure the client to use the proxy:

```ts theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  proxyUrl: "/api/fal/proxy",
});
```

<Note>
  **Protect your API Key**

  Although the client can be configured with credentials, use that only for rapid prototyping. We recommend you always use the proxy to avoid exposing your API Key in the client before you deploy your web application. See the [server-side guide](/model-apis/model-endpoints/server-side) for more details.
</Note>

## 4. Generate an image

Now that the client is configured, you can generate an image using `fal.subscribe` and pass the model id and the input parameters:

```ts theme={null}
const result = await fal.subscribe("fal-ai/flux/dev", {
  input: {
    prompt,
    image_size: "square_hd",
  },
  pollInterval: 5000,
  logs: true,
  onQueueUpdate(update) {
    console.log("queue update", update);
  },
});

const imageUrl = result.data.images[0].url;
```

See more about Flux Dev used in this example on [fal.ai/models/fal-ai/flux/dev](https://fal.ai/models/fal-ai/flux/dev).

## What's next?

Image generation is just one of the many cool things you can do with fal. Make sure you:

* Check our demo application at [github.com/fal-ai/serverless-js/apps/demo-nextjs-app-router](https://github.com/fal-ai/fal-js/tree/main/apps/demo-nextjs-app-router)
* Check all the available [Model APIs](https://fal.ai/models)
* Learn how to write your own model APIs on [Introduction to serverless functions](/serverless)
* Read more about function endpoints on [private serverless models](/serverless)
* Check the next page to learn how to [deploy your app to Vercel](/model-apis/integrations/vercel)


# https://fal.ai/docs/examples/integrations/use-llms.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use LLMs Tutorial

> fal provides an easy-to-use API for generating text using Language Models (LLMs). You can use the `fal-ai/any-llm` endpoint to generate text based on a given prompt and model.

Here’s an example of how to use the `fal-ai/any-llm` endpoint to generate text using the `anthropic/claude-3.5-sonnet` model:

```js theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/any-llm", {
  input: {
    model: "anthropic/claude-3.5-sonnet",
    prompt: "What is the meaning of life?"
  },
});
```

## How to select LLM model to use

fal offers a variety of LLM models. You can select the model that best fits your needs based on the style and quality of the text you want to generate. Here are some of the available models:

* `anthropic/claude-3.5-sonnet`: Claude 3.5 Sonnet
* `google/gemini-pro-1.5`: Gemini Pro 1.5
* `meta-llama/llama-3.2-3b-instruct`: Llama 3.2 3B Instruct
* `openai/gpt-4o`: GPT-4o

To select a model, simply specify the model ID in the `model` field as shown in the example above. You can find more LLMs in the [Any LLM](https://fal.ai/models/fal-ai/any-llm) page.


# https://fal.ai/docs/examples/integrations/vercel.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Add fal.ai to your Next.js app Integration

## You will learn how to:

* Connect a Next.js app deployed on Vercel to fal.ai

## Prerequisites

<Steps>
  <Step>
    A [fal.ai](https://fal.ai) account
  </Step>

  <Step>
    A [Vercel account](https://vercel.com)
  </Step>

  <Step>
    A Next.js app. Check the [Next.js guide](/model-apis/integrations/nextjs) if you don't have one yet.
  </Step>

  <Step>
    App deployed on Vercel. Run `npx vercel` in your app directory to deploy it in case you haven't done it yet.
  </Step>
</Steps>

## Vercel official integration

The recommended way to add fal.ai to your app deployed on Vercel is to use the official integration. You can find it in the [Vercel marketplace](https://vercel.com/integrations/fal).

Click on **Add integration** and follow the steps. After you're done, re-deploy your app and you're good to go!

<Frame>
  ![Vercel integration](https://integrations-og-image.vercel.sh/api/og/fal?42673700034a7509d66487f3ed68a2bd)
</Frame>

## Manual setup

You can also manually add fal credentials to your Vercel environment manually.

<Steps>
  <Step>
    Go to your [fal.ai dashboard](https://fal.ai/dashboard/keys), create an **API-scoped** key and copy it. Make sure you create an alias do identify which app is using it.
  </Step>

  <Step>
    Go to your app settings in Vercel and add a new environment variable called `FAL_KEY` with the value of the key you just copied. You can choose other names, but keep in mind that the default convention of fal-provided libraries is `FAL_KEY`.
  </Step>

  <Step>
    Re-deploy your app and you're good to go!
  </Step>
</Steps>


# https://fal.ai/docs/examples/serverless/deploy-prometheus-pushgateway.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Publish Custom Metrics with Prometheus Pushgateway

> Publish custom metrics on fal using Prometheus Pushgateway with direct port exposure and persistent storage.

Serverless workers are usually short-lived, which makes them a poor direct scrape target for Prometheus.
[Prometheus Pushgateway](https://github.com/prometheus/pushgateway) solves this by letting your jobs push metrics to a stable endpoint that Prometheus scrapes on its own schedule.

In this example, you deploy Pushgateway itself on fal as a small always-available service with persistent storage for metric state. Then your apps push custom metrics to it, and Prometheus scrapes from one predictable URL.

## 🚀 Try this Example

**Steps to run:**

1. Save this as `pushgateway.py`:

```python theme={null}
import os
import subprocess

import fal
from fal.container import ContainerImage

PORT = 8080
PERSISTENCE_DIR = "/data/pushgateway"
PERSISTENCE_FILE = f"{PERSISTENCE_DIR}/metrics.dat"

@fal.function(
    image=ContainerImage.from_dockerfile_str(
        r"""
FROM prom/pushgateway:v1.11.0 AS pushgateway_stage

FROM python:3.10-slim-bookworm
COPY --from=pushgateway_stage /bin/pushgateway /usr/local/bin/pushgateway
"""
    ),
    machine_type="M",
    exposed_port=PORT,
    max_concurrency=1,
    min_concurrency=1,
    max_multiplexing=256,
)
def pushgateway() -> None:
    os.makedirs(PERSISTENCE_DIR, exist_ok=True)
    subprocess.run(
        [
            "pushgateway",
            f"--web.listen-address=0.0.0.0:{PORT}",
            f"--persistence.file={PERSISTENCE_FILE}",
            "--persistence.interval=5m",
        ],
        check=True,
    )
```

2. Deploy it:

```bash theme={null}
fal deploy pushgateway.py::pushgateway --name pushgateway
```

After deploy, your gateway is available at:

```text theme={null}
https://fal.run/<your-username>/pushgateway
```

Opening that URL in a browser (`/`) shows the Pushgateway web interface, which is useful for quickly checking pushed metric groups.

## Push and Scrape Metrics

Set your base URL:

```bash theme={null}
BASE_URL="https://fal.run/<your-username>/pushgateway"
```

Push a sample metric:

```bash theme={null}
cat <<'EOF' | curl -X PUT \
  -H "Content-Type: text/plain" \
  -H "Authorization: Key $FAL_KEY" \
  --data-binary @- \
  "$BASE_URL/metrics/job/example/instance/local"
# TYPE demo_jobs_total counter
demo_jobs_total 1
EOF
```

Scrape all metrics:

```bash theme={null}
curl -H "Authorization: Key $FAL_KEY" "$BASE_URL/metrics"
```

Check health:

```bash theme={null}
curl -H "Authorization: Key $FAL_KEY" "$BASE_URL/-/healthy"
```

## Prometheus Scrape Configuration

Use `fal.run` as the target host and include your app path in `metrics_path`:

```yaml theme={null}
scrape_configs:
  - job_name: fal_pushgateway
    honor_labels: true
    scheme: https
    static_configs:
      - targets: ["fal.run"]
    metrics_path: /<your-username>/pushgateway/metrics
    authorization:
      type: Key
      credentials: <your-fal-key>
```


# https://fal.ai/docs/examples/video-generation/deploy-3d-progressive-rendering.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy 3D Progressive Rendering

> Build a real-time text-to-3D and image-to-3D application with live voxel streaming using SAM-3D Objects.

This example demonstrates how to build a 3D reconstruction pipeline that streams
voxel data in real-time during diffusion. Watch your 3D models take shape
progressively as geometry and appearance diffusion stages run.

<div style={{ display: 'flex', gap: '16px', marginTop: '24px', marginBottom: '24px' }}>
  <video autoPlay loop muted playsInline controls style={{ flex: 1, borderRadius: '8px', maxWidth: '50%' }}>
    <source src="https://storage.googleapis.com/falserverless/example_inputs/3d.mp4" type="video/mp4" />
  </video>

  <video autoPlay loop muted playsInline controls style={{ flex: 1, borderRadius: '8px', maxWidth: '50%' }}>
    <source src="https://storage.googleapis.com/falserverless/example_inputs/minecraft3Dstream.mp4" type="video/mp4" />
  </video>
</div>

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/rehan-remade/Manifold).

**Live Demo:** [manifold-jet.vercel.app](https://manifold-jet.vercel.app/)

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate:

```bash theme={null}
fal auth login
```

3. Clone the repository with submodules:

```bash theme={null}
git clone --recurse-submodules https://github.com/rehan-remade/Manifold.git
cd Manifold
```

4. Set up the frontend:

```bash theme={null}
cd frontend
npm install
```

5. Configure environment variables in `frontend/.env.local`:

```env theme={null}
FAL_KEY=your_fal_api_key_here
FAL_ENDPOINT_ID=rehan/sam-3d-stream
GROQ_API_KEY=your_groq_api_key_here  # Optional, for prompt enhancement
```

6. Run the development server:

```bash theme={null}
npm run dev
```

Open [http://localhost:3000](http://localhost:3000) to see the demo.

<Tip>
  You can use the hosted endpoint `rehan/sam-3d-stream` directly, or deploy your own custom endpoint to modify the reconstruction pipeline.
</Tip>

## How it Works

1. **Prompt Enhancement** — Groq LLM (`llama-3.3-70b`) rewrites your text into an optimized image prompt + segmentation label
2. **Image Generation** — `fal-ai/z-image/turbo` generates a 3D-ready image in \~1s
3. **3D Reconstruction** — SAM-3D runs geometry and appearance diffusion on H100, streaming voxel data via SSE callbacks at each denoising step
4. **Live Visualization** — React Three Fiber renders voxels/mesh/GLB in real-time as data streams in

For image-to-3D, a vision model analyzes the uploaded image to generate the segmentation prompt.

## Deploy Your Own Endpoint

To customize the SAM-3D backend, deploy your own:

```bash theme={null}
cd serverless
fal deploy app.py::SAM3DStreamApp
```

Then update `FAL_ENDPOINT_ID` in `.env.local` with your new endpoint ID.

## Key Features

* **Progressive Rendering**: See voxels appear during both geometry and appearance diffusion stages
* **Binary Streaming Protocol**: Efficient base64-encoded voxel data (xyz + rgb per voxel)
* **Multiple Output Formats**: Voxels, vertex-colored mesh preview, and final GLB model
* **Custom Container**: Complex CUDA dependencies handled via Dockerfile
* **H100 GPU**: High-performance inference for fast reconstruction

## Backend Architecture

The serverless endpoint uses Server-Sent Events (SSE) for streaming progressive updates:

```python theme={null}
import fal
from fal.container import ContainerImage
from fastapi.responses import StreamingResponse

class SAM3DStreamApp(
    fal.App,
    keep_alive=600,
    kind="container",
    image=ContainerImage.from_dockerfile_str(dockerfile_str, builder="depot"),
):
    machine_type = "GPU-H100"

    def setup(self):
        # Download model weights and initialize pipeline
        from huggingface_hub import snapshot_download
        
        snapshot_download(
            "jetjodh/sam-3d-objects",
            local_dir=str(CACHE_DIR),
        )
        self.pipeline = self._create_pipeline(config_path)

    @fal.endpoint("/stream")
    def stream_3d_reconstruction(self, input: SAM3DStreamInput, request: Request):
        """Stream 3D reconstruction with real-time voxel visualization."""
        
        def geometry_callback(stage, step, total_steps, coords, **kwargs):
            # Encode and queue voxel data for streaming
            voxel_data = encode_voxels_binary(coords)
            progress_queue.put({
                "stage": "geometry",
                "step": step,
                "voxel_data": voxel_data,
            })

        def appearance_callback(stage, step, total_steps, coords, colors, **kwargs):
            # Stream colored voxels during appearance diffusion
            voxel_data = encode_voxels_binary(coords, colors)
            progress_queue.put({
                "stage": "appearance",
                "step": step,
                "voxel_data": voxel_data,
            })

        # Run pipeline with streaming callbacks
        outputs = self.pipeline.run(
            merged_image,
            geometry_callback=geometry_callback,
            appearance_callback=appearance_callback,
        )

        return StreamingResponse(
            event_stream(),
            media_type="text/event-stream",
        )
```

## SSE Event Types

The streaming endpoint emits these event types:

| Event          | Description                                                      |
| -------------- | ---------------------------------------------------------------- |
| `loading`      | Initial setup and image loading                                  |
| `geometry`     | Voxel coordinates during geometry diffusion (Stage 1)            |
| `appearance`   | Voxel coordinates + colors during appearance diffusion (Stage 2) |
| `mesh_preview` | Vertex-colored mesh (instant preview before texture baking)      |
| `glb_ready`    | Final textured GLB model data                                    |
| `complete`     | Final URLs for Gaussian splat and GLB files                      |

## Binary Voxel Encoding

Voxels are packed as uint8 arrays for efficient streaming:

```python theme={null}
def encode_voxels_binary(coords_np, colors_list):
    """Pack voxels as uint8: [x,y,z,r,g,b] per voxel."""
    # Normalize coordinates to 0-255 range
    coords_normalized = ((coords_np - coords_min) / coords_range * 255).astype(np.uint8)
    
    # Pack coordinates and colors
    packed = np.empty((len(coords_np), 6), dtype=np.uint8)
    packed[:, :3] = coords_normalized  # xyz
    packed[:, 3:] = colors_arr[:, :3]  # rgb
    
    return base64.b64encode(packed.tobytes()).decode("ascii")
```

## Frontend Integration

The React frontend uses a custom hook to consume the SSE stream:

```typescript theme={null}
export function useSAM3DStream() {
  const [voxels, setVoxels] = useState<Voxel[]>([]);
  const [meshData, setMeshData] = useState<MeshData | null>(null);
  const [renderMode, setRenderMode] = useState<RenderMode>("voxels");

  const startStream = useCallback(async (imageUrl: string, prompt: string) => {
    const response = await fetch("/api/stream-3d", {
      method: "POST",
      body: JSON.stringify({ imageUrl, prompt }),
    });

    const reader = response.body.getReader();
    
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      // Parse SSE events
      const event = JSON.parse(line.slice(6));
      
      if (event.stage === "geometry" || event.stage === "appearance") {
        const decoded = decodeVoxels(event);
        setVoxels(decoded);
        setRenderMode("voxels");
      } else if (event.stage === "mesh_preview") {
        const mesh = decodeMesh(event);
        setMeshData(mesh);
        setRenderMode("mesh");
      }
    }
  }, []);

  return { voxels, meshData, renderMode, startStream };
}
```

## Voxel Rendering with Three.js

Use React Three Fiber to render the streaming voxels:

```tsx theme={null}
function VoxelViewer({ voxels }: { voxels: Voxel[] }) {
  return (
    <Canvas>
      <instancedMesh args={[undefined, undefined, voxels.length]}>
        <boxGeometry args={[0.1, 0.1, 0.1]} />
        <meshStandardMaterial vertexColors />
        {voxels.map((voxel, i) => (
          <group key={i} position={[voxel.x, voxel.y, voxel.z]}>
            <mesh>
              <boxGeometry args={[0.1, 0.1, 0.1]} />
              <meshStandardMaterial color={voxel.color} />
            </mesh>
          </group>
        ))}
      </instancedMesh>
    </Canvas>
  );
}
```

## Custom Container Image

The backend requires complex CUDA dependencies. Use a Dockerfile for full control:

```python theme={null}
dockerfile_str = r"""
FROM nvidia/cuda:12.8.0-cudnn-devel-ubuntu22.04

# Install Python and system dependencies
RUN apt-get update && apt-get install -y python3.11 python3.11-dev \
    libgl1 libosmesa6 libosmesa6-dev

# PyTorch with CUDA support
RUN pip install torch==2.8.0 torchvision --index-url https://download.pytorch.org/whl/cu128

# SAM-3D Objects with streaming callback support
RUN git clone https://github.com/rehan-remade/sam-3d-objects.git && \
    cd sam-3d-objects && pip install -e .

# Additional 3D libraries
RUN pip install kaolin pytorch3d gsplat
"""

class SAM3DStreamApp(
    fal.App,
    kind="container",
    image=ContainerImage.from_dockerfile_str(dockerfile_str, builder="depot"),
):
    machine_type = "GPU-H100"
```

## Input Parameters

| Parameter               | Type          | Default  | Description                         |
| ----------------------- | ------------- | -------- | ----------------------------------- |
| `image_url`             | string        | required | URL of the image to reconstruct     |
| `mask_urls`             | list\[string] | `[]`     | Optional mask URLs for segmentation |
| `prompt`                | string        | `"car"`  | Text prompt for auto-segmentation   |
| `seed`                  | int           | random   | Random seed for reproducibility     |
| `stream_geometry_every` | int           | `1`      | Emit geometry updates every N steps |
| `stream_colors_every`   | int           | `1`      | Emit color updates every N steps    |

## Project Structure

```
manifold/
├── frontend/                 # Next.js web application
│   ├── app/
│   │   ├── page.tsx          # Main orchestrator
│   │   ├── api/              # Server-side API routes
│   │   ├── components/       # React Three Fiber components
│   │   ├── hooks/            # useSAM3DStream SSE hook
│   │   └── lib/              # Types, decoders, constants
│   └── public/
│
├── serverless/               # fal.ai serverless endpoint
│   ├── app.py                # SAM-3D streaming endpoint
│   └── pyproject.toml        # fal app config
│
└── sam-3d/                   # Git submodule (forked SAM-3D Objects)
```

## Performance Considerations

### Streaming Frequency

Control the streaming frequency to balance smoothness vs. performance:

```python theme={null}
class SAM3DStreamInput(BaseModel):
    stream_geometry_every: int = Field(
        default=1,
        ge=1,
        le=10,
        description="Emit geometry updates every N steps (1=smoothest, 10=fastest)",
    )
    stream_colors_every: int = Field(
        default=1,
        ge=1,
        le=10,
        description="Emit color updates every N steps",
    )
```

### Binary Encoding

The binary encoding reduces payload size significantly compared to JSON:

* 6 bytes per voxel (xyz + rgb as uint8)
* \~10,000 voxels = \~60KB per frame
* Base64 encoding adds \~33% overhead

## Key Takeaways

* **SSE streaming** enables real-time visualization of long-running 3D reconstruction
* **Binary encoding** makes voxel streaming efficient over HTTP
* **Custom containers** handle complex GPU dependencies (CUDA, PyTorch3D, kaolin)
* **Progressive rendering** gives users immediate visual feedback during generation
* **H100 GPUs** provide the compute power needed for fast 3D diffusion

This pattern demonstrates how to build interactive 3D AI applications that provide real-time feedback, combining the power of diffusion models with efficient streaming protocols and modern web rendering.


# https://fal.ai/docs/examples/video-generation/deploy-multi-gpu-inference.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Multi-GPU Inference

> Learn how to build a multi-GPU image generation service using data parallelism with Stable Diffusion XL, including real-time streaming and distributed worker coordination.

This tutorial demonstrates how to leverage multiple GPUs for parallel image generation using the `fal.distributed` module. We'll build a production-ready SDXL service that generates multiple image variations simultaneously and supports real-time streaming.

<Note>
  For a comprehensive overview of multi-GPU parallelism strategies and when to use them, see the [Multi-GPU Workloads Overview](/serverless/distributed/overview).
</Note>

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/tree/main/fal_demos/distributed/inference/parallel_sdxl).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate (if not already done):

```bash theme={null}
fal auth login
```

3. Copy the code below into `parallel_sdxl.py`

<CodeGroup>
  ```python parallel_sdxl.py wrap theme={null}
  from math import floor, sqrt
  from typing import TYPE_CHECKING, Any

  import fal
  from fal.distributed import DistributedRunner, DistributedWorker
  from fal.toolkit import File, Image
  from fastapi.responses import Response, StreamingResponse
  from pydantic import BaseModel, Field

  if TYPE_CHECKING:
      import torch
      from PIL import Image as PILImage

  # Helper function


  def tensors_to_image_grid(
      tensors: list["torch.Tensor"], blur_radius: int = 0
  ) -> "PILImage.Image":
      """
      Convert a list of tensors to a grid image.
      """
      import torchvision  # type: ignore[import-untyped]
      from PIL import Image as PILImage
      from PIL import ImageFilter

      # Create a grid of images
      image = (
          torchvision.utils.make_grid(
              tensors,
              nrow=floor(sqrt(len(tensors))),
              normalize=True,
              scale_each=True,
          )
          .permute(1, 2, 0)
          .cpu()
          .numpy()
      )
      image = (image * 255).astype("uint8")
      pil_image = PILImage.fromarray(image)

      if blur_radius > 0:
          pil_image = pil_image.filter(ImageFilter.GaussianBlur(radius=blur_radius))

      return pil_image


  # Distributed app code


  class ExampleDistributedWorker(DistributedWorker):
      """
      This is a distributed worker that runs on multiple GPUs.

      It will run the Stable Diffusion XL model using random seeds on each GPU,
      then return the images as a grid to the main process.
      """

      def setup(self, **kwargs: Any) -> None:
          """
          On setup, we need to initialize the model.
          """
          import torch
          from diffusers import AutoencoderTiny, StableDiffusionXLPipeline

          self.pipeline = StableDiffusionXLPipeline.from_pretrained(
              "stabilityai/stable-diffusion-xl-base-1.0",
              low_cpu_mem_usage=False,
          ).to(self.device, dtype=torch.float16)
          self.tiny_vae = AutoencoderTiny.from_pretrained(
              "madebyollin/taesdxl",
              torch_dtype=torch.float16,
          ).to(self.device, dtype=torch.float16)
          if self.rank != 0:
              self.pipeline.set_progress_bar_config(disable=True)

      def pipeline_callback(
          self,
          pipeline: "torch.nn.Module",
          step: int,
          timestep: int,
          tensors: dict[str, "torch.Tensor"],
      ) -> dict[str, "torch.Tensor"]:
          """
          This callback is called after each step of the pipeline.
          """
          if step > 0 and step % 5 != 0:
              return tensors

          import torch
          import torch.distributed as dist

          latents = tensors["latents"]
          image = self.tiny_vae.decode(
              latents / self.tiny_vae.config.scaling_factor, return_dict=False
          )[0]
          image = self.pipeline.image_processor.postprocess(image, output_type="pt")[0]

          if self.rank == 0:
              gather_list = [
                  torch.zeros_like(image, device=self.device)
                  for _ in range(self.world_size)
              ]
          else:
              gather_list = None

          dist.gather(image, gather_list, dst=0)

          if gather_list:
              remaining = timestep / 1000
              image = tensors_to_image_grid(gather_list, blur_radius=int(remaining * 10))
              self.add_streaming_result({"image": image}, as_text_event=True)

          dist.barrier()
          return tensors

      def __call__(
          self,
          streaming: bool = False,
          width: int = 1024,
          height: int = 1024,
          prompt: str = "A fantasy landscape",
          negative_prompt: str = "A blurry image",
          num_inference_steps: int = 20,
          **kwargs: Any,
      ) -> dict[str, Any]:
          """
          Run the model on the worker and return the image.
          """
          import torch
          import torch.distributed as dist

          image = self.pipeline(
              prompt=prompt,
              height=height,
              width=width,
              negative_prompt=negative_prompt,
              num_inference_steps=num_inference_steps,
              output_type="pt",
              callback_on_step_end=self.pipeline_callback if streaming else None,
          ).images[0]

          if self.rank == 0:
              gather_list = [
                  torch.zeros_like(image, device=self.device)
                  for _ in range(self.world_size)
              ]
          else:
              gather_list = None

          # Gather the images from all workers
          # this will block until all workers are done
          dist.gather(image, gather_list, dst=0)

          # Clean memory on all workers
          torch.cuda.empty_cache()

          if not gather_list:
              # If we are not the main worker, we don't need to do anything
              return {}

          # The main worker will receive the images from all workers
          image = tensors_to_image_grid(gather_list)
          return {"image": image}


  # Fal app code


  class ExampleRequest(BaseModel):
      """
      This is the request model for the example app.

      There is only one required field, the prompt.
      """

      prompt: str = Field()
      negative_prompt: str = Field(default="blurry, low quality")
      num_inference_steps: int = Field(default=20)
      width: int = Field(default=1024)
      height: int = Field(default=1024)


  class ExampleResponse(BaseModel):
      """
      This is the response model for the example app.

      The response contains the image as a file.
      """

      image: File = Field()


  class ExampleDistributedApp(fal.App):
      machine_type = "GPU-H100"
      num_gpus = 2
      requirements = [
          "accelerate==1.4.0",
          "diffusers==0.30.3",
          "fal",
          "huggingface_hub==0.26.5",
          "opencv-python",
          "torch==2.6.0+cu124",
          "torchvision==0.21.0+cu124",
          "transformers==4.47.1",
          "pyzmq==26.0.0",
          "--extra-index-url",
          "https://download.pytorch.org/whl/cu124",
      ]

      async def setup(self) -> None:
          """
          On setup, create a distributed runner to run the model on multiple GPUs.
          """
          self.runner = DistributedRunner(
              worker_cls=ExampleDistributedWorker,
              world_size=self.num_gpus,
          )
          # Start and wait for ready
          await self.runner.start()
          # Warm-up
          warmup_result = await self.runner.invoke(
              ExampleRequest(prompt="a cat wearing a hat").dict()
          )
          assert (
              "image" in warmup_result
          ), "Warm-up failed, no image returned from the worker"

      @fal.endpoint("/")
      async def run(self, request: ExampleRequest, response: Response) -> ExampleResponse:
          """
          Run the model on the worker and return the image.
          """
          result = await self.runner.invoke(request.dict())
          assert "image" in result, "No image returned from the worker"
          return ExampleResponse(image=Image.from_pil(result["image"]))

      @fal.endpoint("/stream")
      async def stream(
          self, request: ExampleRequest, response: Response
      ) -> StreamingResponse:
          """
          Run the model on the worker and return the image as a stream.
          This will return a streaming response that reads the data the worker adds
          via `add_streaming_result`. Images are automatically encoded as data URIs.
          """
          return StreamingResponse(
              self.runner.stream(
                  request.dict(),
                  as_text_events=True,
              ),
              media_type="text/event-stream",
          )


  if __name__ == "__main__":
      app = fal.wrap_app(ExampleDistributedApp)
      app()
  ```

  ```toml pyproject.toml theme={null}
  [build-system]
  requires = ["setuptools>=61.0"]
  build-backend = "setuptools.build_backend"

  [project]
  name = "fal-demos-parallel-sdxl"
  version = "0.1.0"
  description = "Multi-GPU parallel SDXL inference with fal.distributed"
  readme = "README.md"
  requires-python = ">=3.10"
  dependencies = [
      "fal",
      "pydantic<2.0,>=1.8",
  ]

  [tool.fal.apps]
  parallel-sdxl = { auth = "shared", ref = "parallel_sdxl:ExampleDistributedApp", no_scale=true }
  ```
</CodeGroup>

4. Run the app:

```bash theme={null}
fal run parallel_sdxl.py
```

<Info>
  **Or clone this repository**:

  ```bash theme={null}
  git clone https://github.com/fal-ai-community/fal-demos.git
  cd fal-demos
  pip install -e .
  # Use the app name (defined in pyproject.toml)
  fal run parallel-sdxl
  # Or use the full file path:
  # fal run fal_demos/distributed/inference/parallel_sdxl/app.py::ExampleDistributedApp
  ```
</Info>

<Tip>
  **Before you run**, make sure you have:

  * Authenticated with fal: `fal auth login`
  * Activated your virtual environment (recommended): `python -m venv venv && source venv/bin/activate`
</Tip>

## Key Features

* **Multi-GPU Data Parallelism**: Each GPU generates images independently with different random seeds
* **Real-time Streaming**: Stream intermediate results during generation
* **Distributed Coordination**: Automatic synchronization and result gathering across GPUs
* **Memory Efficient**: Uses TinyVAE for fast preview generation
* **Production Ready**: Includes warmup, error handling, and resource cleanup

## Architecture Overview

```mermaid theme={null}
flowchart TB
    App["ExampleDistributedApp<br/>(Main Process)<br/>• Receives HTTP requests<br/>• Manages DistributedRunner"]
    Runner["DistributedRunner<br/>• Orchestrates multiple workers<br/>• Handles communication (ZMQ)"]
    
    subgraph GPU0["GPU 0"]
        Worker0["DistributedWorker<br/>(Rank 0)<br/>• setup(): Load model<br/>• __call__(): Process data"]
    end
    
    subgraph GPU1["GPU 1"]
        Worker1["DistributedWorker<br/>(Rank 1)<br/>• setup(): Load model<br/>• __call__(): Process data"]
    end
    
    Gather["torch.distributed.gather()<br/>Collect results on Rank 0"]
    
    App --> Runner
    Runner --> Worker0
    Runner --> Worker1
    Worker0 --> Gather
    Worker1 --> Gather
    Gather --> App
    
    style App fill:#e1d7f9
    style Runner fill:#f0e7ff
    style Worker0 fill:#d4f1f4
    style Worker1 fill:#d4f1f4
    style Gather fill:#fff4e6
```

## Step-by-Step Implementation

### 1. Define the Distributed Worker

The worker extends `DistributedWorker` and runs on each GPU:

```python theme={null}
class ExampleDistributedWorker(DistributedWorker):
    def setup(self, **kwargs: Any) -> None:
        """Load the model on each GPU"""
        import torch
        from diffusers import AutoencoderTiny, StableDiffusionXLPipeline

        # Each GPU gets its own model instance
        self.pipeline = StableDiffusionXLPipeline.from_pretrained(
            "stabilityai/stable-diffusion-xl-base-1.0",
            low_cpu_mem_usage=False,
        ).to(self.device, dtype=torch.float16)
        
        # TinyVAE for fast preview generation
        self.tiny_vae = AutoencoderTiny.from_pretrained(
            "madebyollin/taesdxl",
            torch_dtype=torch.float16,
        ).to(self.device, dtype=torch.float16)
        
        # Disable progress bar for non-main workers
        if self.rank != 0:
            self.pipeline.set_progress_bar_config(disable=True)
```

**Key DistributedWorker Properties:** [API Reference →](/serverless/distributed/api-reference#distributedworker)

* **`self.device`**: PyTorch CUDA device for this worker (`cuda:0`, `cuda:1`, etc.). Always use `.to(self.device)` when loading models.
* **`self.rank`**: Worker ID (0 to N-1). Rank 0 is typically the "main" worker that returns results.
* **`self.world_size`**: Total number of workers (GPUs).
* **`setup(**kwargs)`**: Called once during `runner.start()` to initialize each worker.

### 2. Implement the Worker Logic

```python theme={null}
def __call__(
    self,
    streaming: bool = False,
    width: int = 1024,
    height: int = 1024,
    prompt: str = "A fantasy landscape",
    negative_prompt: str = "A blurry image",
    num_inference_steps: int = 20,
    **kwargs: Any,
) -> dict[str, Any]:
    """Generate image on this GPU"""
    import torch
    import torch.distributed as dist

    # Each GPU generates independently (different random seed)
    image = self.pipeline(
        prompt=prompt,
        height=height,
        width=width,
        negative_prompt=negative_prompt,
        num_inference_steps=num_inference_steps,
        output_type="pt",
        callback_on_step_end=self.pipeline_callback if streaming else None,
    ).images[0]

    # Prepare gather list on rank 0
    if self.rank == 0:
        gather_list = [
            torch.zeros_like(image, device=self.device)
            for _ in range(self.world_size)
        ]
    else:
        gather_list = None

    # Gather all images to rank 0
    dist.gather(image, gather_list, dst=0)

    # Only rank 0 returns results
    if not gather_list:
        return {}

    # Create a grid of all generated images
    image = tensors_to_image_grid(gather_list)
    return {"image": image}
```

**Important Concepts:**

1. **Independent Generation**: Each GPU uses a different random seed automatically
2. **Distributed Gather**: `dist.gather()` collects results from all GPUs to rank 0
3. **Rank-Specific Logic**: Only rank 0 prepares the gather list and returns results
4. **Memory Cleanup**: Clear CUDA cache after generation

### 3. Add Real-Time Streaming (Optional)

Stream intermediate results during generation:

```python theme={null}
def pipeline_callback(
    self,
    pipeline: "torch.nn.Module",
    step: int,
    timestep: int,
    tensors: dict[str, "torch.Tensor"],
) -> dict[str, "torch.Tensor"]:
    """Called after each inference step"""
    if step > 0 and step % 5 != 0:
        return tensors  # Only stream every 5 steps

    import torch
    import torch.distributed as dist

    # Decode latents to preview image
    latents = tensors["latents"]
    image = self.tiny_vae.decode(
        latents / self.tiny_vae.config.scaling_factor, return_dict=False
    )[0]
    image = self.pipeline.image_processor.postprocess(image, output_type="pt")[0]

    # Gather previews from all workers
    if self.rank == 0:
        gather_list = [
            torch.zeros_like(image, device=self.device)
            for _ in range(self.world_size)
        ]
    else:
        gather_list = None

    dist.gather(image, gather_list, dst=0)

    # Stream the grid preview
    if gather_list:
        remaining = timestep / 1000
        image = tensors_to_image_grid(gather_list, blur_radius=int(remaining * 10))
        self.add_streaming_result({"image": image}, as_text_event=True)
        # ↑ Sends intermediate results to the client during streaming
        # Only called from rank 0 to avoid duplicate messages
        # See: /serverless/distributed/api-reference#add_streaming_result

    dist.barrier()  # Sync all GPUs before continuing
    return tensors
```

**Streaming Features:**

* Progressive blur reduction as generation progresses
* Updates every 5 steps to balance frequency and overhead
* Uses TinyVAE for fast latent decoding
* Automatic base64 encoding for browser display
* `add_streaming_result()` sends updates to the client. [API Reference →](/serverless/distributed/api-reference#add_streaming_result)

### 4. Create the Main Application

```python theme={null}
class ExampleDistributedApp(fal.App):
    machine_type = "GPU-H100"
    num_gpus = 2  # Use 2 GPUs
    
    requirements = [
        "accelerate==1.4.0",
        "diffusers==0.30.3",
        "torch==2.6.0+cu124",
        "torchvision==0.21.0+cu124",
        "transformers==4.47.1",
        "pyzmq==26.0.0",  # Required for distributed communication
        "--extra-index-url",
        "https://download.pytorch.org/whl/cu124",
    ]

    async def setup(self) -> None:
        """Initialize the distributed runner"""
        # Create runner with your worker class and number of GPUs
        self.runner = DistributedRunner(
            worker_cls=ExampleDistributedWorker,
            world_size=self.num_gpus,
        )
        # Start all workers and initialize them
        await self.runner.start()
        
        # Warmup generation - tests that workers are ready
        warmup_result = await self.runner.invoke(
            ExampleRequest(prompt="a cat wearing a hat").dict()
        )
        assert "image" in warmup_result, "Warmup failed"

    @fal.endpoint("/")
    async def run(self, request: ExampleRequest) -> ExampleResponse:
        """Standard generation endpoint"""
        # Invoke workers and get the final result
        result = await self.runner.invoke(request.dict())
        return ExampleResponse(image=Image.from_pil(result["image"]))

    @fal.endpoint("/stream")
    async def stream(self, request: ExampleRequest) -> StreamingResponse:
        """Streaming generation endpoint"""
        # Stream intermediate results as they're generated
        return StreamingResponse(
            self.runner.stream(request.dict(), as_text_events=True),
            media_type="text/event-stream",
        )
```

<Info>
  **Key Methods Used:**

  * `DistributedRunner(worker_cls, world_size)` - Creates the runner. [API Reference →](/serverless/distributed/api-reference#distributedrunner)
  * `await runner.start()` - Initializes all workers. [API Reference →](/serverless/distributed/api-reference#start)
  * `await runner.invoke(payload)` - Executes workers and returns result. [API Reference →](/serverless/distributed/api-reference#invoke)
  * `runner.stream(payload, as_text_events=True)` - Streams intermediate results. [API Reference →](/serverless/distributed/api-reference#stream)
</Info>

**Configuration:**

* `num_gpus`: Specify number of GPUs to use
* `machine_type`: Choose GPU type (H100, A100, etc.)
* `pyzmq`: Required dependency for distributed communication

### 5. Define Input/Output Models

```python theme={null}
class ExampleRequest(BaseModel):
    prompt: str = Field()
    negative_prompt: str = Field(default="blurry, low quality")
    num_inference_steps: int = Field(default=20)
    width: int = Field(default=1024)
    height: int = Field(default=1024)

class ExampleResponse(BaseModel):
    image: File = Field()
```

## Running the Application

### Local Development

```bash theme={null}
# Run with fal CLI using app name
fal run parallel-sdxl

# Or use the full file path
fal run fal_demos/distributed/inference/parallel_sdxl/app.py::ExampleDistributedApp
```

### Production Deployment

```bash theme={null}
# Deploy to production
fal deploy parallel-sdxl
```

<Info>
  After running `fal run` or `fal deploy`, you'll see a URL like `https://fal.ai/dashboard/sdk/username/app-id/`. You can:

  * **Test in the Playground**: Click the URL or visit it in your browser to open the interactive playground
  * **View on Dashboard**: Visit [fal.ai/dashboard](https://fal.ai/dashboard) to see all your apps, monitor usage, and manage deployments
</Info>

### Using the Application

**Test in the Playground:**

After deploying, open the URL provided by the CLI (e.g., `https://fal.ai/dashboard/sdk/username/app-id/`) in your browser to access an interactive playground where you can test your app with a UI.

**Call from Code:**

**Standard Generation:**

```python theme={null}
import fal_client

result = fal_client.submit(
    "username/app-name",  # Replace with your deployed app name
    arguments={
        "prompt": "A serene mountain landscape at sunset",
        "num_inference_steps": 30
    }
)

# Get the result
output = result.get()
print(output["image"].url)
```

**Streaming Generation:**

```python theme={null}
import fal_client

for event in fal_client.stream(
    "username/app-name",  # Replace with your deployed app name
    arguments={
        "prompt": "A serene mountain landscape at sunset",
        "num_inference_steps": 30
    },
    path="/stream"
):
    print(f"Step {event['step']}: {event['progress'] * 100}%")
    if event.get("preview_image"):
        print(f"Preview available: {event['preview_image'].url}")
```

<Note>
  For other languages (JavaScript, TypeScript, etc.) and advanced client usage, see the [Client Libraries documentation](/model-apis/clients/javascript).
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Multi-GPU Workloads Overview" icon="diagram-project" href="/serverless/distributed/overview">
    Learn about other parallelism strategies
  </Card>

  <Card title="Deploy Text-to-Image Model" icon="image" href="/serverless/tutorials/deploy-text-to-image-model">
    Single-GPU image generation
  </Card>
</CardGroup>

## Additional Resources

* [fal.distributed API Reference](/serverless/distributed/api-reference)
* [PyTorch Distributed Documentation](https://pytorch.org/docs/stable/distributed.html)
* [Parallel SDXL Source Code](https://github.com/fal-ai-community/fal-demos/tree/main/fal_demos/distributed/inference/parallel_sdxl)


# https://fal.ai/docs/examples/video-generation/deploy-realtime-video-to-video-model.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Real-time Video-to-Video Model

> Run a real-time video-to-video pipeline that returns YOLO detections on your stream.

This example turns a live webcam feed into annotated video using YOLO. WebRTC is
the transport layer for low-latency, real-time streaming.

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/tree/main/fal_demos/video/yolo_webcam_webrtc).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate:

```bash theme={null}
fal auth login
```

3. Clone the demos repo and install dependencies:

```bash theme={null}
git clone https://github.com/fal-ai-community/fal-demos.git
cd fal-demos
pip install -e .
```

4. Run the backend (local dev):

```bash theme={null}
fal run fal_demos/video/yolo_webcam_webrtc/yolo.py::WebcamWebRtc
```

5. Run the frontend:

```bash theme={null}
cd fal_demos/video/yolo_webcam_webrtc/frontend
npm install
FAL_KEY=myfalkey npm run dev
```

Open the Vite dev server in your browser and set the **Endpoint** field to the
full real-time endpoint (for example: `myuser/myapp/webrtc`).

<Tip>
  This deployment flow is the same as other serverless examples, like [Deploy Text-to-Image Model](/examples/image-generation/deploy-text-to-image-model), but the request path is a real-time endpoint.
</Tip>

## Deploy to fal

To host the backend, deploy the app and use the resulting endpoint in the UI:

```bash theme={null}
fal deploy fal_demos/video/yolo_webcam_webrtc/yolo.py::WebcamWebRtc
```

The real-time endpoint will be `your-username/your-app/webrtc`.

## How it works

* The browser streams your webcam to the app in real-time (WebRTC transport).
* The backend runs YOLO on each frame and draws detection boxes.
* The annotated stream is sent back to the browser over the same connection.


# https://fal.ai/docs/examples/video-generation/deploy-realtime-world-model.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Real-time World Model

> Run a real-time world model demo powered by Matrix-Game.

This example streams a live world model with Matrix-Game. WebRTC is the
transport layer for low-latency, real-time video streaming.

<div style={{ display: 'flex', justifyContent: 'center', gap: '16px', marginTop: '24px', marginBottom: '24px' }}>
  <video autoPlay loop muted playsInline controls style={{ borderRadius: '8px', maxWidth: '60%' }}>
    <source src="https://storage.googleapis.com/falserverless/example_inputs/webRTCMatrix.mp4" type="video/mp4" />
  </video>
</div>

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/tree/main/fal_demos/video/matrix_webrtc).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate:

```bash theme={null}
fal auth login
```

3. Clone the demos repo and install dependencies:

```bash theme={null}
git clone https://github.com/fal-ai-community/fal-demos.git
cd fal-demos
pip install -e .
```

4. Run the backend (local dev):

```bash theme={null}
fal run fal_demos/video/matrix_webrtc/matrix.py::MatrixGame2
```

5. Run the frontend:

```bash theme={null}
cd fal_demos/video/matrix_webrtc/frontend
npm install
FAL_KEY=myfalkey npm run dev
```

Open the Vite dev server in your browser and set the **Endpoint** field to the
full real-time endpoint (for example: `myuser/myapp/webrtc`).

<Tip>
  This deployment flow is the same as other serverless examples, like [Deploy Text-to-Image Model](/examples/image-generation/deploy-text-to-image-model), but the request path is a real-time endpoint.
</Tip>

## Deploy to fal

To host the backend, deploy the app and use the resulting endpoint in the UI:

```bash theme={null}
fal deploy fal_demos/video/matrix_webrtc/matrix.py::MatrixGame2
```

The real-time endpoint will be `your-username/your-app/webrtc`.

## Game modes and seed image

The backend defaults to the `universal` mode in `MatrixGame2.setup()`. Other
supported modes include `universal` and `gta_drive`. To switch modes, update
`self._default_mode` and `self._mode_seed_dirs` in `matrix.py`.

The seed image path is derived in `MatrixGame2.setup()` from the selected mode.
If you want a different seed, update `self._default_seed_path` in `matrix.py`.


# https://fal.ai/docs/examples/video-generation/deploy-text-to-video-model.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a Text-to-Video Model

> This example demonstrates how to build a sophisticated text-to-video generation service using Wan2.1, showcasing advanced techniques including custom safety checking with multiple AI models, prompt expansion using LLMs, video tensor processing, and comprehensive integration of multiple fal services within a single application.

## 🚀 Try this Example

View the complete source code on [GitHub](https://github.com/fal-ai-community/fal-demos/blob/main/fal_demos/video/wan.py).

**Steps to run:**

1. Install fal:

```bash theme={null}
pip install fal
```

2. Authenticate (if not already done):

```bash theme={null}
fal auth login
```

3. Copy the code below into `wan.py`

<CodeGroup>
  ```python wan.py wrap theme={null}
  import os
  import random
  import tempfile
  from typing import Literal

  import fal
  from fal.exceptions import FieldException
  from fal.toolkit import FAL_MODEL_WEIGHTS_DIR, File, clone_repository
  from pydantic import BaseModel, Field


  class WanT2VRequest(BaseModel):
      prompt: str = Field(
          description="The text prompt to guide video generation.",
          examples=[
              "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage."
          ],
      )
      negative_prompt: str = Field(
          default="",
          description="""
              The negative prompt to use. Use it to address details that you don't want
              in the image. This could be colors, objects, scenery and even the small
              details (e.g. moustache, blurry, low resolution).
          """,
          examples=[
              "",
          ],
      )
      seed: int | None = Field(
          default=None,
          description="Random seed for reproducibility. If None, a random seed is chosen.",
      )
      aspect_ratio: Literal["9:16", "16:9"] = Field(
          default="16:9",
          description="Aspect ratio of the generated video (16:9 or 9:16).",
      )
      num_inference_steps: int = Field(
          default=30,
          description="Number of inference steps for sampling. Higher values give better quality but take longer.",
          ge=2,
          le=40,
      )
      inference_steps: int = Field(
          default=30,
          description="Number of inference steps for sampling. Higher values give better quality but take longer.",
          ge=2,
          le=40,
      )
      guidance_scale: float = Field(
          default=5.0,
          description="Classifier-free guidance scale. Controls prompt adherence vs. creativity",
          ge=0.0,
          le=20.0,
          title="Guidance scale (CFG)",
      )
      shift: float = Field(
          default=5.0,
          description="Noise schedule shift parameter. Affects temporal dynamics.",
          ge=0.0,
          le=10.0,
      )
      sampler: Literal["unipc", "dpm++"] = Field(
          default="unipc",
          description="The sampler to use for generation.",
      )
      enable_safety_checker: bool = Field(
          default=False,
          examples=[True],
          description="If set to true, the safety checker will be enabled.",
      )
      enable_prompt_expansion: bool = Field(
          default=False,
          examples=[False],
          description="Whether to enable prompt expansion.",
      )


  class WanT2VResponse(BaseModel):
      video: File = Field(
          description="The generated video file.",
          examples=[
              File._from_url(
                  "https://v3.fal.media/files/monkey/kqYTedbmW3W58-J_fsTIo_tmpbb3f9orp.mp4"
              )
          ],
      )
      seed: int = Field(description="The seed used for generation.")


  class Wan(fal.App):
      app_name = "wan"
      min_concurrency = 0
      max_concurrency = 1
      keep_alive = 300
      machine_type = "GPU-H100"
      requirements = [
          "torch==2.6.0",
          "torchvision==0.21.0",
          "opencv-python>=4.9.0.80",
          "diffusers==0.32.2",
          "transformers==4.49.0",
          "tokenizers==0.21.0",
          "accelerate==1.4.0",
          "tqdm",
          "imageio",
          "easydict",
          "ftfy",
          "dashscope",
          "imageio-ffmpeg",
          "https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.0.post1/flash_attn-2.7.0.post1+cu12torch2.5cxx11abiFALSE-cp311-cp311-linux_x86_64.whl",
          "numpy==1.24.4",
          "xfuser==0.4.1",
          "fal-client",
      ]

      def setup(self):
          """Initialize the app by cloning the repository, downloading models, and starting the server."""
          from pathlib import Path

          from huggingface_hub import snapshot_download

          # Clone the Wan Repository, make sure to pin the commit hash to avoid breaking changes
          # using a temporary directory ensures that there are fewer clashes with other workers while starting up
          target_dir = clone_repository(
              "https://github.com/Wan-Video/Wan2.1.git",
              commit_hash="6797c48002e977f2bc98ec4da1930f4cd46181a6",
              target_dir="/tmp",
              include_to_path=True,
              repo_name="wan-t2v",
          )
          os.chdir(target_dir)

          # Download model weights with HF transfer enabled
          os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
          checkpoint_dir = Path(
              snapshot_download(
                  "Wan-AI/Wan2.1-T2V-1.3B",
                  local_dir=FAL_MODEL_WEIGHTS_DIR / "wan_t2v_1.3B_480p",
                  local_dir_use_symlinks=True,
                  local_files_only=False,
              )
          )

          import wan
          from wan.configs import WAN_CONFIGS

          self.cfg = WAN_CONFIGS["t2v-1.3B"]

          self.wan_t2v = wan.WanT2V(
              config=self.cfg,
              checkpoint_dir=checkpoint_dir,
              device_id=0,
              rank=0,
              t5_fsdp=False,
              dit_fsdp=False,
              use_usp=False,
              t5_cpu=False,
          )

          self.RESOLUTIONS = {
              "480p": {
                  "16:9": (832, 480),
                  "9:16": (480, 832),
              }
          }

      # Custom NSFW checkers with any-llm
      def _is_nsfw_prompt(self, prompt: str) -> bool:
          import fal_client

          try:
              response = fal_client.subscribe(
                  "fal-ai/any-llm",
                  {
                      "prompt": prompt,
                      "system_prompt": 'With just a single word of "yes" or "no" tell me the given user prompt contains any not safe for work material. Don\'t say anything other than yes or no. If the prompt contains unsafe material, say yes, otherwise say no.',
                      "model": "google/gemini-flash-1.5",
                  },
              )
          except Exception:
              return True
          else:
              return "yes" in response["output"].lower()

      # Better nsfw check to ensure tighter safety
      def _is_nsfw_request(self, image: str) -> bool:
          import fal_client

          try:
              image_url = fal_client.upload_image(image)
              response = fal_client.subscribe(
                  "fal-ai/imageutils/nsfw", {"image_url": image_url}
              )
          except Exception:
              return True
          else:
              if response["nsfw_probability"] >= 0.3:
                  return True

          # Secondary check
          try:
              response = fal_client.subscribe(
                  "fal-ai/any-llm/vision",
                  {
                      "prompt": 'With just a single word of "yes" or "no" tell me the given user image contains any not safe for work material. Don\'t say anything other than yes or no. If the image contains unsafe material, say yes, otherwise say no.',
                      "image_url": image_url,
                      "model": "google/gemini-flash-1.5",
                  },
              )
          except Exception:
              return True
          else:
              return "yes" in response["output"]

      # Prompt expansion using any-llm
      def _expand_prompt(self, prompt: str) -> str:
          import fal_client

          try:
              response = fal_client.run(
                  "fal-ai/any-llm",
                  arguments={
                      "model": "google/gemini-flash-1.5",
                      "prompt": prompt,
                      "system_prompt": 'Take the user\'s input prompt and enhance it by focusing on a single, central subject to create a coherent and impactful result. Structure the description from coarse to fine details, starting with broad elements and zooming into specific textures, colors, and finer characteristics. If relevant, include close-up and medium shots to describe both intimate details and the surrounding context, ensuring clarity in depth and framing. Append "high resolution 4k" at the end to reduce warping and ensure the highest level of detail. Specify vivid colors, rich textures, and appropriate moods to enhance the overall visual quality and cohesion of the output. Maximum output 200 tokens.',
                  },
                  timeout=10,
              )

          except Exception:
              import traceback

              traceback.print_exc()
              prompt = prompt
          else:
              prompt = response["output"] or prompt
          return prompt

      # Specify the endpoint path to ensure that it is clearly distinguishable from the other variants of the model
      @fal.endpoint("/v2.1/1.3b/text-to-video")
      def generate_image_to_video(self, request: WanT2VRequest) -> WanT2VResponse:
          """WAN 1.3B model for fast text-to-video generation."""

          if request.enable_safety_checker and self._is_nsfw_prompt(request.prompt):
              raise FieldException("prompt", "NSFW content detected in the prompt.")

          if request.enable_prompt_expansion:
              prompt = self._expand_prompt(request.prompt)
          else:
              prompt = request.prompt

          seed = request.seed or random.randint(0, 1000000)
          size = self.RESOLUTIONS["480p"][request.aspect_ratio]
          from wan.utils.utils import cache_video

          video = self.wan_t2v.generate(
              input_prompt=prompt,
              size=size,
              frame_num=81,
              n_prompt=request.negative_prompt,
              shift=request.shift,
              sample_solver=request.sampler,
              sampling_steps=request.inference_steps,
              guide_scale=request.guidance_scale,
              seed=seed,
              offload_model=False,
          )
          # Save the video to a temporary file
          with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as f:
              save_path = f.name
              cache_video(
                  tensor=video[None],
                  save_file=save_path,
                  fps=self.cfg.sample_fps,
                  nrow=1,
                  normalize=True,
                  value_range=(-1, 1),
              )

              return WanT2VResponse(video=File.from_path(save_path), seed=seed)
  ```

  ```toml pyproject.toml wrap theme={null}
  [project]
  name = "wan-demo"
  version = "0.1.0"
  description = "Wan text-to-video generation demo"
  requires-python = ">=3.11"
  dependencies = [
      "pydantic>=2.0",
      "fal @ git+https://github.com/fal-ai/fal.git#subdirectory=projects/fal"
  ]

  [tool.fal.apps]
  wan = { auth = "shared", ref = "wan.py::Wan", no_scale=true }
  ```
</CodeGroup>

4. Run the app:

```bash theme={null}
fal run wan.py
```

<Info>
  **Or clone this repository**:

  ```bash theme={null}
  git clone https://github.com/fal-ai-community/fal-demos.git
  cd fal-demos
  pip install -e .
  # Use the app name (defined in pyproject.toml)
  fal run wan
  # Or use the full file path:
  # fal run fal_demos/video/wan.py::Wan
  ```
</Info>

<Tip>
  **Before you run**, make sure you have:

  * Authenticated with fal: `fal auth login`
  * Activated your virtual environment (recommended): `python -m venv venv && source venv/bin/activate` (macOS/Linux) or `venv\Scripts\activate` (Windows)
</Tip>

## Key Features

* **Advanced Video Generation**: High-quality text-to-video with Wan2.1 model
* **Multi-Model Safety Checking**: Text and image NSFW detection using multiple AI models
* **AI-Powered Prompt Expansion**: Enhance prompts using LLM services
* **Model Weight Management**: Efficient downloading and caching of large model weights
* **Service Integration**: Seamless integration of multiple fal AI services
* **Advanced Dependencies**: Complex wheel installations and GPU optimizations

## When to Use Service Integration

Service integration within fal apps is powerful for:

* **Multi-stage AI pipelines**: Combining multiple AI models in sequence
* **Safety and moderation**: Adding content filtering with specialized models
* **Content enhancement**: Using LLMs to improve or expand inputs
* **Quality assurance**: Multi-model validation and checking

## Project Setup

```python theme={null}
import os
import random
import tempfile
from typing import Literal

import fal
from fal.exceptions import FieldException
from fal.toolkit import FAL_MODEL_WEIGHTS_DIR, File, clone_repository
from pydantic import BaseModel, Field
```

## Comprehensive Input Model

Define detailed input schemas with professional validation:

```python theme={null}
class WanT2VRequest(BaseModel):
    prompt: str = Field(
        description="The text prompt to guide video generation.",
        examples=[
            "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage."
        ],
    )
    negative_prompt: str = Field(
        default="",
        description="""
            The negative prompt to use. Use it to address details that you don't want
            in the image. This could be colors, objects, scenery and even the small
            details (e.g. moustache, blurry, low resolution).
        """,
        examples=[""],
    )
    seed: int | None = Field(
        default=None,
        description="Random seed for reproducibility. If None, a random seed is chosen.",
    )
    aspect_ratio: Literal["9:16", "16:9"] = Field(
        default="16:9",
        description="Aspect ratio of the generated video (16:9 or 9:16).",
    )
    num_inference_steps: int = Field(
        default=30,
        description="Number of inference steps for sampling. Higher values give better quality but take longer.",
        ge=2,
        le=40,
    )
    inference_steps: int = Field(
        default=30,
        description="Number of inference steps for sampling. Higher values give better quality but take longer.",
        ge=2,
        le=40,
    )
    guidance_scale: float = Field(
        default=5.0,
        description="Classifier-free guidance scale. Controls prompt adherence vs. creativity",
        ge=0.0,
        le=20.0,
        title="Guidance scale (CFG)",
    )
    shift: float = Field(
        default=5.0,
        description="Noise schedule shift parameter. Affects temporal dynamics.",
        ge=0.0,
        le=10.0,
    )
    sampler: Literal["unipc", "dpm++"] = Field(
        default="unipc",
        description="The sampler to use for generation.",
    )
    enable_safety_checker: bool = Field(
        default=False,
        examples=[True],
        description="If set to true, the safety checker will be enabled.",
    )
    enable_prompt_expansion: bool = Field(
        default=False,
        examples=[False],
        description="Whether to enable prompt expansion.",
    )

class WanT2VResponse(BaseModel):
    video: File = Field(
        description="The generated video file.",
        examples=[
            File._from_url(
                "https://v3.fal.media/files/monkey/kqYTedbmW3W58-J_fsTIo_tmpbb3f9orp.mp4"
            )
        ],
    )
    seed: int = Field(description="The seed used for generation.")
```

## Application Configuration with Advanced Dependencies

```python theme={null}
class Wan(fal.App):
    app_name = "wan"
    min_concurrency = 0
    max_concurrency = 1
    keep_alive = 300
    machine_type = "GPU-H100"  # High-end GPU for video generation
    requirements = [
        "torch==2.6.0",
        "torchvision==0.21.0",
        "opencv-python>=4.9.0.80",
        "diffusers==0.32.2",
        "transformers==4.49.0",
        "tokenizers==0.21.0",
        "accelerate==1.4.0",
        "tqdm",
        "imageio",
        "easydict",
        "ftfy",
        "dashscope",
        "imageio-ffmpeg",
        # Custom wheel installation for optimized performance
        "https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.0.post1/flash_attn-2.7.0.post1+cu12torch2.5cxx11abiFALSE-cp311-cp311-linux_x86_64.whl",
        "numpy==1.24.4",
        "xfuser==0.4.1",
        "fal-client",  # For service integration
    ]
```

## Advanced Model Setup

The setup method demonstrates complex initialization workflows:

```python theme={null}
def setup(self):
    """Initialize the app by cloning the repository, downloading models, and starting the server."""
    from pathlib import Path
    from huggingface_hub import snapshot_download

    # Clone repository with commit pinning
    target_dir = clone_repository(
        "https://github.com/Wan-Video/Wan2.1.git",
        commit_hash="6797c48002e977f2bc98ec4da1930f4cd46181a6",
        target_dir="/tmp",  # Use temp directory to avoid conflicts
        include_to_path=True,
        repo_name="wan-t2v",
    )
    os.chdir(target_dir)

    # Enable HuggingFace transfer optimization
    os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"

    # Download model weights to managed directory
    checkpoint_dir = Path(
        snapshot_download(
            "Wan-AI/Wan2.1-T2V-1.3B",
            local_dir=FAL_MODEL_WEIGHTS_DIR / "wan_t2v_1.3B_480p",
            local_dir_use_symlinks=True,  # Efficient storage
            local_files_only=False,
        )
    )

    # Initialize the model
    import wan
    from wan.configs import WAN_CONFIGS

    self.cfg = WAN_CONFIGS["t2v-1.3B"]
    self.wan_t2v = wan.WanT2V(
        config=self.cfg,
        checkpoint_dir=checkpoint_dir,
        device_id=0,
        rank=0,
        t5_fsdp=False,
        dit_fsdp=False,
        use_usp=False,
        t5_cpu=False,
    )

    # Define supported resolutions
    self.RESOLUTIONS = {
        "480p": {
            "16:9": (832, 480),
            "9:16": (480, 832),
        }
    }
```

## Custom Safety Checking with AI Services

Implement multi-layered safety checking using different AI models:

```python theme={null}
def _is_nsfw_prompt(self, prompt: str) -> bool:
    """Check if text prompt contains NSFW content using LLM."""
    import fal_client

    try:
        response = fal_client.subscribe(
            "fal-ai/any-llm",
            {
                "prompt": prompt,
                "system_prompt": 'With just a single word of "yes" or "no" tell me the given user prompt contains any not safe for work material. Don\'t say anything other than yes or no. If the prompt contains unsafe material, say yes, otherwise say no.',
                "model": "google/gemini-flash-1.5",
            },
        )
    except Exception:
        return True  # Err on the side of caution
    else:
        return "yes" in response["output"].lower()

def _is_nsfw_request(self, image: str) -> bool:
    """Multi-stage image NSFW detection."""
    import fal_client

    try:
        # Upload image for analysis
        image_url = fal_client.upload_image(image)

        # Primary check with specialized NSFW detector
        response = fal_client.subscribe(
            "fal-ai/imageutils/nsfw",
            {"image_url": image_url}
        )
    except Exception:
        return True
    else:
        if response["nsfw_probability"] >= 0.3:
            return True

    # Secondary check with vision LLM
    try:
        response = fal_client.subscribe(
            "fal-ai/any-llm/vision",
            {
                "prompt": 'With just a single word of "yes" or "no" tell me the given user image contains any not safe for work material. Don\'t say anything other than yes or no. If the image contains unsafe material, say yes, otherwise say no.',
                "image_url": image_url,
                "model": "google/gemini-flash-1.5",
            },
        )
    except Exception:
        return True
    else:
        return "yes" in response["output"]
```

## AI-Powered Prompt Expansion

Enhance user prompts using LLM services:

```python theme={null}
def _expand_prompt(self, prompt: str) -> str:
    """Expand and enhance prompts using LLM for better video generation."""
    import fal_client

    try:
        response = fal_client.run(
            "fal-ai/any-llm",
            arguments={
                "model": "google/gemini-flash-1.5",
                "prompt": prompt,
                "system_prompt": 'Take the user\'s input prompt and enhance it by focusing on a single, central subject to create a coherent and impactful result. Structure the description from coarse to fine details, starting with broad elements and zooming into specific textures, colors, and finer characteristics. If relevant, include close-up and medium shots to describe both intimate details and the surrounding context, ensuring clarity in depth and framing. Append "high resolution 4k" at the end to reduce warping and ensure the highest level of detail. Specify vivid colors, rich textures, and appropriate moods to enhance the overall visual quality and cohesion of the output. Maximum output 200 tokens.',
            },
            timeout=10,
        )
    except Exception:
        import traceback
        traceback.print_exc()
        return prompt  # Return original if expansion fails
    else:
        return response["output"] or prompt
```

## Professional API Endpoint with Versioning

```python theme={null}
@fal.endpoint("/v2.1/1.3b/text-to-video")
def generate_image_to_video(self, request: WanT2VRequest) -> WanT2VResponse:
    """WAN 1.3B model for fast text-to-video generation."""

    # Safety checking
    if request.enable_safety_checker and self._is_nsfw_prompt(request.prompt):
        raise FieldException("prompt", "NSFW content detected in the prompt.")

    # Prompt enhancement
    if request.enable_prompt_expansion:
        prompt = self._expand_prompt(request.prompt)
    else:
        prompt = request.prompt

    # Generate deterministic or random seed
    seed = request.seed or random.randint(0, 1000000)
    size = self.RESOLUTIONS["480p"][request.aspect_ratio]

    # Import video utilities
    from wan.utils.utils import cache_video

    # Generate video
    video = self.wan_t2v.generate(
        input_prompt=prompt,
        size=size,
        frame_num=81,  # ~2.7 seconds at 30fps
        n_prompt=request.negative_prompt,
        shift=request.shift,
        sample_solver=request.sampler,
        sampling_steps=request.inference_steps,
        guide_scale=request.guidance_scale,
        seed=seed,
        offload_model=False,
    )

    # Save video to temporary file
    with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as f:
        save_path = f.name
        cache_video(
            tensor=video[None],  # Add batch dimension
            save_file=save_path,
            fps=self.cfg.sample_fps,
            nrow=1,
            normalize=True,
            value_range=(-1, 1),
        )

        return WanT2VResponse(
            video=File.from_path(save_path),
            seed=seed
        )
```

## Key Concepts and Best Practices

### Service Integration Patterns

**Text Analysis with LLMs:**

```python theme={null}
response = fal_client.subscribe(
    "fal-ai/any-llm",
    {
        "prompt": user_prompt,
        "system_prompt": "Your analysis instructions...",
        "model": "google/gemini-flash-1.5",
    },
)
```

**Image Analysis:**

```python theme={null}
image_url = fal_client.upload_image(image)
response = fal_client.subscribe(
    "fal-ai/imageutils/nsfw",
    {"image_url": image_url}
)
```

**Vision-Language Models:**

```python theme={null}
response = fal_client.subscribe(
    "fal-ai/any-llm/vision",
    {
        "prompt": "Analysis prompt...",
        "image_url": image_url,
        "model": "google/gemini-flash-1.5",
    },
)
```

### Model Weight Management

```python theme={null}
# Use FAL_MODEL_WEIGHTS_DIR for managed storage
checkpoint_dir = Path(
    snapshot_download(
        "Wan-AI/Wan2.1-T2V-1.3B",
        local_dir=FAL_MODEL_WEIGHTS_DIR / "wan_t2v_1.3B_480p",
        local_dir_use_symlinks=True,  # Efficient storage
        local_files_only=False,
    )
)
```

### Video Processing Pipeline

```python theme={null}
# Generate video tensor
video = model.generate(...)

# Convert tensor to video file
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as f:
    cache_video(
        tensor=video[None],  # Add batch dimension
        save_file=f.name,
        fps=cfg.sample_fps,
        normalize=True,
        value_range=(-1, 1),
    )
    return Response(video=File.from_path(f.name))
```

### Error Handling in Service Integration

```python theme={null}
try:
    response = fal_client.subscribe("service-name", arguments)
except Exception:
    # Handle gracefully - don't break the main workflow
    return default_behavior()
else:
    return process_response(response)
```

### Advanced Dependencies

```python theme={null}
requirements = [
    # Custom wheel for optimized performance
    "https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.0.post1/flash_attn-2.7.0.post1+cu12torch2.5cxx11abiFALSE-cp311-cp311-linux_x86_64.whl",
    # Other dependencies...
]
```

## Deployment and Usage

### Running the Service

```bash theme={null}
# Development
fal run fal_demos/video/wan.py::Wan

# Production deployment
fal deploy wan
```

### Making Requests

```python theme={null}
import fal_client

result = await fal_client.submit_async(
    "your-username/wan/v2.1/1.3b/text-to-video",
    arguments={
        "prompt": "A cat walking through a futuristic city",
        "aspect_ratio": "16:9",
        "num_inference_steps": 30,
        "enable_safety_checker": True,
        "enable_prompt_expansion": True,
        "seed": 42
    }
)

# The response includes the video file and seed
video_url = result["video"]["url"]  # Ready to embed in web players
seed_used = result["seed"]
```

## Advanced Features Demonstrated

1. **Multi-Model Workflows**: Combining text analysis, image analysis, and video generation
2. **Content Moderation**: Multi-layered safety checking with different AI models
3. **Dynamic Prompt Enhancement**: AI-powered prompt expansion for better results
4. **Efficient Resource Management**: Model weight caching and memory optimization
5. **Service Orchestration**: Seamless integration of multiple fal services

## Performance Optimizations

### Memory Management

```python theme={null}
offload_model=False  # Keep model in VRAM for better performance
use_usp=False       # Optimize for single-user scenarios
```

### Storage Efficiency

```python theme={null}
local_dir_use_symlinks=True  # Avoid duplicate model weights
FAL_MODEL_WEIGHTS_DIR       # Use managed storage location
```

## Key Takeaways

* **Service integration** enables sophisticated AI workflows within single applications
* **Multi-model safety checking** provides robust content moderation
* **AI-powered enhancement** can significantly improve user inputs
* **Resource management** is crucial for large model deployments
* **Error handling** in service integration must be graceful and not break main workflows

This pattern demonstrates how to build enterprise-grade AI services that combine multiple AI models, advanced safety features, and professional API design while maintaining the scalability and ease of deployment that fal provides. It represents the pinnacle of what's possible when combining all the techniques we've learned across the previous examples.


# https://fal.ai/docs/examples/video-generation/generate-videos-from-image.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate Videos from Image Tutorial

## How to Generate Videos using the fal API

fal offers a simple and easy-to-use API that allows you to generate videos from your images using pre-trained models. This endpoint is perfect for creating video clips from your images for various use cases such as social media, marketing, and more.

Here is an example of how to generate videos using the fal API:

```js theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/minimax-video/image-to-video", {
  input: {
    prompt: "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage.",
    image_url: "https://fal.media/files/elephant/8kkhB12hEZI2kkbU8pZPA_test.jpeg"
  },
});
```

## How to select the model to use

fal offers a variety of video generation models. You can select the model that best fits your needs based on the style and quality of the images you want to generate. Here are some of the available models:

* [fal-ai/minimax-video](https://fal.ai/models/fal-ai/minimax-video/image-to-video): Generate video clips from your images using MiniMax Video model.
* [fal-ai/luma-dream-machine](https://fal.ai/models/fal-ai/luma-dream-machine/image-to-video): Generate video clips from your images using Luma Dream Machine v1.5
* [fal-ai/kling-video/v1/standard](https://fal.ai/models/fal-ai/kling-video/v1/standard/image-to-video): Generate video clips from your images using Kling 1.0

To select a model, simply specify the model ID in the subscribe method as shown in the example above. You can find more models and their descriptions in the [Image to Video Models](https://fal.ai/models?categories=image-to-video) page.


# https://fal.ai/docs/model-api-reference/3d-api/hunyuan-3d-v3.1-part.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hunyuan 3d V3.1 Part API

> API reference for Hunyuan 3d V3.1 Part. Split 3D models into parts with Hunyuan 3D

**Endpoint:** `POST https://fal.run/fal-ai/hunyuan-3d/v3.1/part`
**Endpoint ID:** `fal-ai/hunyuan-3d/v3.1/part`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/hunyuan-3d/v3.1/part/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/hunyuan-3d/v3.1/part",
      arguments={
          "input_file_url": "https://v3b.fal.media/files/b/0a8bf92a/XECcItG5QHt0LViFTRCON_converted.fbx"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/hunyuan-3d/v3.1/part", {
    input: {
        input_file_url: "https://v3b.fal.media/files/b/0a8bf92a/XECcItG5QHt0LViFTRCON_converted.fbx"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/hunyuan-3d/v3.1/part \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "input_file_url": "https://v3b.fal.media/files/b/0a8bf92a/XECcItG5QHt0LViFTRCON_converted.fbx"
  }'
  ```
</CodeGroup>

## Related

* [Hunyuan 3D Pro Image to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-image-to-3d) — 3D
* [Hunyuan 3D Pro Text to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-text-to-3d) — 3D
* [Hunyuan 3D Rapid Image to 3D](/model-api-reference/3d-api/hunyuan-3d-rapid-image-to-3d) — 3D
* [Hunyuan 3d](/model-api-reference/3d-api/hunyuan-3d) — 3D
* [Hunyuan 3D Smart Topology](/model-api-reference/3d-api/hunyuan-3d-smart-topology) — 3D

## API Reference

### Input Schema

<ParamField body="input_file_url" type="string" required>
  URL of FBX file to split into parts. ONLY FBX format supported. Max size: 100MB, face count ≤30,000. Recommended: AIGC-generated models.
</ParamField>

### Output Schema

<ParamField body="result_files" type="list<File>" required>
  List of generated part files in FBX format
</ParamField>

## Input Example

```json theme={null}
{
  "input_file_url": "https://v3b.fal.media/files/b/0a8bf92a/XECcItG5QHt0LViFTRCON_converted.fbx"
}
```

## Output Example

```json theme={null}
{
  "result_files": [
    {
      "content_type": "application/octet-stream",
      "file_name": "part_0.fbx",
      "file_size": 2048000,
      "url": "https://v3b.fal.media/files/b/0a8bf94b/zOP--lT23slziGKp99dJm_part_0.fbx"
    }
  ]
}
```


# https://fal.ai/docs/model-api-reference/3d-api/hunyuan-3d-v3.1-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hunyuan 3d V3.1 Pro API

> API reference for Hunyuan 3d V3.1 Pro. Generate 3D models from images with Hunyuan 3D Pro

<Tabs>
  <Tab title="Image To 3d">
    **Endpoint:** `POST https://fal.run/fal-ai/hunyuan-3d/v3.1/pro/image-to-3d`
    **Endpoint ID:** `fal-ai/hunyuan-3d/v3.1/pro/image-to-3d`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/hunyuan-3d/v3.1/pro/image-to-3d/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/hunyuan-3d/v3.1/pro/image-to-3d",
          arguments={
              "input_image_url": "https://v3b.fal.media/files/b/0a8c3155/BTXNRrzOFsO6OvdSxdXmv_6ZcaGmrY.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/hunyuan-3d/v3.1/pro/image-to-3d", {
        input: {
            input_image_url: "https://v3b.fal.media/files/b/0a8c3155/BTXNRrzOFsO6OvdSxdXmv_6ZcaGmrY.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/hunyuan-3d/v3.1/pro/image-to-3d \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "input_image_url": "https://v3b.fal.media/files/b/0a8c3155/BTXNRrzOFsO6OvdSxdXmv_6ZcaGmrY.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="input_image_url" type="string" required>
      Front view image URL. Resolution: 128-5000px, max 8MB, formats: JPG/PNG/WEBP. Tips: simple background, single object, object >50% of frame.
    </ParamField>

    <ParamField body="back_image_url" type="string">
      Optional back/rear view image URL (JPG/PNG recommended).
    </ParamField>

    <ParamField body="left_image_url" type="string">
      Optional left side view image URL (JPG/PNG recommended).
    </ParamField>

    <ParamField body="right_image_url" type="string">
      Optional right side view image URL (JPG/PNG recommended).
    </ParamField>

    <ParamField body="top_image_url" type="string">
      Optional top view image URL (v3.1 exclusive, JPG/PNG recommended).
    </ParamField>

    <ParamField body="bottom_image_url" type="string">
      Optional bottom view image URL (v3.1 exclusive, JPG/PNG recommended).
    </ParamField>

    <ParamField body="left_front_image_url" type="string">
      Optional left-front 45 degree angle view image URL (v3.1 exclusive, JPG/PNG recommended).
    </ParamField>

    <ParamField body="right_front_image_url" type="string">
      Optional right-front 45 degree angle view image URL (v3.1 exclusive, JPG/PNG recommended).
    </ParamField>

    <ParamField body="generate_type" type="GenerateTypeEnum" default="Normal">
      Generation task type. Normal: textured model. Geometry: geometry-only white model (no textures). LowPoly/Sketch are not available in v3.1. Default value: `"Normal"`

      Possible values: `Normal`, `Geometry`
    </ParamField>

    <ParamField body="enable_pbr" type="boolean" default="false">
      Enable PBR material generation (metallic, roughness, normal textures). Ignored when generate\_type is Geometry.
    </ParamField>

    <ParamField body="face_count" type="integer" default="500000">
      Target polygon face count. Range: 40,000-1,500,000. Default: 500,000. Default value: `500000`

      Range: `40000` to `1500000`
    </ParamField>

    ### Output Schema

    <ParamField body="model_glb" type="File" required>
      Generated 3D object in GLB format.
    </ParamField>

    <ParamField body="thumbnail" type="File">
      Preview thumbnail of the generated model
    </ParamField>

    <ParamField body="model_urls" type="ModelUrls" required>
      URLs for different 3D model formats
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "input_image_url": "https://v3b.fal.media/files/b/0a8c3155/BTXNRrzOFsO6OvdSxdXmv_6ZcaGmrY.png",
      "generate_type": "Normal",
      "enable_pbr": false,
      "face_count": 500000
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "model_glb": {
        "content_type": "model/gltf-binary",
        "file_name": "model.glb",
        "file_size": 38554640,
        "url": "https://v3b.fal.media/files/b/0a8c3187/jOeZmtBuhdQMkDu65AkdT_model.glb"
      },
      "thumbnail": {
        "content_type": "image/png",
        "file_name": "preview.png",
        "file_size": 194908,
        "url": "https://v3b.fal.media/files/b/0a8c3187/gxidaODj4OvPXruCfrZ-__preview.png"
      },
      "model_urls": {
        "glb": {
          "content_type": "model/gltf-binary",
          "file_name": "model.glb",
          "file_size": 38554640,
          "url": "https://v3b.fal.media/files/b/0a8c3187/jOeZmtBuhdQMkDu65AkdT_model.glb"
        },
        "obj": {
          "content_type": "model/obj",
          "file_name": "model.obj",
          "file_size": 31447160,
          "url": "https://v3b.fal.media/files/b/0a8c3186/no-aBFEDnOuthILfv-wzs_model.obj"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Text To 3d">
    **Endpoint:** `POST https://fal.run/fal-ai/hunyuan-3d/v3.1/pro/text-to-3d`
    **Endpoint ID:** `fal-ai/hunyuan-3d/v3.1/pro/text-to-3d`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/hunyuan-3d/v3.1/pro/text-to-3d/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/hunyuan-3d/v3.1/pro/text-to-3d",
          arguments={
              "prompt": "A super cool space ship with details"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/hunyuan-3d/v3.1/pro/text-to-3d", {
        input: {
            prompt: "A super cool space ship with details"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/hunyuan-3d/v3.1/pro/text-to-3d \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A super cool space ship with details"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of the 3D content to generate. Max 1024 UTF-8 characters.
    </ParamField>

    <ParamField body="generate_type" type="GenerateTypeEnum" default="Normal">
      Generation task type. Normal: textured model. Geometry: geometry-only white model (no textures). LowPoly/Sketch are not available in v3.1. Default value: `"Normal"`

      Possible values: `Normal`, `Geometry`
    </ParamField>

    <ParamField body="enable_pbr" type="boolean" default="false">
      Enable PBR material generation (metallic, roughness, normal textures). Ignored when generate\_type is Geometry.
    </ParamField>

    <ParamField body="face_count" type="integer" default="500000">
      Target polygon face count. Range: 40,000-1,500,000. Default: 500,000. Default value: `500000`

      Range: `40000` to `1500000`
    </ParamField>

    ### Output Schema

    <ParamField body="model_glb" type="File" required>
      Generated 3D object in GLB format.
    </ParamField>

    <ParamField body="thumbnail" type="File">
      Preview thumbnail of the generated model
    </ParamField>

    <ParamField body="model_urls" type="ModelUrls" required>
      URLs for different 3D model formats
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A super cool space ship with details",
      "generate_type": "Normal",
      "enable_pbr": false,
      "face_count": 500000
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "model_glb": {
        "content_type": "model/gltf-binary",
        "file_name": "model.glb",
        "file_size": 35833072,
        "url": "https://v3b.fal.media/files/b/0a8c5483/z6sbpr5wBRjqgnQlJM2Ot_model.glb"
      },
      "thumbnail": {
        "content_type": "image/png",
        "file_name": "preview.png",
        "file_size": 68927,
        "url": "https://v3b.fal.media/files/b/0a8c5483/EE97ZV7cM-3UVG4peyWTQ_preview.png"
      },
      "model_urls": {
        "glb": {
          "content_type": "model/gltf-binary",
          "file_name": "model.glb",
          "file_size": 35833072,
          "url": "https://v3b.fal.media/files/b/0a8c5483/z6sbpr5wBRjqgnQlJM2Ot_model.glb"
        },
        "mtl": {
          "content_type": "text/plain",
          "file_name": "material.mtl",
          "file_size": 88,
          "url": "https://v3b.fal.media/files/b/0a8c5482/ZxJepsEkhM67VSugmZ7QT_material.mtl"
        },
        "obj": {
          "content_type": "model/obj",
          "file_name": "6168030a8817075aaa55c94cc5145000.obj",
          "file_size": 34755929,
          "url": "https://v3b.fal.media/files/b/0a8c5482/ZzC1xlOftyGQxhDkbZzVW_6168030a8817075aaa55c94cc5145000.obj"
        },
        "texture": {
          "content_type": "image/png",
          "file_name": "texture_20250901.png",
          "file_size": 19996580,
          "url": "https://v3b.fal.media/files/b/0a8c5482/jOL2nBpcOGspwxQf0_U-z_texture_20250901.png"
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Hunyuan 3D Pro Text to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-text-to-3d) — 3D
* [Hunyuan 3D Rapid Image to 3D](/model-api-reference/3d-api/hunyuan-3d-rapid-image-to-3d) — 3D
* [Hunyuan 3d](/model-api-reference/3d-api/hunyuan-3d) — 3D
* [Hunyuan 3D Smart Topology](/model-api-reference/3d-api/hunyuan-3d-smart-topology) — 3D
* [Hunyuan 3D Part Splitter](/model-api-reference/3d-api/hunyuan-3d-part-splitter) — 3D
* [Hunyuan 3D Pro Image to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-image-to-3d) — 3D

## Limitations

* `generate_type` restricted to: `Normal`, `Geometry`
* `face_count` range: 40000 to 1500000


# https://fal.ai/docs/model-api-reference/3d-api/hunyuan-3d-v3.1-rapid.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hunyuan 3d V3.1 Rapid API

> API reference for Hunyuan 3d V3.1 Rapid. Rapidly generate 3D models from images using Hunyuan 3D.

<Tabs>
  <Tab title="Image To 3d">
    **Endpoint:** `POST https://fal.run/fal-ai/hunyuan-3d/v3.1/rapid/image-to-3d`
    **Endpoint ID:** `fal-ai/hunyuan-3d/v3.1/rapid/image-to-3d`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/hunyuan-3d/v3.1/rapid/image-to-3d/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/hunyuan-3d/v3.1/rapid/image-to-3d",
          arguments={
              "input_image_url": "https://v3b.fal.media/files/b/0a865ab1/omYcawLUo4RZbO8J6ZgZR.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/hunyuan-3d/v3.1/rapid/image-to-3d", {
        input: {
            input_image_url: "https://v3b.fal.media/files/b/0a865ab1/omYcawLUo4RZbO8J6ZgZR.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/hunyuan-3d/v3.1/rapid/image-to-3d \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "input_image_url": "https://v3b.fal.media/files/b/0a865ab1/omYcawLUo4RZbO8J6ZgZR.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="input_image_url" type="string" required>
      Front view image URL. Resolution: 128-5000px, max 8MB (recommended ≤6MB for base64 encoding), formats: JPG/PNG/WEBP. Tips: simple background, single object, object >50% of frame.
    </ParamField>

    <ParamField body="enable_pbr" type="boolean" default="false">
      Enable PBR material generation (metallic, roughness, normal textures). Does not take effect when enable\_geometry is True.
    </ParamField>

    <ParamField body="enable_geometry" type="boolean" default="false">
      Generate geometry-only white model without textures. When enabled, enable\_pbr is ignored and OBJ is not supported (default output is GLB).
    </ParamField>

    ### Output Schema

    <ParamField body="model_glb" type="File">
      Generated 3D model file. Contains GLB if available, otherwise OBJ.
    </ParamField>

    <ParamField body="material_mtl" type="File">
      MTL material file for the OBJ model.
    </ParamField>

    <ParamField body="texture" type="File">
      Texture image for the 3D model.
    </ParamField>

    <ParamField body="thumbnail" type="File">
      Preview thumbnail of the generated model
    </ParamField>

    <ParamField body="model_urls" type="ModelUrls" required>
      URLs for different 3D model formats.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "input_image_url": "https://v3b.fal.media/files/b/0a865ab1/omYcawLUo4RZbO8J6ZgZR.png",
      "enable_pbr": false,
      "enable_geometry": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "model_glb": {
        "content_type": "model/obj",
        "file_name": "8b1dbea208d194b9089a950abc2df426.obj",
        "file_size": 3172659,
        "url": "https://v3b.fal.media/files/b/0a8c4439/vj933H8B4W3wbd3e2RNby_8b1dbea208d194b9089a950abc2df426.obj"
      },
      "material_mtl": {
        "content_type": "text/plain",
        "file_name": "material.mtl",
        "file_size": 88,
        "url": "https://v3b.fal.media/files/b/0a8c4439/_RhytNH4xZ5EFHr34YzJt_material.mtl"
      },
      "texture": {
        "content_type": "image/png",
        "file_name": "texture_20250901.png",
        "file_size": 11728567,
        "url": "https://v3b.fal.media/files/b/0a8c4439/_4NXiSoGcZ-GYwmgUTfHZ_texture_20250901.png"
      },
      "thumbnail": {
        "content_type": "image/png",
        "file_name": "preview.png",
        "file_size": 82521,
        "url": "https://v3b.fal.media/files/b/0a8c4439/70Sm1pZ16SQP-mEbaKICC_preview.png"
      },
      "model_urls": {
        "mtl": {
          "content_type": "text/plain",
          "file_name": "material.mtl",
          "file_size": 88,
          "url": "https://v3b.fal.media/files/b/0a8c4439/_RhytNH4xZ5EFHr34YzJt_material.mtl"
        },
        "obj": {
          "content_type": "model/obj",
          "file_name": "8b1dbea208d194b9089a950abc2df426.obj",
          "file_size": 3172659,
          "url": "https://v3b.fal.media/files/b/0a8c4439/vj933H8B4W3wbd3e2RNby_8b1dbea208d194b9089a950abc2df426.obj"
        },
        "texture": {
          "content_type": "image/png",
          "file_name": "texture_20250901.png",
          "file_size": 11728567,
          "url": "https://v3b.fal.media/files/b/0a8c4439/_4NXiSoGcZ-GYwmgUTfHZ_texture_20250901.png"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Text To 3d">
    **Endpoint:** `POST https://fal.run/fal-ai/hunyuan-3d/v3.1/rapid/text-to-3d`
    **Endpoint ID:** `fal-ai/hunyuan-3d/v3.1/rapid/text-to-3d`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/hunyuan-3d/v3.1/rapid/text-to-3d/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/hunyuan-3d/v3.1/rapid/text-to-3d",
          arguments={
              "prompt": "A rustic wooden treasure chest with metal bands and ornate lock"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/hunyuan-3d/v3.1/rapid/text-to-3d", {
        input: {
            prompt: "A rustic wooden treasure chest with metal bands and ornate lock"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/hunyuan-3d/v3.1/rapid/text-to-3d \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A rustic wooden treasure chest with metal bands and ornate lock"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of the 3D content to generate. Max 200 UTF-8 characters.
    </ParamField>

    <ParamField body="enable_pbr" type="boolean" default="false">
      Enable PBR material generation (metallic, roughness, normal textures). Does not take effect when enable\_geometry is True.
    </ParamField>

    <ParamField body="enable_geometry" type="boolean" default="false">
      Generate geometry-only white model without textures. When enabled, enable\_pbr is ignored and OBJ is not supported (default output is GLB).
    </ParamField>

    ### Output Schema

    <ParamField body="model_obj" type="File">
      Generated 3D model in OBJ format.
    </ParamField>

    <ParamField body="material_mtl" type="File">
      MTL material file for the OBJ model.
    </ParamField>

    <ParamField body="texture" type="File">
      Texture image for the 3D model.
    </ParamField>

    <ParamField body="thumbnail" type="File">
      Preview thumbnail of the generated model
    </ParamField>

    <ParamField body="model_urls" type="ModelUrls" required>
      URLs for different 3D model formats.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A rustic wooden treasure chest with metal bands and ornate lock",
      "enable_pbr": false,
      "enable_geometry": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "model_obj": {
        "content_type": "model/obj",
        "file_name": "0f7f7a1ac578c80d4397a7f2b69b40ff.obj",
        "file_size": 5306476,
        "url": "https://v3b.fal.media/files/b/0a8c44d5/2W2KRP1DM_-4qI8F_n05b_0f7f7a1ac578c80d4397a7f2b69b40ff.obj"
      },
      "material_mtl": {
        "content_type": "text/plain",
        "file_name": "material.mtl",
        "file_size": 157,
        "url": "https://v3b.fal.media/files/b/0a8c44d5/EHzTxJtHpdIliaMNnEke-_material.mtl"
      },
      "texture": {
        "content_type": "image/png",
        "file_name": "material.png",
        "file_size": 5915609,
        "url": "https://v3b.fal.media/files/b/0a8c44d5/T0q-P0aqXVG_y7jff-XTa_material.png"
      },
      "thumbnail": {
        "content_type": "image/png",
        "file_name": "preview.png",
        "file_size": 281374,
        "url": "https://v3b.fal.media/files/b/0a8c44d6/D9_IYgpugP0deXvSwBC2J_preview.png"
      },
      "model_urls": {
        "mtl": {
          "content_type": "text/plain",
          "file_name": "material.mtl",
          "file_size": 157,
          "url": "https://v3b.fal.media/files/b/0a8c44d5/EHzTxJtHpdIliaMNnEke-_material.mtl"
        },
        "obj": {
          "content_type": "model/obj",
          "file_name": "0f7f7a1ac578c80d4397a7f2b69b40ff.obj",
          "file_size": 5306476,
          "url": "https://v3b.fal.media/files/b/0a8c44d5/2W2KRP1DM_-4qI8F_n05b_0f7f7a1ac578c80d4397a7f2b69b40ff.obj"
        },
        "texture": {
          "content_type": "image/png",
          "file_name": "material.png",
          "file_size": 5915609,
          "url": "https://v3b.fal.media/files/b/0a8c44d5/T0q-P0aqXVG_y7jff-XTa_material.png"
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Hunyuan 3D Pro Image to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-image-to-3d) — 3D
* [Hunyuan 3D Pro Text to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-text-to-3d) — 3D
* [Hunyuan 3d](/model-api-reference/3d-api/hunyuan-3d) — 3D
* [Hunyuan 3D Smart Topology](/model-api-reference/3d-api/hunyuan-3d-smart-topology) — 3D
* [Hunyuan 3D Part Splitter](/model-api-reference/3d-api/hunyuan-3d-part-splitter) — 3D
* [Hunyuan 3D Rapid Image to 3D](/model-api-reference/3d-api/hunyuan-3d-rapid-image-to-3d) — 3D


# https://fal.ai/docs/model-api-reference/3d-api/hunyuan-3d-v3.1-smart-topology.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hunyuan 3d V3.1 Smart Topology API

> API reference for Hunyuan 3d V3.1 Smart Topology. Optimize 3D mesh topology with Hunyuan 3D Smart Topology.

**Endpoint:** `POST https://fal.run/fal-ai/hunyuan-3d/v3.1/smart-topology`
**Endpoint ID:** `fal-ai/hunyuan-3d/v3.1/smart-topology`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/hunyuan-3d/v3.1/smart-topology/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/hunyuan-3d/v3.1/smart-topology",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/hunyuan-3d/v3.1/smart-topology", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/hunyuan-3d/v3.1/smart-topology \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Related

* [Hunyuan 3D Pro Image to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-image-to-3d) — 3D
* [Hunyuan 3D Pro Text to 3D](/model-api-reference/3d-api/hunyuan-3d-pro-text-to-3d) — 3D
* [Hunyuan 3D Rapid Image to 3D](/model-api-reference/3d-api/hunyuan-3d-rapid-image-to-3d) — 3D
* [Hunyuan 3d](/model-api-reference/3d-api/hunyuan-3d) — 3D
* [Hunyuan 3D Part Splitter](/model-api-reference/3d-api/hunyuan-3d-part-splitter) — 3D

## API Reference

### Input Schema

<ParamField body="input_file_url" type="string" default="https://v3b.fal.media/files/b/0a8c09c0/VYDiCTcDGK55qY2-idGbX_model.glb">
  URL of GLB or OBJ file to optimize topology. Max size: 200MB. Default value: `"https://v3b.fal.media/files/b/0a8c09c0/VYDiCTcDGK55qY2-idGbX_model.glb"`
</ParamField>

<ParamField body="input_file_type" type="InputFileTypeEnum" default="glb">
  Input 3D file format. Default value: `"glb"`

  Possible values: `glb`, `obj`
</ParamField>

<ParamField body="polygon_type" type="PolygonTypeEnum" default="triangle">
  Output polygon type. triangle: triangular faces only. quadrilateral: mixed quad and triangle faces. Default value: `"triangle"`

  Possible values: `triangle`, `quadrilateral`
</ParamField>

<ParamField body="face_level" type="FaceLevelEnum" default="medium">
  Target polygon density. high: more detail/polygons, medium: balanced, low: fewer polygons. Default value: `"medium"`

  Possible values: `high`, `medium`, `low`
</ParamField>

### Output Schema

<ParamField body="model_glb" type="File" required>
  Processed 3D model with optimized topology (primary file).
</ParamField>

<ParamField body="model_urls" type="ModelUrls" required>
  URLs for different 3D model formats
</ParamField>

## Input Example

```json theme={null}
{
  "input_file_url": "https://v3b.fal.media/files/b/0a8c09c0/VYDiCTcDGK55qY2-idGbX_model.glb",
  "input_file_type": "glb",
  "polygon_type": "triangle",
  "face_level": "medium"
}
```

## Output Example

```json theme={null}
{
  "model_glb": {
    "content_type": "model/obj",
    "file_name": "model.obj",
    "file_size": 394409,
    "url": "https://v3b.fal.media/files/b/0a8c0ab4/tqMY5NJLnHjpwN8rQ15dj_model.obj"
  },
  "model_urls": {
    "glb": {
      "content_type": "model/gltf-binary",
      "file_name": "model.glb",
      "file_size": 206004,
      "url": "https://v3b.fal.media/files/b/0a8c0ab4/eX-_x0Wv8fZL05l9CGp6Y_model.glb"
    },
    "obj": {
      "content_type": "model/obj",
      "file_name": "model.obj",
      "file_size": 394409,
      "url": "https://v3b.fal.media/files/b/0a8c0ab4/tqMY5NJLnHjpwN8rQ15dj_model.obj"
    }
  }
}
```

## Limitations

* `input_file_type` restricted to: `glb`, `obj`
* `polygon_type` restricted to: `triangle`, `quadrilateral`
* `face_level` restricted to: `high`, `medium`, `low`


# https://fal.ai/docs/model-api-reference/3d-api/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 3D API

> 3D API reference. Generate 3D assets from text or images using AI models.

## Overview

Generate 3D assets from text or images using AI models. Create 3D meshes, textures, and scenes for games, design, and visualization.

## Top Models

<CardGroup cols={2}>
  <Card title="Trellis 2 API" href="/model-api-reference/3d-api/trellis-2">
    Generate 3D models from your images using Trellis 2. A native 3D generative model enabling versatile and high-quality 3D asset creation.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a87573c/DwQCx7YBl36dnFSHaU8OT_bfc26b64d210462489530b5d5d5d98e1.jpg" alt="Example output from Trellis 2" noZoom />
    </Frame>
  </Card>

  <Card title="Hunyuan 3D Pro Image to 3D API" href="/model-api-reference/3d-api/hunyuan-3d-v3.1-pro">
    Generate 3D models from images with Hunyuan 3D Pro

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8c1eed/a9u-FinZ2o0AGqcGFlRoD_5c16e7c0e1ae412cacc53893cae95698.jpg" alt="Example output from Hunyuan 3D Pro Image to 3D" noZoom />
    </Frame>
  </Card>

  <Card title="Trellis API" href="/model-api-reference/3d-api/trellis">
    Generate 3D models from your images using Trellis. A native 3D generative model enabling versatile and high-quality 3D asset creation.

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/web-examples/trellis/trellis-photo.jpg" alt="Example output from Trellis" noZoom />
    </Frame>
  </Card>
</CardGroup>

Explore all 3d models on [fal.ai/models](https://fal.ai/models).

## Quick Start

Get started with **Trellis 2**:

<CodeGroup>
  ```python title="Python" theme={null}
  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/trellis-2",
      arguments={
          "image_url": "https://v3b.fal.media/files/b/0a86b60d/xkpao5B0uxmH0tmJm0HVL_2fe35ce1-fe44-475b-b582-6846a149537c.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/trellis-2", {
    input: {
        image_url: "https://v3b.fal.media/files/b/0a86b60d/xkpao5B0uxmH0tmJm0HVL_2fe35ce1-fe44-475b-b582-6846a149537c.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```
</CodeGroup>

## Pricing

For detailed pricing information, see the [fal.ai pricing page](https://fal.ai/pricing) or individual model pages.


# https://fal.ai/docs/model-api-reference/3d-api/trellis.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Trellis API

> API reference for Trellis. Generate 3D models from your images using Trellis. A native 3D generative model enabling versatile and high-quality 3D asset creation.

<Tabs>
  <Tab title="Trellis">
    **Endpoint:** `POST https://fal.run/fal-ai/trellis`
    **Endpoint ID:** `fal-ai/trellis`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/trellis/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/trellis",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/web-examples/rodin3d/warriorwoman.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/trellis", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/web-examples/rodin3d/warriorwoman.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/trellis \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/web-examples/rodin3d/warriorwoman.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      URL of the input image to convert to 3D
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed for reproducibility
    </ParamField>

    <ParamField body="ss_guidance_strength" type="float" default="7.5">
      Guidance strength for sparse structure generation Default value: `7.5`

      Range: `0` to `10`
    </ParamField>

    <ParamField body="ss_sampling_steps" type="integer" default="12">
      Sampling steps for sparse structure generation Default value: `12`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="slat_guidance_strength" type="float" default="3">
      Guidance strength for structured latent generation Default value: `3`

      Range: `0` to `10`
    </ParamField>

    <ParamField body="slat_sampling_steps" type="integer" default="12">
      Sampling steps for structured latent generation Default value: `12`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="mesh_simplify" type="float" default="0.95">
      Mesh simplification factor Default value: `0.95`

      Range: `0.9` to `0.98`
    </ParamField>

    <ParamField body="texture_size" type="TextureSizeEnum" default="1024">
      Texture resolution Default value: `"1024"`

      Possible values: `512`, `1024`, `2048`
    </ParamField>

    ### Output Schema

    <ParamField body="model_mesh" type="File" required>
      Generated 3D mesh file
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      Processing timings
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/web-examples/rodin3d/warriorwoman.png",
      "ss_guidance_strength": 7.5,
      "ss_sampling_steps": 12,
      "slat_guidance_strength": 3,
      "slat_sampling_steps": 12,
      "mesh_simplify": 0.95,
      "texture_size": 1024
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "model_mesh": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019
      }
    }
    ```
  </Tab>

  <Tab title="Multi">
    **Endpoint:** `POST https://fal.run/fal-ai/trellis/multi`
    **Endpoint ID:** `fal-ai/trellis/multi`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/trellis/multi/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/trellis/multi",
          arguments={
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/model_tests/video_models/front.png",
                  "https://storage.googleapis.com/falserverless/model_tests/video_models/back.png",
                  "https://storage.googleapis.com/falserverless/model_tests/video_models/left.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/trellis/multi", {
        input: {
            image_urls: [
              "https://storage.googleapis.com/falserverless/model_tests/video_models/front.png",
              "https://storage.googleapis.com/falserverless/model_tests/video_models/back.png",
              "https://storage.googleapis.com/falserverless/model_tests/video_models/left.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/trellis/multi \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_urls": [
          "https://storage.googleapis.com/falserverless/model_tests/video_models/front.png",
          "https://storage.googleapis.com/falserverless/model_tests/video_models/back.png",
          "https://storage.googleapis.com/falserverless/model_tests/video_models/left.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>" required>
      List of URLs of input images to convert to 3D
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed for reproducibility
    </ParamField>

    <ParamField body="ss_guidance_strength" type="float" default="7.5">
      Guidance strength for sparse structure generation Default value: `7.5`

      Range: `0` to `10`
    </ParamField>

    <ParamField body="ss_sampling_steps" type="integer" default="12">
      Sampling steps for sparse structure generation Default value: `12`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="slat_guidance_strength" type="float" default="3">
      Guidance strength for structured latent generation Default value: `3`

      Range: `0` to `10`
    </ParamField>

    <ParamField body="slat_sampling_steps" type="integer" default="12">
      Sampling steps for structured latent generation Default value: `12`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="mesh_simplify" type="float" default="0.95">
      Mesh simplification factor Default value: `0.95`

      Range: `0.9` to `0.98`
    </ParamField>

    <ParamField body="texture_size" type="TextureSizeEnum" default="1024">
      Texture resolution Default value: `"1024"`

      Possible values: `512`, `1024`, `2048`
    </ParamField>

    <ParamField body="multiimage_algo" type="MultiimageAlgoEnum" default="stochastic">
      Algorithm for multi-image generation Default value: `"stochastic"`

      Possible values: `stochastic`, `multidiffusion`
    </ParamField>

    ### Output Schema

    <ParamField body="model_mesh" type="File" required>
      Generated 3D mesh file
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      Processing timings
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_urls": [
        "https://storage.googleapis.com/falserverless/model_tests/video_models/front.png",
        "https://storage.googleapis.com/falserverless/model_tests/video_models/back.png",
        "https://storage.googleapis.com/falserverless/model_tests/video_models/left.png"
      ],
      "ss_guidance_strength": 7.5,
      "ss_sampling_steps": 12,
      "slat_guidance_strength": 3,
      "slat_sampling_steps": 12,
      "mesh_simplify": 0.95,
      "texture_size": 1024,
      "multiimage_algo": "stochastic"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "model_mesh": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019
      }
    }
    ```
  </Tab>
</Tabs>

## Trellis - Advanced AI Model for 3D Generation

Transform your creative workflows with Trellis, a powerful AI model designed for reliable, high-quality 3D asset generation from images. Built for developers who need production-ready 3D models with minimal complexity.

### Overview

Trellis provides a streamlined API for generating 3D models from images, utilizing a native 3D generative model based on Structured LATents (SLAT) representation. Whether you're building creative tools, content generation systems, or enhancing existing applications, Trellis delivers consistent, high-quality 3D assets with simple integration.

### Getting Started

Setting up Trellis takes just a few minutes. Choose your preferred SDK:

For JavaScript/TypeScript projects:

```bash theme={null}
npm install --save @fal-ai/client
```

For Python applications:

```bash theme={null}
pip install fal-client
```

Configure your authentication:

JavaScript:

```javascript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY_HERE"
});
```

Python:

```python theme={null}
import fal_client
import os

os.environ["FAL_KEY"] = "YOUR_FAL_KEY_HERE"
```

### Basic Usage

Generate your first 3D model with just a few lines of code:

JavaScript:

```javascript theme={null}
const result = await fal.subscribe("fal-ai/trellis", {
  input: {
    image_url: "https://example.com/your-image.jpg"
  }
});
```

Python:

```python theme={null}
result = fal_client.subscribe("fal-ai/trellis", {
    "image_url": "https://example.com/your-image.jpg"
})
```

### Advanced Features

Trellis supports advanced configuration options to fine-tune your results:

**3D Output Formats**

* Generate multiple 3D representations (Radiance Fields, 3D Gaussians, meshes)
* Export to GLB format for universal compatibility
* Maintain high detail in both geometry and texture

**Quality Control**

* Intricate shape and texture detail preservation
* Flexible output format selection
* Support for local 3D editing capabilities

### API Parameters

**Input Parameters:**

* `image_url` (required): URL of the input image
* Additional configuration options available for advanced use cases

**Output:**

* 3D model in multiple formats
* GLB file export capability
* High-quality mesh and texture data

### Best Practices

Maximize your success with Trellis by following these guidelines:

**Error Handling**

```javascript theme={null}
try {
  const result = await fal.subscribe("fal-ai/trellis", {
    input: { image_url: "your-image-url" }
  });
} catch (error) {
  console.error("Generation failed:", error.message);
}
```

**Image Requirements**

* Use clear, well-lit images with distinct subjects
* Supported formats: JPG, JPEG, PNG, WebP, GIF, AVIF
* Best results with images showing full object visibility

### Technical Specifications

**Model Architecture:**

* Based on Structured LATents (SLAT) representation
* Powered by Rectified Flow Transformers
* Up to 2 billion parameters
* Trained on 500K diverse 3D objects

**Performance Metrics:**

* Fast 3D generation from single images
* High-quality output with intricate details
* Multiple output format support

### File Upload Support

Upload local images using the file storage API:

```javascript theme={null}
import { fal } from "@fal-ai/client";

const file = new File([imageData], "image.jpg", { type: "image/jpeg" });
const url = await fal.storage.upload(file);

const result = await fal.subscribe("fal-ai/trellis", {
  input: {
    image_url: url
  }
});
```

### Queue-Based Processing

For asynchronous workflows:

```javascript theme={null}
// Submit request
const { request_id } = await fal.queue.submit("fal-ai/trellis", {
  input: {
    image_url: "your-image-url"
  },
  webhookUrl: "https://optional.webhook.url/for/results"
});

// Check status
const status = await fal.queue.status("fal-ai/trellis", {
  requestId: request_id,
  logs: true
});

// Get result
const result = await fal.queue.result("fal-ai/trellis", {
  requestId: request_id
});
```

### Integration Support

Our documentation includes complete reference implementations for:

* React/Next.js applications
* Python backend services
* Node.js environments
* REST API clients

### Use Cases

**3D Asset Creation**

* Game development assets
* Product visualization
* Digital art and design
* AR/VR content creation

**Professional Applications**

* E-commerce product models
* Architecture visualization
* Educational content
* Creative prototyping

### Pricing and Usage

* **Cost**: \$0.02 per unit
* Transparent, usage-based pricing
* No subscription necessary
* No hidden fees or minimum commitments

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Support and Resources

Access comprehensive support through multiple channels:

**Documentation**

* [API Reference](https://fal.ai/models/fal-ai/trellis/api)
* [General fal.ai Documentation](https://docs.fal.ai/)
* Code examples and tutorials

**Community Support**

* Active developer community
* Regular updates and improvements
* Direct technical support

Get started with Trellis today and experience the next generation of AI-powered 3D asset generation. Sign up for an API key at [fal.ai](https://fal.ai/login).

## Related

* [Trellis](/model-api-reference/3d-api/trellis) — 3D

## Limitations

* `ss_guidance_strength` range: 0 to 10
* `ss_sampling_steps` range: 1 to 50
* `slat_guidance_strength` range: 0 to 10
* `slat_sampling_steps` range: 1 to 50
* `mesh_simplify` range: 0.9 to 0.98
* `texture_size` restricted to: `512`, `1024`, `2048`
* `multiimage_algo` restricted to: `stochastic`, `multidiffusion`


# https://fal.ai/docs/model-api-reference/3d-api/trellis-2.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Trellis 2 API

> API reference for Trellis 2. Generate 3D models from your images using Trellis 2. A native 3D generative model enabling versatile and high-quality 3D asset creation.

**Endpoint:** `POST https://fal.run/fal-ai/trellis-2`
**Endpoint ID:** `fal-ai/trellis-2`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/trellis-2/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/trellis-2",
      arguments={
          "image_url": "https://v3b.fal.media/files/b/0a86b60d/xkpao5B0uxmH0tmJm0HVL_2fe35ce1-fe44-475b-b582-6846a149537c.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/trellis-2", {
    input: {
        image_url: "https://v3b.fal.media/files/b/0a86b60d/xkpao5B0uxmH0tmJm0HVL_2fe35ce1-fe44-475b-b582-6846a149537c.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/trellis-2 \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://v3b.fal.media/files/b/0a86b60d/xkpao5B0uxmH0tmJm0HVL_2fe35ce1-fe44-475b-b582-6846a149537c.png"
  }'
  ```
</CodeGroup>

## Capabilities

* Reproducible generation (seed)
* Image input

## API Reference

### Input Schema

<ParamField body="seed" type="integer">
  Random seed for reproducibility
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="1024">
  Output resolution; higher is slower but more detailed Default value: `"1024"`

  Possible values: `512`, `1024`, `1536`
</ParamField>

<ParamField body="ss_guidance_strength" type="float" default="7.5">
  How closely the initial 3D structure follows the input image. Higher values produce more faithful but potentially noisier results. Default value: `7.5`

  Range: `0` to `10`
</ParamField>

<ParamField body="ss_guidance_rescale" type="float" default="0.7">
  Dampens artifacts from high guidance in stage 1. Lower values allow stronger guidance effects, higher values stabilize the output. Default value: `0.7`

  Range: `0` to `1`
</ParamField>

<ParamField body="ss_sampling_steps" type="integer" default="12">
  Number of denoising steps for the initial structure. More steps = slower but potentially higher quality. Default value: `12`

  Range: `1` to `50`
</ParamField>

<ParamField body="ss_rescale_t" type="float" default="5">
  Controls noise schedule sharpness for structure generation. Higher values produce sharper transitions. Default value: `5`

  Range: `1` to `6`
</ParamField>

<ParamField body="shape_slat_guidance_strength" type="float" default="7.5">
  How closely the detailed geometry follows the input image. Higher values add more detail but may introduce noise. Default value: `7.5`

  Range: `0` to `10`
</ParamField>

<ParamField body="shape_slat_guidance_rescale" type="float" default="0.5">
  Dampens artifacts from high guidance in the shape stage. Increase if you see noisy geometry. Default value: `0.5`

  Range: `0` to `1`
</ParamField>

<ParamField body="shape_slat_sampling_steps" type="integer" default="12">
  Number of denoising steps for shape refinement. More steps = slower but potentially smoother geometry. Default value: `12`

  Range: `1` to `50`
</ParamField>

<ParamField body="shape_slat_rescale_t" type="float" default="3">
  Controls noise schedule sharpness for shape refinement. Higher values produce sharper geometric details. Default value: `3`

  Range: `1` to `6`
</ParamField>

<ParamField body="tex_slat_guidance_strength" type="float" default="1">
  How closely the texture follows the input image colors. Higher values produce more vivid but potentially oversaturated textures. Default value: `1`

  Range: `0` to `10`
</ParamField>

<ParamField body="tex_slat_guidance_rescale" type="float" default="0">
  Dampens artifacts from high guidance in the texture stage. Increase if textures look noisy or have color banding.

  Range: `0` to `1`
</ParamField>

<ParamField body="tex_slat_sampling_steps" type="integer" default="12">
  Number of denoising steps for texture generation. More steps = slower but potentially cleaner textures. Default value: `12`

  Range: `1` to `50`
</ParamField>

<ParamField body="tex_slat_rescale_t" type="float" default="3">
  Controls noise schedule sharpness for texture generation. Higher values produce sharper texture details. Default value: `3`

  Range: `1` to `6`
</ParamField>

<ParamField body="decimation_target" type="integer" default="500000">
  Target number of vertices in the final mesh. Lower values produce smaller files but less detail. 500k is good for most uses, reduce to 20k-50k for web/mobile. Default value: `500000`

  Range: `5000` to `2000000`
</ParamField>

<ParamField body="texture_size" type="TextureSizeEnum" default="2048">
  Resolution of the texture image baked onto the mesh. Higher values capture finer surface details but produce larger files. Default value: `"2048"`

  Possible values: `1024`, `2048`, `4096`
</ParamField>

<ParamField body="remesh" type="boolean" default="true">
  Rebuild the mesh topology for cleaner triangles. Slower but usually produces better results for downstream use (animation, 3D printing, etc). Default value: `true`
</ParamField>

<ParamField body="remesh_band" type="float" default="1">
  Controls how far remeshing can move vertices from the original surface. Higher values allow more smoothing but may lose fine details. Default value: `1`

  Range: `0` to `4`
</ParamField>

<ParamField body="remesh_project" type="float" default="0">
  How much to project remeshed vertices back onto the original surface. 0 = no projection (smoother), 1 = full projection (preserves detail).

  Range: `0` to `1`
</ParamField>

<ParamField body="image_url" type="string" required>
  URL of the input image to convert to 3D
</ParamField>

### Output Schema

<ParamField body="model_glb" type="File" required>
  Generated 3D GLB file
</ParamField>

## Input Example

```json theme={null}
{
  "resolution": 1024,
  "ss_guidance_strength": 7.5,
  "ss_guidance_rescale": 0.7,
  "ss_sampling_steps": 12,
  "ss_rescale_t": 5,
  "shape_slat_guidance_strength": 7.5,
  "shape_slat_guidance_rescale": 0.5,
  "shape_slat_sampling_steps": 12,
  "shape_slat_rescale_t": 3,
  "tex_slat_guidance_strength": 1,
  "tex_slat_guidance_rescale": 0,
  "tex_slat_sampling_steps": 12,
  "tex_slat_rescale_t": 3,
  "decimation_target": 500000,
  "texture_size": 2048,
  "remesh": true,
  "remesh_band": 1,
  "remesh_project": 0,
  "image_url": "https://v3b.fal.media/files/b/0a86b60d/xkpao5B0uxmH0tmJm0HVL_2fe35ce1-fe44-475b-b582-6846a149537c.png"
}
```

## Output Example

```json theme={null}
{
  "model_glb": {
    "url": "https://v3b.fal.media/files/b/0a86b61d/DNmTkiWHUQ8k-rG6aussB_trellis2_68d6300f70f34d23b69a912b5fe60487.glb"
  }
}
```

## Limitations

* `resolution` restricted to: `512`, `1024`, `1536`
* `ss_guidance_strength` range: 0 to 10
* `ss_guidance_rescale` range: 0 to 1
* `ss_sampling_steps` range: 1 to 50
* `ss_rescale_t` range: 1 to 6
* `shape_slat_guidance_strength` range: 0 to 10
* `shape_slat_guidance_rescale` range: 0 to 1
* `shape_slat_sampling_steps` range: 1 to 50
* `shape_slat_rescale_t` range: 1 to 6
* `tex_slat_guidance_strength` range: 0 to 10
* `tex_slat_guidance_rescale` range: 0 to 1
* `tex_slat_sampling_steps` range: 1 to 50
* `tex_slat_rescale_t` range: 1 to 6
* `decimation_target` range: 5000 to 2000000
* `texture_size` restricted to: `1024`, `2048`, `4096`
* `remesh_band` range: 0 to 4
* `remesh_project` range: 0 to 1


# https://fal.ai/docs/model-api-reference/audio-api/kling-video-create-voice.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video Create Voice API

> API reference for Kling Video Create Voice. Create Voices to be used with Kling Models Voice Control

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/create-voice`
**Endpoint ID:** `fal-ai/kling-video/create-voice`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/create-voice/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/create-voice",
      arguments={
          "voice_url": "https://v3b.fal.media/files/b/0a867736/_Wo19V-XrOVYZt6jKE8t5_kling_video.wav"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/create-voice", {
    input: {
        voice_url: "https://v3b.fal.media/files/b/0a867736/_Wo19V-XrOVYZt6jKE8t5_kling_video.wav"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/create-voice \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "voice_url": "https://v3b.fal.media/files/b/0a867736/_Wo19V-XrOVYZt6jKE8t5_kling_video.wav"
  }'
  ```
</CodeGroup>

## API Reference

### Input Schema

<ParamField body="voice_url" type="string" required>
  URL of the voice audio file. Supports .mp3/.wav audio or .mp4/.mov video. Duration must be 5-30 seconds with clean, single-voice audio.
</ParamField>

### Output Schema

<ParamField body="voice_id" type="string" required>
  Unique identifier for the created voice
</ParamField>

## Input Example

```json theme={null}
{
  "voice_url": "https://v3b.fal.media/files/b/0a867736/_Wo19V-XrOVYZt6jKE8t5_kling_video.wav"
}
```

## Output Example

```json theme={null}
{
  "voice_id": "829877809978941442"
}
```


# https://fal.ai/docs/model-api-reference/audio-api/kling-video-v1.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V1 API

> API reference for Kling Video V1. Generate speech from text prompts and different voices using the Kling TTS model, which leverages advanced AI techniques to create high-quality text-to-speech.

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1/tts`
**Endpoint ID:** `fal-ai/kling-video/v1/tts`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1/tts/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/v1/tts",
      arguments={
          "text": "Hello world! Kling TTS is available on FAL!"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/v1/tts", {
    input: {
        text: "Hello world! Kling TTS is available on FAL!"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/v1/tts \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "text": "Hello world! Kling TTS is available on FAL!"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="text" type="string" required>
  The text to be converted to speech
</ParamField>

<ParamField body="voice_id" type="VoiceIdEnum" default="genshin_vindi2">
  The voice ID to use for speech synthesis Default value: `"genshin_vindi2"`

  Possible values: `genshin_vindi2`, `zhinen_xuesheng`, `AOT`, `ai_shatang`, `genshin_klee2`, `genshin_kirara`, `ai_kaiya`, `oversea_male1`, `ai_chenjiahao_712`, `girlfriend_4_speech02`, `chat1_female_new-3`, `chat_0407_5-1`, `cartoon-boy-07`, `uk_boy1`, `cartoon-girl-01`, `PeppaPig_platform`, `ai_huangzhong_712`, `ai_huangyaoshi_712`, `ai_laoguowang_712`, `chengshu_jiejie`, `you_pingjing`, `calm_story1`, `uk_man2`, `laopopo_speech02`, `heainainai_speech02`, `reader_en_m-v1`, `commercial_lady_en_f-v1`, `tiyuxi_xuedi`, `tiexin_nanyou`, `girlfriend_1_speech02`, `girlfriend_2_speech02`, `zhuxi_speech02`, `uk_oldman3`, `dongbeilaotie_speech02`, `chongqingxiaohuo_speech02`, `chuanmeizi_speech02`, `chaoshandashu_speech02`, `ai_taiwan_man2_speech02`, `xianzhanggui_speech02`, `tianjinjiejie_speech02`, `diyinnansang_DB_CN_M_04-v2`, `yizhipiannan-v1`, `guanxiaofang-v2`, `tianmeixuemei-v1`, `daopianyansang-v1`, `mengwa-v1`
</ParamField>

<ParamField body="voice_speed" type="float" default="1">
  Rate of speech Default value: `1`

  Range: `0.8` to `2`
</ParamField>

### Output Schema

<ParamField body="audio" type="File" required>
  The generated audio
</ParamField>

### Input Example

```json theme={null}
{
  "text": "Hello world! Kling TTS is available on FAL!",
  "voice_id": "genshin_vindi2",
  "voice_speed": 1
}
```

### Output Example

```json theme={null}
{
  "audio": {
    "url": "https://v3.fal.media/files/monkey/O-ekVTtYqeDblD1oSf2uv_output.mp3"
  }
}
```

## Related

* [Kling AI Avatar v2 Pro](/model-api-reference/video-generation-api/kling-ai-avatar-v2-pro) — Video Generation
* [Kling AI Avatar v2 Standard](/model-api-reference/video-generation-api/kling-ai-avatar-v2-standard) — Video Generation
* [Kling AI Avatar](/model-api-reference/video-generation-api/kling-ai-avatar) — Video Generation
* [Kling AI Avatar Pro](/model-api-reference/video-generation-api/kling-ai-avatar-pro) — Video Generation

## Limitations

* `voice_speed` range: 0.8 to 2


# https://fal.ai/docs/model-api-reference/audio-api/kling-video-video-to-audio.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video Video To Audio API

> API reference for Kling Video Video To Audio. Generate audio from input videos using Kling

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/video-to-audio`
**Endpoint ID:** `fal-ai/kling-video/video-to-audio`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/video-to-audio/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/video-to-audio",
      arguments={
          "video_url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-v2.5-turbo-pro-image-to-video-output.mp4"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/video-to-audio", {
    input: {
        video_url: "https://storage.googleapis.com/falserverless/model_tests/kling/kling-v2.5-turbo-pro-image-to-video-output.mp4"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/video-to-audio \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "video_url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-v2.5-turbo-pro-image-to-video-output.mp4"
  }'
  ```
</CodeGroup>

## Examples

<video src="https://v3b.fal.media/files/b/zebra/SrjZVk4yqjXSLWOdq7p6P_output.mp4" controls width="100%" />

## Capabilities

* Video input

## API Reference

### Input Schema

<ParamField body="video_url" type="string" required>
  The video URL to extract audio from. Only .mp4/.mov formats are supported. File size does not exceed 100MB. Video duration between 3.0s and 20.0s.
</ParamField>

<ParamField body="sound_effect_prompt" type="string" default="Car tires screech as they accelerate in a drag race">
  Sound effect prompt. Cannot exceed 200 characters. Default value: `"Car tires screech as they accelerate in a drag race"`
</ParamField>

<ParamField body="background_music_prompt" type="string" default="intense car race">
  Background music prompt. Cannot exceed 200 characters. Default value: `"intense car race"`
</ParamField>

<ParamField body="asmr_mode" type="boolean" default="false">
  Enable ASMR mode. This mode enhances detailed sound effects and is suitable for highly immersive content scenarios.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The original video with dubbed audio applied
</ParamField>

<ParamField body="audio" type="File" required>
  The extracted/generated audio from the video in MP3 format
</ParamField>

## Input Example

```json theme={null}
{
  "video_url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-v2.5-turbo-pro-image-to-video-output.mp4",
  "sound_effect_prompt": "Car tires screech as they accelerate in a drag race",
  "background_music_prompt": "intense car race",
  "asmr_mode": false
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3.fal.media/files/monkey/O-ekVTtYqeDblD1oSf2uv_dubbed_video.mp4"
  },
  "audio": {
    "url": "https://v3.fal.media/files/monkey/O-ekVTtYqeDblD1oSf2uv_extracted_audio.mp3"
  }
}
```


# https://fal.ai/docs/model-api-reference/audio-api/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Audio API

> Audio API reference. Models for audio processing including text-to-speech, speech-to-text, voice cloning, and music generation..

## Overview

Models for audio processing including text-to-speech, speech-to-text, voice cloning, and music generation.

## Top Models

<CardGroup cols={2}>
  <Card title="Whisper API" href="/model-api-reference/audio-api/whisper">
    Whisper is a model for speech transcription and translation.

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/whisper.jpg" alt="Example output from Whisper" noZoom />
    </Frame>
  </Card>

  <Card title="Kling Video Create Voice API" href="/model-api-reference/audio-api/kling-video-create-voice">
    Create Voices to be used with Kling Models Voice Control

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a868c52/jCucNmpNTg7UQ2WYGJHAr_36ad5b9439824f5e9f8fd7f1ed297d27.jpg" alt="Example output from Kling Video Create Voice" noZoom />
    </Frame>
  </Card>

  <Card title="xAI Text to Speech API" href="/model-api-reference/audio-api/xai-tts">
    Generate speech with expressive and realistic voices from xAI

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a92763c/4toOv_gM9xUL_Zwmt4Gc8_67e9f077fc4c48e78dfa428f7d50b190.jpg" alt="Example output from xAI Text to Speech" noZoom />
    </Frame>
  </Card>
</CardGroup>

Explore all audio models on [fal.ai/models](https://fal.ai/models).

## Quick Start

Get started with **Whisper**:

<CodeGroup>
  ```python title="Python" theme={null}
  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/whisper",
      arguments={
          "audio_url": "https://storage.googleapis.com/falserverless/model_tests/whisper/dinner_conversation.mp3"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/whisper", {
    input: {
        audio_url: "https://storage.googleapis.com/falserverless/model_tests/whisper/dinner_conversation.mp3"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```
</CodeGroup>

## Pricing

For detailed pricing information, see the [fal.ai pricing page](https://fal.ai/pricing) or individual model pages.


# https://fal.ai/docs/model-api-reference/audio-api/whisper.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Whisper API

> API reference for Whisper. Whisper is a model for speech transcription and translation.

**Endpoint:** `POST https://fal.run/fal-ai/whisper`
**Endpoint ID:** `fal-ai/whisper`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/whisper/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/whisper",
      arguments={
          "audio_url": "https://storage.googleapis.com/falserverless/model_tests/whisper/dinner_conversation.mp3"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/whisper", {
    input: {
        audio_url: "https://storage.googleapis.com/falserverless/model_tests/whisper/dinner_conversation.mp3"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/whisper \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "audio_url": "https://storage.googleapis.com/falserverless/model_tests/whisper/dinner_conversation.mp3"
  }'
  ```
</CodeGroup>

## Capabilities

* Audio input
* Text prompt input

## API Reference

### Input Schema

<ParamField body="audio_url" type="string" required>
  URL of the audio file to transcribe. Supported formats: mp3, mp4, mpeg, mpga, m4a, wav or webm.
</ParamField>

<ParamField body="task" type="TaskEnum" default="transcribe">
  Task to perform on the audio file. Either transcribe or translate. Default value: `"transcribe"`

  Possible values: `transcribe`, `translate`
</ParamField>

<ParamField body="language" type="Enum">
  Language of the audio file. If set to null, the language will be
  automatically detected. Defaults to null.

  If translate is selected as the task, the audio will be translated to
  English, regardless of the language selected.

  Possible values: `af`, `am`, `ar`, `as`, `az`, `ba`, `be`, `bg`, `bn`, `bo`, `br`, `bs`, `ca`, `cs`, `cy`, `da`, `de`, `el`, `en`, `es`, `et`, `eu`, `fa`, `fi`, `fo`, `fr`, `gl`, `gu`, `ha`, `haw`, `he`, `hi`, `hr`, `ht`, `hu`, `hy`, `id`, `is`, `it`, `ja`, `jw`, `ka`, `kk`, `km`, `kn`, `ko`, `la`, `lb`, `ln`, `lo`, `lt`, `lv`, `mg`, `mi`, `mk`, `ml`, `mn`, `mr`, `ms`, `mt`, `my`, `ne`, `nl`, `nn`, `no`, `oc`, `pa`, `pl`, `ps`, `pt`, `ro`, `ru`, `sa`, `sd`, `si`, `sk`, `sl`, `sn`, `so`, `sq`, `sr`, `su`, `sv`, `sw`, `ta`, `te`, `tg`, `th`, `tk`, `tl`, `tr`, `tt`, `uk`, `ur`, `uz`, `vi`, `yi`, `yo`, `zh`
</ParamField>

<ParamField body="diarize" type="boolean" default="false">
  Whether to diarize the audio file. Defaults to false. Setting to true will add costs proportional to diarization inference time.
</ParamField>

<ParamField body="chunk_level" type="ChunkLevelEnum" default="segment">
  Level of the chunks to return. Either none, segment or word. `none` would imply that all of the audio will be transcribed without the timestamp tokens, we suggest to switch to `none` if you are not satisfied with the transcription quality, since it will usually improve the quality of the results. Switching to `none` will also provide minor speed ups in the transcription due to less amount of generated tokens. Notice that setting to none will produce **a single chunk with the whole transcription**. Default value: `"segment"`

  Possible values: `none`, `segment`, `word`
</ParamField>

<ParamField body="batch_size" type="integer" default="64">
  Default value: `64`

  Range: `1` to `64`
</ParamField>

<ParamField body="prompt" type="string" default="">
  Prompt to use for generation. Defaults to an empty string. Default value: `""`
</ParamField>

<ParamField body="num_speakers" type="integer">
  Number of speakers in the audio file. Defaults to null.
  If not provided, the number of speakers will be automatically
  detected.
</ParamField>

### Output Schema

<ParamField body="text" type="string" required>
  Transcription of the audio file
</ParamField>

<ParamField body="chunks" type="list<WhisperChunk>">
  Timestamp chunks of the audio file
</ParamField>

<ParamField body="inferred_languages" type="list<Enum>" required>
  List of languages that the audio file is inferred to be. Defaults to null.
</ParamField>

<ParamField body="diarization_segments" type="list<DiarizationSegment>" required>
  Speaker diarization segments of the audio file. Only present if diarization is enabled.
</ParamField>

## Input Example

```json theme={null}
{
  "audio_url": "https://storage.googleapis.com/falserverless/model_tests/whisper/dinner_conversation.mp3",
  "task": "transcribe",
  "diarize": false,
  "chunk_level": "segment",
  "batch_size": 64,
  "prompt": "",
  "num_speakers": null
}
```

## Output Example

```json theme={null}
{
  "text": "María, ¿qué cenamos hoy? No sé, ¿qué cenamos? ¿Cenamos pollo frito o pollo asado o algo? Mejor a la plancha, quiero una salada. A la plancha, vale. Y hacemos una ensalada con tomate y esas cosas. Vale. Pues eso lo hacemos, ¿vale? Venga, vale.",
  "chunks": [
    {
      "text": ""
    }
  ],
  "diarization_segments": [
    {
      "speaker": ""
    }
  ]
}
```

## Limitations

* `task` restricted to: `transcribe`, `translate`
* `chunk_level` restricted to: `none`, `segment`, `word`
* `batch_size` range: 1 to 64


# https://fal.ai/docs/model-api-reference/audio-api/xai-tts.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Xai Tts API

> API reference for Xai Tts. Generate speech with expressive and realistic voices from xAI

**Endpoint:** `POST https://fal.run/xai/tts/v1`
**Endpoint ID:** `xai/tts/v1`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/tts/v1/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "xai/tts/v1",
      arguments={
          "text": "Hello! This is xAI text to speech, brought to you by Fal AI."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("xai/tts/v1", {
    input: {
        text: "Hello! This is xAI text to speech, brought to you by Fal AI."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/xai/tts/v1 \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "text": "Hello! This is xAI text to speech, brought to you by Fal AI."
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="text" type="string" required>
  The text to convert to speech. Maximum 15,000 characters. Supports speech tags for expressive delivery: inline tags like \[laugh], \[pause], \[sigh] and wrapping tags like \<whisper>text\</whisper>, \<slow>text\</slow>.
</ParamField>

<ParamField body="voice" type="VoiceEnum" default="eve">
  Voice to use for synthesis. eve: energetic, upbeat. ara: warm, friendly. rex: confident, clear. sal: smooth, balanced. leo: authoritative, strong. Default value: `"eve"`

  Possible values: `eve`, `ara`, `rex`, `sal`, `leo`
</ParamField>

<ParamField body="language" type="LanguageEnum" default="auto">
  BCP-47 language code or 'auto' for automatic detection. Supported: en, zh, fr, de, hi, id, it, ja, ko, pt-BR, pt-PT, ru, es-MX, es-ES, tr, vi, bn, ar-EG, ar-SA, ar-AE. Default value: `"auto"`

  Possible values: `auto`, `en`, `ar-EG`, `ar-SA`, `ar-AE`, `bn`, `zh`, `fr`, `de`, `hi`, `id`, `it`, `ja`, `ko`, `pt-BR`, `pt-PT`, `ru`, `es-MX`, `es-ES`, `tr`, `vi`
</ParamField>

<ParamField body="output_format" type="OutputFormat">
  Output format configuration. Defaults to MP3 at 24 kHz / 128 kbps.
</ParamField>

### Output Schema

<ParamField body="audio" type="File" required>
  The generated audio file.
</ParamField>

### Input Example

```json theme={null}
{
  "text": "Hello! This is xAI text to speech, brought to you by Fal AI.",
  "voice": "eve",
  "language": "auto"
}
```

### Output Example

```json theme={null}
{
  "audio": {
    "url": "https://v3b.fal.media/files/b/0a92750b/exZJCm6TDejS5xIulJs2r_xai_tts_output.mp3"
  }
}
```

## Limitations

* `voice` restricted to: `eve`, `ara`, `rex`, `sal`, `leo`


# https://fal.ai/docs/model-api-reference/image-generation-api/birefnet.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Birefnet API

> API reference for Birefnet. bilateral reference framework (BiRefNet) for high-resolution dichotomous image segmentation (DIS)

<Tabs>
  <Tab title="Birefnet">
    **Endpoint:** `POST https://fal.run/fal-ai/birefnet`
    **Endpoint ID:** `fal-ai/birefnet`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/birefnet/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/birefnet",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/birefnet", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/birefnet \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="model" type="ModelEnum" default="General Use (Light)">
      Model to use for background removal.
      The 'General Use (Light)' model is the original model used in the BiRefNet repository.
      The 'General Use (Heavy)' model is a slower but more accurate model.
      The 'Portrait' model is a model trained specifically for portrait images.
      The 'General Use (Light)' model is recommended for most use cases.

      The corresponding models are as follows:

      * 'General Use (Light)': BiRefNet-DIS\_ep580.pth
      * 'General Use (Heavy)': BiRefNet-massive-epoch\_240.pth
      * 'Portrait': BiRefNet-portrait-TR\_P3M\_10k-epoch\_120.pth Default value: `"General Use (Light)"`

      Possible values: `General Use (Light)`, `General Use (Heavy)`, `Portrait`
    </ParamField>

    <ParamField body="operating_resolution" type="OperatingResolutionEnum" default="1024x1024">
      The resolution to operate on. The higher the resolution, the more accurate the output will be for high res input images. Default value: `"1024x1024"`

      Possible values: `1024x1024`, `2048x2048`
    </ParamField>

    <ParamField body="output_mask" type="boolean" default="false">
      Whether to output the mask used to remove the background
    </ParamField>

    <ParamField body="refine_foreground" type="boolean" default="true">
      Whether to refine the foreground using the estimated mask Default value: `true`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of the image to remove background from
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the output image Default value: `"png"`

      Possible values: `webp`, `png`, `gif`
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="ImageFile" required>
      Image with background removed
    </ParamField>

    <ParamField body="mask_image" type="ImageFile">
      Mask used to remove the background
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "model": "General Use (Light)",
      "operating_resolution": "1024x1024",
      "output_mask": false,
      "refine_foreground": true,
      "sync_mode": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg",
      "output_format": "png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "content_type": "image/png",
        "file_name": "birefnet-output.png",
        "height": 1024,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/birefnet-output.png",
        "width": 1024
      }
    }
    ```
  </Tab>

  <Tab title="V2">
    **Endpoint:** `POST https://fal.run/fal-ai/birefnet/v2`
    **Endpoint ID:** `fal-ai/birefnet/v2`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/birefnet/v2/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/birefnet/v2",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/birefnet/v2", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/birefnet/v2 \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg"
      }'
      ```
    </CodeGroup>

    ## Examples

    <Frame>
      <img src="https://fal.media/files/rabbit/LtkIjHOS-wgmPEghTIzkq_13ddac3a62f74e219b12cebef972ec18.png" alt="Example output from Birefnet Background Removal" />
    </Frame>

    ### Input Schema

    <ParamField body="model" type="ModelEnum" default="General Use (Light)">
      Model to use for background removal.
      The 'General Use (Light)' model is the original model used in the BiRefNet repository.
      The 'General Use (Light 2K)' model is the original model used in the BiRefNet repository but trained with 2K images.
      The 'General Use (Heavy)' model is a slower but more accurate model.
      The 'Matting' model is a model trained specifically for matting images.
      The 'Portrait' model is a model trained specifically for portrait images.
      The 'General Use (Dynamic)' model supports dynamic resolutions from 256x256 to 2304x2304.
      The 'General Use (Light)' model is recommended for most use cases.

      The corresponding models are as follows:

      * 'General Use (Light)': BiRefNet
      * 'General Use (Light 2K)': BiRefNet\_lite-2K
      * 'General Use (Heavy)': BiRefNet\_lite
      * 'Matting': BiRefNet-matting
      * 'Portrait': BiRefNet-portrait
      * 'General Use (Dynamic)': BiRefNet\_dynamic Default value: `"General Use (Light)"`

      Possible values: `General Use (Light)`, `General Use (Light 2K)`, `General Use (Heavy)`, `Matting`, `Portrait`, `General Use (Dynamic)`
    </ParamField>

    <ParamField body="operating_resolution" type="OperatingResolutionEnum" default="1024x1024">
      The resolution to operate on. The higher the resolution, the more accurate the output will be for high res input images. The '2304x2304' option is only available for the 'General Use (Dynamic)' model. Default value: `"1024x1024"`

      Possible values: `1024x1024`, `2048x2048`, `2304x2304`
    </ParamField>

    <ParamField body="output_mask" type="boolean" default="false">
      Whether to output the mask used to remove the background
    </ParamField>

    <ParamField body="refine_foreground" type="boolean" default="true">
      Whether to refine the foreground using the estimated mask Default value: `true`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of the image to remove background from
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the output image Default value: `"png"`

      Possible values: `webp`, `png`, `gif`
    </ParamField>

    <ParamField body="mask_only" type="boolean" default="false">
      Whether to return only the segmentation mask without applying it to the image. When set to `True`, only the mask will be returned and foreground refinement will be skipped. Useful for reducing computation and data transfer when only the mask is needed.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="ImageFile" required>
      Image with background removed. When `mask_only` is `True`, this contains the segmentation mask instead.
    </ParamField>

    <ParamField body="mask_image" type="ImageFile">
      Mask used to remove the background
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "model": "General Use (Light)",
      "operating_resolution": "1024x1024",
      "output_mask": false,
      "refine_foreground": true,
      "sync_mode": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-input.jpeg",
      "output_format": "png",
      "mask_only": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "content_type": "image/png",
        "file_name": "birefnet-output.png",
        "height": 1024,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/birefnet-output.png",
        "width": 1024
      }
    }
    ```
  </Tab>
</Tabs>

BiRefNet's bilateral reference framework delivers high-resolution dichotomous image segmentation with precision mask generation. Trading traditional single-pass segmentation for a **dual-reference architecture**, it achieves cleaner edge detection and handles complex foreground-background separation. Purpose-built for production workflows requiring pixel-perfect transparency extraction from product photos, portraits, and complex scenes.

**Use Cases:** E-commerce Product Photography | Portrait Editing | Design Asset Preparation

***

## Performance

BiRefNet operates at **production-ready speeds** with three specialized model variants optimized for different accuracy-speed tradeoffs, processing images up to 2048x2048 resolution with optional mask output for downstream compositing workflows.

| Metric                   | Result                                                  | Context                                                    |
| :----------------------- | :------------------------------------------------------ | :--------------------------------------------------------- |
| **Operating Resolution** | Up to 2048x2048                                         | 4 megapixels max for high-fidelity edge detection          |
| **Model Variants**       | 3 specialized models                                    | Light (fast), Heavy (accurate), Portrait (optimized)       |
| **Cost per Inference**   | \$0 per compute second                                  | Pay only for actual processing time                        |
| **Output Formats**       | PNG, WebP, GIF                                          | Transparency-preserving formats with optional mask export  |
| **Related Endpoints**    | [BiRefNet v2](https://fal.ai/models/fal-ai/birefnet/v2) | Enhanced accuracy variant for demanding segmentation tasks |

***

## Precision Segmentation Architecture

BiRefNet's bilateral reference framework processes images through parallel pathways, one analyzing global context, the other focusing on local detail, then synthesizes both for edge-accurate mask generation. This contrasts with standard single-encoder approaches that struggle with fine details like hair strands or transparent objects.

**What this means for you:**

* **Three-tier model selection:** Choose Light (BiRefNet-DIS\_ep580) for speed, Heavy (BiRefNet-massive-epoch\_240) for complex scenes, or Portrait (BiRefNet-portrait-TR\_P3M\_10k-epoch\_120) for face-optimized segmentation based on your accuracy requirements

* **Scalable resolution processing:** Operate at 1024x1024 for standard workflows or 2048x2048 (4MP) for high-resolution source images requiring maximum edge fidelity

* **Optional foreground refinement:** Enable `refine_foreground` to apply mask-guided enhancement that preserves subject detail while ensuring clean transparency

* **Dual output capability:** Export both the background-removed image and the raw segmentation mask for manual compositing or downstream processing pipelines

***

## Technical Specifications

| Spec                      | Details                                     |
| :------------------------ | :------------------------------------------ |
| **Architecture**          | BiRefNet Bilateral Reference Framework      |
| **Input Formats**         | JPEG, PNG, WebP, GIF, AVIF via URL          |
| **Output Formats**        | PNG (default), WebP, GIF with alpha channel |
| **Operating Resolutions** | 1024x1024, 2048x2048                        |
| **License**               | Commercial use permitted                    |

[API Documentation](https://fal.ai/models/fal-ai/birefnet/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

**BiRefNet v2** – BiRefNet v1 provides the core bilateral reference architecture with proven segmentation accuracy for general use cases. [BiRefNet v2](https://fal.ai/models/fal-ai/birefnet/v2) builds on this foundation with enhanced edge detection refinement for challenging scenarios like fine hair detail or semi-transparent objects where the original model may struggle.

## Limitations

* `model` restricted to: `General Use (Light)`, `General Use (Heavy)`, `Portrait`
* `operating_resolution` restricted to: `1024x1024`, `2048x2048`
* `output_format` restricted to: `webp`, `png`, `gif`
* `model` restricted to: `General Use (Light)`, `General Use (Light 2K)`, `General Use (Heavy)`, `Matting`, `Portrait`, `General Use (Dynamic)`
* `operating_resolution` restricted to: `1024x1024`, `2048x2048`, `2304x2304`


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-background.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Background API

> API reference for Bria Background. Bria RMBG 2.0 enables seamless removal of backgrounds from images, ideal for professional editing tasks. Trained exclusively on licensed data for safe and risk-free 

<Tabs>
  <Tab title="Remove">
    **Endpoint:** `POST https://fal.run/fal-ai/bria/background/remove`
    **Endpoint ID:** `fal-ai/bria/background/remove`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/background/remove/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bria/background/remove",
          arguments={
              "image_url": "https://fal.media/files/panda/K5Rndvzmn1j-OI1VZXDVd.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bria/background/remove", {
        input: {
            image_url: "https://fal.media/files/panda/K5Rndvzmn1j-OI1VZXDVd.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bria/background/remove \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/panda/K5Rndvzmn1j-OI1VZXDVd.jpeg"
      }'
      ```
    </CodeGroup>

    ## Examples

    <Frame>
      <img src="https://v3.fal.media/files/lion/YBr6fXnaBoA_Hsy89qG6Q_44ab15cf50b0431fa4786c565c5b9032.png" alt="Example output from Bria RMBG 2.0" />
    </Frame>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      Input Image to erase from
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      The generated image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://fal.media/files/panda/K5Rndvzmn1j-OI1VZXDVd.jpeg",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "content_type": "image/png",
        "file_name": "070c731993e949d993c10ef6283d335d.png",
        "file_size": 1076276,
        "height": 1024,
        "url": "https://v3.fal.media/files/tiger/GQEMNjRyxSoza7N8LPPqb_070c731993e949d993c10ef6283d335d.png",
        "width": 1024
      }
    }
    ```
  </Tab>

  <Tab title="Replace">
    **Endpoint:** `POST https://fal.run/fal-ai/bria/background/replace`
    **Endpoint ID:** `fal-ai/bria/background/replace`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/background/replace/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bria/background/replace",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/bria/bria_bg_replace_fg.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bria/background/replace", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/bria/bria_bg_replace_fg.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bria/background/replace \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/bria/bria_bg_replace_fg.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      Input Image to erase from
    </ParamField>

    <ParamField body="ref_image_url" type="string" default="">
      The URL of the reference image to be used for generating the new background. Use "" to leave empty. Either ref\_image\_url or bg\_prompt has to be provided but not both. If both ref\_image\_url and ref\_image\_file are provided, ref\_image\_url will be used. Accepted formats are jpeg, jpg, png, webp. Default value: `""`
    </ParamField>

    <ParamField body="prompt" type="string">
      The prompt you would like to use to generate images.
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      The negative prompt you would like to use to generate images. Default value: `""`
    </ParamField>

    <ParamField body="refine_prompt" type="boolean" default="true">
      Whether to refine prompt Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.

      Range: `0` to `2147483647`
    </ParamField>

    <ParamField body="fast" type="boolean" default="true">
      Whether to use the fast model Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of Images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed value used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/bria/bria_bg_replace_fg.jpg",
      "ref_image_url": "https://storage.googleapis.com/falserverless/bria/bria_bg_replace_bg.jpg",
      "prompt": "Man leaning against a wall",
      "negative_prompt": "",
      "refine_prompt": true,
      "fast": true,
      "num_images": 1,
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "url": "https://storage.googleapis.com/falserverless/bria/bria_bg_replace_res.jpg"
        }
      ]
    }
    ```
  </Tab>
</Tabs>

Bria's RMBG 2.0 delivers production-grade background removal at \$0.018 per inference, trained exclusively on **licensed commercial data**. Trading breadth for legal certainty, this model solves the compliance headache that blocks most background removal tools from enterprise deployment. Built for teams that need defensible image segmentation without licensing risk.

**Use Cases:** E-commerce Product Photography | Marketing Asset Production | Professional Photo Editing

***

## Performance

At \$0.018 per generation, RMBG 2.0 is a **specialized utility model**, comparable to standard background removal pricing but with the critical differentiator of commercial licensing clarity.

| Metric                | Result                                                                                                                                                                                               | Context                                                |
| :-------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------- |
| **Training Data**     | 100% licensed commercial imagery                                                                                                                                                                     | Legal defensibility for enterprise deployment          |
| **Cost per Image**    | \$0.018                                                                                                                                                                                              | 55 generations per \$1.00 on fal                       |
| **Input Format**      | Single image URL                                                                                                                                                                                     | Standard image-to-image pipeline                       |
| **Output Format**     | PNG with transparency                                                                                                                                                                                | 1024x1024 preserved dimensions                         |
| **Related Endpoints** | [Background Replace](https://fal.ai/models/fal-ai/bria/background/replace), [Product Shot](https://fal.ai/models/fal-ai/bria/product-shot), [Expand Image](https://fal.ai/models/fal-ai/bria/expand) | Same-family variants for product photography workflows |

***

## Built for Commercial Deployment

RMBG 2.0 uses a **segmentation architecture** trained exclusively on licensed data, contrasting sharply with open models trained on scraped web imagery.

**What this means for you:**

* **Enterprise-safe training data:** Every training image carries commercial licensing, eliminating copyright exposure in regulated industries

* **Transparent background removal:** Clean PNG output with alpha channel preservation for immediate compositing workflows

* **Single-purpose optimization:** Focused solely on background segmentation rather than multi-task compromise

* **Straightforward integration:** Standard image URL input via [fal's API](https://fal.ai/models/fal-ai/bria/background/remove/api) with synchronous or asynchronous processing modes

***

## Technical Specifications

| Spec               | Details                                      |
| :----------------- | :------------------------------------------- |
| **Architecture**   | Bria RMBG 2.0                                |
| **Input Formats**  | JPEG, PNG, WebP, GIF, AVIF via URL           |
| **Output Formats** | PNG with alpha channel transparency          |
| **Resolution**     | Up to 1024x1024 (preserves input dimensions) |
| **License**        | Commercial use with licensed training data   |

[API Documentation](https://fal.ai/models/fal-ai/bria/background/remove/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

\*\*Bria Background Replace ($0.023)** – RMBG 2.0 ($0.018) strips backgrounds cleanly, 22% more cost-effective. [Background Replace](https://fal.ai/models/fal-ai/bria/background/replace) adds generative fill capabilities for product staging workflows where you need both removal and context reconstruction.

\*\*Bria Product Shot ($0.023)** – RMBG 2.0 ($0.018) handles pure segmentation, while [Product Shot](https://fal.ai/models/fal-ai/bria/product-shot) combines removal with studio-quality scene generation for e-commerce listings. Product Shot trades simplicity for complete product photography automation at 28% higher cost.

\*\*Bria Expand Image ($0.023)** – RMBG 2.0 focuses on isolation; [Expand Image](https://fal.ai/models/fal-ai/bria/expand) handles outpainting for aspect ratio adjustments post-removal. Teams typically chain RMBG 2.0 into Expand for complete product asset workflows, with Expand adding generative borders at $0.023 per operation.

## Related

* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation
* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation

## Limitations

* `seed` range: 0 to 2147483647
* `num_images` range: 1 to 4


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-embed-product.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Embed Product API

> API reference for Bria Embed Product. Seamlessly integrate one or more products into a predefined scene with pixel-perfect control.

**Endpoint:** `POST https://fal.run/bria/embed-product`
**Endpoint ID:** `bria/embed-product`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/embed-product/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bria/embed-product",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bria/embed-product", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/bria/embed-product \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation

## Capabilities

* Reproducible generation (seed)
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="image_source" type="string">
  URL of the image.
</ParamField>

<ParamField body="products" type="list<EmbedItem>">
  List of products to embed in the image.
</ParamField>

<ParamField body="seed" type="integer" default="5555">
  Random seed for reproducibility. Default value: `5555`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If true, returns the image directly in the response (increases latency).
</ParamField>

### Output Schema

<ParamField body="image" type="Image" required>
  Generated image with products embedded.
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed used for generation.
</ParamField>

## Input Example

```json theme={null}
{
  "image_source": "https://bria-datasets.s3.us-east-1.amazonaws.com/embed-product/an_empty_living_room_0.png",
  "products": [
    {
      "coordinates": {
        "height": 300,
        "width": 100,
        "x": 300,
        "y": 317
      },
      "image_source": "https://bria-datasets.s3.us-east-1.amazonaws.com/embed-product/a_standing_lamp_over_white_background_0.png"
    },
    {
      "coordinates": {
        "height": 156,
        "width": 120,
        "x": 646,
        "y": 287
      },
      "image_source": "https://bria-datasets.s3.us-east-1.amazonaws.com/embed-product/a_wall_picture_on_white_background_0.png"
    }
  ],
  "seed": 5555,
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "image": {
    "url": "",
    "content_type": "image/png",
    "file_name": "z9RV14K95DvU.png",
    "file_size": 4404019,
    "width": 1024,
    "height": 1024
  }
}
```


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-eraser.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Eraser API

> API reference for Bria Eraser. Bria Eraser enables precise removal of unwanted objects from images while maintaining high-quality outputs. Trained exclusively on licensed data for safe and risk-free c

**Endpoint:** `POST https://fal.run/fal-ai/bria/eraser`
**Endpoint ID:** `fal-ai/bria/eraser`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/eraser/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bria/eraser",
      arguments={
          "image_url": "https://storage.googleapis.com/falserverless/bria/bria_eraser_img.png",
          "mask_url": "https://storage.googleapis.com/falserverless/bria/bria_eraser_mask.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bria/eraser", {
    input: {
        image_url: "https://storage.googleapis.com/falserverless/bria/bria_eraser_img.png",
        mask_url: "https://storage.googleapis.com/falserverless/bria/bria_eraser_mask.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bria/eraser \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://storage.googleapis.com/falserverless/bria/bria_eraser_img.png",
    "mask_url": "https://storage.googleapis.com/falserverless/bria/bria_eraser_mask.png"
  }'
  ```
</CodeGroup>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation

## Capabilities

* Image input
* Inpainting (mask support)
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="image_url" type="string" required>
  Input Image to erase from
</ParamField>

<ParamField body="mask_url" type="string" required>
  The URL of the binary mask image that represents the area that will be cleaned.
</ParamField>

<ParamField body="mask_type" type="MaskTypeEnum" default="manual">
  You can use this parameter to specify the type of the input mask from the list. 'manual' opttion should be used in cases in which the mask had been generated by a user (e.g. with a brush tool), and 'automatic' mask type should be used when mask had been generated by an algorithm like 'SAM'. Default value: `"manual"`

  Possible values: `manual`, `automatic`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="preserve_alpha" type="boolean" default="false">
  If set to true, attempts to preserve the alpha channel of the input image.
</ParamField>

### Output Schema

<ParamField body="image" type="Image" required>
  The generated image
</ParamField>

## Input Example

```json theme={null}
{
  "image_url": "https://storage.googleapis.com/falserverless/bria/bria_eraser_img.png",
  "mask_url": "https://storage.googleapis.com/falserverless/bria/bria_eraser_mask.png",
  "mask_type": "manual",
  "sync_mode": false,
  "preserve_alpha": false
}
```

## Output Example

```json theme={null}
{
  "image": {
    "content_type": "image/png",
    "url": "https://storage.googleapis.com/falserverless/bria/bria_eraser_res.png"
  }
}
```

## Limitations

* `mask_type` restricted to: `manual`, `automatic`


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-expand.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Expand API

> API reference for Bria Expand. Bria Expand expands images beyond their borders in high quality. Trained exclusively on licensed data for safe and risk-free commercial use. Access the model's source co

**Endpoint:** `POST https://fal.run/fal-ai/bria/expand`
**Endpoint ID:** `fal-ai/bria/expand`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/expand/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bria/expand",
      arguments={
          "image_url": "https://storage.googleapis.com/falserverless/model_tests/orange.png",
          "canvas_size": [
              1200,
              674
          ]
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bria/expand", {
    input: {
        image_url: "https://storage.googleapis.com/falserverless/model_tests/orange.png",
        canvas_size: [
          1200,
          674
        ]
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bria/expand \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://storage.googleapis.com/falserverless/model_tests/orange.png",
    "canvas_size": [
      1200,
      674
    ]
  }'
  ```
</CodeGroup>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation

## Capabilities

* Image input
* Aspect ratio control
* Text prompt input
* Reproducible generation (seed)
* Negative prompts
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="image_url" type="string" required>
  The URL of the input image.
</ParamField>

<ParamField body="canvas_size" type="list<integer>" required>
  The desired size of the final image, after the expansion. should have an area of less than 5000x5000 pixels.
</ParamField>

<ParamField body="aspect_ratio" type="Enum">
  The desired aspect ratio of the final image. Will be used over original\_image\_size and original\_image\_location if provided.

  Possible values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`
</ParamField>

<ParamField body="original_image_size" type="list<integer>">
  The desired size of the original image, inside the full canvas. Ensure that the ratio of input image foreground or main subject to the canvas area is greater than 15% to achieve optimal results. Will be ignored if aspect\_ratio is provided.
</ParamField>

<ParamField body="original_image_location" type="list<integer>">
  The desired location of the original image, inside the full canvas. Provide the location of the upper left corner of the original image. The location can also be outside the canvas (the original image will be cropped). Will be ignored if aspect\_ratio is provided.
</ParamField>

<ParamField body="prompt" type="string" default="">
  Text on which you wish to base the image expansion. This parameter is optional. Bria currently supports prompts in English only, excluding special characters. Default value: `""`
</ParamField>

<ParamField body="seed" type="integer">
  You can choose whether you want your generated expension to be random or predictable. You can recreate the same result in the future by using the seed value of a result from the response. You can exclude this parameter if you are not interested in recreating your results. This parameter is optional.

  Range: `0` to `2147483647`
</ParamField>

<ParamField body="negative_prompt" type="string" default="">
  The negative prompt you would like to use to generate images. Default value: `""`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="image" type="Image" required>
  The generated image
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed value used for generation.
</ParamField>

## Input Example

```json theme={null}
{
  "image_url": "https://storage.googleapis.com/falserverless/model_tests/orange.png",
  "canvas_size": [
    1200,
    674
  ],
  "original_image_size": [
    610,
    855
  ],
  "original_image_location": [
    301,
    -66
  ],
  "prompt": "",
  "negative_prompt": "",
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "image": {
    "content_type": "image/png",
    "file_name": "afa402a35ea742cdb5c3e219b2b19bfb.png",
    "file_size": 1471342,
    "height": 674,
    "url": "https://v3.fal.media/files/koala/8np-spgxxG-I1r3cjthRV_afa402a35ea742cdb5c3e219b2b19bfb.png",
    "width": 1200
  }
}
```

## Limitations

* `seed` range: 0 to 2147483647


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-fibo.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Fibo API

> API reference for Bria Fibo. SOTA Open source model trained on licensed data, transforming intent into structured control for precise, high-quality AI image generation in enterprise and agentic workfl

**Endpoint:** `POST https://fal.run/bria/fibo/generate`
**Endpoint ID:** `bria/fibo/generate`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo/generate/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bria/fibo/generate",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bria/fibo/generate", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/bria/fibo/generate \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Examples

> 3D animated anthropomorphic fox character, adventurous hero pose, orange and white fur with teal accents, wearing leather adventure vest with pouches, confident expression, stylized proportions, standing in T-pose, neutral gray background, game-ready character design, cel-shaded rendering style

<Frame>
  <img src="https://v3b.fal.media/files/b/rabbit/SVbriPvB6AgcT6ZgoA8ci_e3d0d38608a443cc81dd1ba138e6c985.png" alt="Generated image: 3D animated anthropomorphic fox character, adventurous hero pose, orange and whi" />
</Frame>

> A hyper-detailed, ultra-fluffy owl sitting in the trees at night, looking directly at the camera with wide, adorable, expressive eyes. Its feathers are soft and voluminous, catching the cool moonlight with subtle silver highlights. The owl's gaze is curious and full of charm, giving it a whimsical, ...

<Frame>
  <img src="https://v3b.fal.media/files/b/penguin/96Py3o4WxTC-hErIb4yRC_be2f4924640c46fe8ce2277eab6fb22d.png" alt="Generated image: A hyper-detailed, ultra-fluffy owl sitting in the trees at night, looking direct" />
</Frame>

> A glowing jack-o’-lantern carved from a rich orange pumpkin, its jagged grin and triangular eyes illuminated by a warm flickering candle inside. The surface shows natural texture and faint imperfections, with soft shadows cast on the ground. Set in a dimly lit autumn scene with fallen leaves, cool m...

<Frame>
  <img src="https://v3b.fal.media/files/b/lion/5WUu7709UwZxX8tuzfCyi_4d984ad95a444ef8aa4bfcb7d19b2352.png" alt="Generated image: A glowing jack-o’-lantern carved from a rich orange pumpkin, its jagged grin and" />
</Frame>

### Input Schema

<ParamField body="prompt" type="string">
  Prompt for image generation.
</ParamField>

<ParamField body="structured_prompt" type="StructuredPrompt">
  The structured prompt to generate an image from.
</ParamField>

<ParamField body="image_url" type="string">
  Reference image (file or URL).
</ParamField>

<ParamField body="seed" type="integer" default="5555">
  Random seed for reproducibility. Default value: `5555`
</ParamField>

<ParamField body="steps_num" type="integer" default="50">
  Number of inference steps. Default value: `50`

  Range: `20` to `50`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
  Aspect ratio. Options: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9 Default value: `"1:1"`

  Possible values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`
</ParamField>

<ParamField body="negative_prompt" type="string" default="">
  Negative prompt for image generation. Default value: `""`
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="1MP">
  Output image resolution Default value: `"1MP"`

  Possible values: `1MP`, `4MP`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If true, returns the image directly in the response (increases latency).
</ParamField>

### Output Schema

<ParamField body="image" type="Image" required>
  Generated image.
</ParamField>

<ParamField body="images" type="list<object>" default="">
  Generated images.
</ParamField>

<ParamField body="structured_prompt" type="Structured Prompt" required>
  Current prompt.
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "A hyper-detailed, ultra-fluffy owl sitting in the trees at night, looking directly at the camera with wide, adorable, expressive eyes. Its feathers are soft and voluminous, catching the cool moonlight with subtle silver highlights. The owl’s gaze is curious and full of charm, giving it a whimsical, storybook-like personality.",
  "seed": 5555,
  "steps_num": 50,
  "aspect_ratio": "1:1",
  "negative_prompt": "",
  "resolution": "1MP",
  "sync_mode": false
}
```

### Output Example

```json theme={null}
{
  "image": {
    "url": "",
    "content_type": "image/png",
    "file_name": "z9RV14K95DvU.png",
    "file_size": 4404019,
    "width": 1024,
    "height": 1024
  },
  "images": []
}
```

Text-to-image models have mastered imagination - but not control. FIBO changes that.
FIBO is trained on structured JSON captions up to 1,000+ words and designed to understand and control different visual parameters such as lighting, composition, color, and camera settings, enabling precise and reproducible outputs.
With only 8 billion parameters, FIBO provides a new level of image quality, prompt adherence and professional control. Enterprises demand repeatability, governance, and transparency. FIBO delivers - open-source, rights-clear, and ready for production.

# 🔑 Key Features

* LLM guided JSON-native prompting: structured schemas up to 1,000+ words (lighting, camera, composition, DoF)
* Iterative controlled generation: generate images from short prompts or keep refining and get inspiration from detailed JSONs and input images
* Disentangled control: tweak a single attribute (e.g., camera angle) without breaking the scene.
* Enterprise-grade: 100% licensed data; governance, repeatability, and legal clarity.
* Strong prompt adherence: high alignment on PRISM-style evaluations.

# Benchmark:

![benchmark](https://v3b.fal.media/files/b/kangaroo/ISYj3rTKlV1LvG76ZGJcb_Screenshot%202025-10-29%20at%207.54.17%3FAM.png)

# 💡 What can you do with FIBO?

## Generate

Start with a quick idea. FIBO’s language model expands your short prompt into a rich, structured JSON prompt, then generates the image. You get both the image and the expanded prompt.

## Refine

Continue from a detailed structured prompt and add a small instruction - for example, “backlit,” “85 mm,” or “warmer skin tones.” FIBO updates only the requested attributes, re-generates the image, and returns the refined prompt alongside it.

## Inspire

Provide an image instead of text. FIBO’s vision-language model extracts a detailed prompt describing it, combines that with your creative intent, and generates new, related images - ideal for exploring new directions without altering the original.

## Limitations

* `steps_num` range: 20 to 50
* `resolution` restricted to: `1MP`, `4MP`


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-fibo-edit.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Fibo Edit API

> API reference for Bria Fibo Edit. A high-quality editing model that achieves maximum controllability and transparency by combining JSON + Mask + Image.

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/edit`
    **Endpoint ID:** `bria/fibo-edit/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/edit",
          arguments={},
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/edit", {
        input: {},
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{}'
      ```
    </CodeGroup>

    ## Examples

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8b696e/RDNU7DokXPnC6AasT4fVD_0943bf8f73d5424eb3cfb656abb4ce49.png" alt="Example output from Fibo Edit" />
    </Frame>

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8b6984/5kSvXeLDU0_7iAqbeT9ht_0998cd4960b54a34b614b94411f339e3.png" alt="Example output from Fibo Edit" />
    </Frame>

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8b6993/Bmgq09cV1iMd0hKYe-uXv_2d8cc1342c0a4a44ad26ed229f77fefb.png" alt="Example output from Fibo Edit" />
    </Frame>

    ### Input Schema

    <ParamField body="image_url" type="string">
      Reference image (file or URL).
    </ParamField>

    <ParamField body="mask_url" type="string">
      Mask image (file or URL). Optional
    </ParamField>

    <ParamField body="instruction" type="string">
      Instruction for image editing.
    </ParamField>

    <ParamField body="structured_instruction" type="StructuredInstruction">
      The structured prompt to generate an image from.
    </ParamField>

    <ParamField body="original_vgl" type="StructuredInstruction">
      The original vgl used to generate the image.
    </ParamField>

    <ParamField body="new_vgl" type="StructuredInstruction">
      The new vgl describing image after edit.
    </ParamField>

    <ParamField body="seed" type="integer" default="5555">
      Random seed for reproducibility. Default value: `5555`
    </ParamField>

    <ParamField body="steps_num" type="integer" default="30">
      Number of inference steps. Default value: `30`

      Range: `20` to `50`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      Negative prompt for image generation. Default value: `""`
    </ParamField>

    <ParamField body="guidance_scale" type="float | integer" default="5">
      Guidance scale for text. Default value: `5`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If true, returns the image directly in the response (increases latency).
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://v3b.fal.media/files/b/0a8b07e8/GYKVk2EVivg_MC3jRRZi3_png%20-%202026-01-13T094835.850%20(3).png",
      "instruction": "change lighting to starlight nighttime",
      "seed": 5555,
      "steps_num": 30,
      "negative_prompt": "",
      "guidance_scale": 5,
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": [
        {
          "url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/ewT7wv-jMgkqs7z7xQNNL_e8707c299d034feab7a64d903118098f.png"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Restore">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/restore`
    **Endpoint ID:** `bria/fibo-edit/restore`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/restore/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/restore",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T134151.337.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/restore", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T134151.337.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/restore \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T134151.337.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T134151.337.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Relight">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/relight`
    **Endpoint ID:** `bria/fibo-edit/relight`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/relight/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/relight",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/bria_result+-+2026-01-13T095546.173.png",
              "light_direction": "front",
              "light_type": "soft overcast daylight lighting"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/relight", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/bria_result+-+2026-01-13T095546.173.png",
            light_direction: "front",
            light_type: "soft overcast daylight lighting"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/relight \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/bria_result+-+2026-01-13T095546.173.png",
        "light_direction": "front",
        "light_type": "soft overcast daylight lighting"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="light_direction" type="Enum" required>
      Where the light comes from.

      Possible values: `front`, `side`, `bottom`, `top-down`
    </ParamField>

    <ParamField body="light_type" type="LightTypeEnum" required>
      The quality/style/time of day.

      Possible values: `midday`, `blue hour light`, `low-angle sunlight`, `sunrise light`, `spotlight on subject`, `overcast light`, `soft overcast daylight lighting`, `cloud-filtered lighting`, `fog-diffused lighting`, `moonlight lighting`, `starlight nighttime`, `soft bokeh lighting`, `harsh studio lighting`
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/bria_result+-+2026-01-13T095546.173.png",
      "light_direction": "front",
      "light_type": "soft overcast daylight lighting"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Sketch_to_colored_image">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/sketch_to_colored_image`
    **Endpoint ID:** `bria/fibo-edit/sketch_to_colored_image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/sketch_to_colored_image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/sketch_to_colored_image",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_b_w_sketch_of_a_cat.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/sketch_to_colored_image", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_b_w_sketch_of_a_cat.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/sketch_to_colored_image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_b_w_sketch_of_a_cat.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_b_w_sketch_of_a_cat.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Erase_by_text">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/erase_by_text`
    **Endpoint ID:** `bria/fibo-edit/erase_by_text`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/erase_by_text/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/erase_by_text",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
              "object_name": "Table"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/erase_by_text", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
            object_name: "Table"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/erase_by_text \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
        "object_name": "Table"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="object_name" type="string" required>
      The name of the object to remove.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
      "object_name": "Table"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Colorize">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/colorize`
    **Endpoint ID:** `bria/fibo-edit/colorize`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/colorize/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/colorize",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T083840.113.png",
              "color": "contemporary color"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/colorize", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T083840.113.png",
            color: "contemporary color"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/colorize \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T083840.113.png",
        "color": "contemporary color"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="color" type="ColorEnum" required>
      Select the color palette or aesthetic for the output image

      Possible values: `contemporary color`, `vivid color`, `black and white colors`, `sepia vintage`
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/png+-+2026-01-13T083840.113.png",
      "color": "contemporary color"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Restyle">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/restyle`
    **Endpoint ID:** `bria/fibo-edit/restyle`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/restyle/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/restyle",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/high_camera_angle_warm_filter.png",
              "style": "3D Render"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/restyle", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/high_camera_angle_warm_filter.png",
            style: "3D Render"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/restyle \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/high_camera_angle_warm_filter.png",
        "style": "3D Render"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="style" type="StyleEnum" required>
      Select the desired artistic style for the output image.

      Possible values: `3D Render`, `Cubism`, `Oil Painting`, `Anime`, `Cartoon`, `Coloring Book`, `Retro Ad`, `Pop Art Halftone`, `Vector Art`, `Story Board`, `Art Nouveau`, `Cross Etching`, `Wood Cut`
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/high_camera_angle_warm_filter.png",
      "style": "3D Render"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Rewrite_text">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/rewrite_text`
    **Endpoint ID:** `bria/fibo-edit/rewrite_text`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/rewrite_text/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/rewrite_text",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_an_image_of_cake__with_text_on_it_saying___Hi_there__.png",
              "new_text": "FIBO Edit!"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/rewrite_text", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_an_image_of_cake__with_text_on_it_saying___Hi_there__.png",
            new_text: "FIBO Edit!"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/rewrite_text \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_an_image_of_cake__with_text_on_it_saying___Hi_there__.png",
        "new_text": "FIBO Edit!"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="new_text" type="string" required>
      The new text string to appear in the image.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_an_image_of_cake__with_text_on_it_saying___Hi_there__.png",
      "new_text": "FIBO Edit!"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Add_object_by_text">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/add_object_by_text`
    **Endpoint ID:** `bria/fibo-edit/add_object_by_text`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/add_object_by_text/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/add_object_by_text",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
              "instruction": "Place a red vase with flowers on the table."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/add_object_by_text", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
            instruction: "Place a red vase with flowers on the table."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/add_object_by_text \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
        "instruction": "Place a red vase with flowers on the table."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="instruction" type="string" required>
      The full natural language command describing what to add and where.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/an_empty_table_in_living_room.png",
      "instruction": "Place a red vase with flowers on the table."
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Blend">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/blend`
    **Endpoint ID:** `bria/fibo-edit/blend`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/blend/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/blend",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/shirt.png",
              "instruction": "Place the art on the shirt, keep the art exactly the same"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/blend", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/shirt.png",
            instruction: "Place the art on the shirt, keep the art exactly the same"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/blend \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/shirt.png",
        "instruction": "Place the art on the shirt, keep the art exactly the same"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="instruction" type="string" required>
      Instruct what elements you would like to blend in your image.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/shirt.png",
      "instruction": "Place the art on the shirt, keep the art exactly the same"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Replace_object_by_text">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/replace_object_by_text`
    **Endpoint ID:** `bria/fibo-edit/replace_object_by_text`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/replace_object_by_text/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/replace_object_by_text",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/a_bowl_of_fruits__should_have_a_red_apple.png",
              "instruction": "Replace the red apple with a green pear"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/replace_object_by_text", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/a_bowl_of_fruits__should_have_a_red_apple.png",
            instruction: "Replace the red apple with a green pear"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/replace_object_by_text \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/a_bowl_of_fruits__should_have_a_red_apple.png",
        "instruction": "Replace the red apple with a green pear"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="instruction" type="string" required>
      The full natural language command describing what to replace.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/a_bowl_of_fruits__should_have_a_red_apple.png",
      "instruction": "Replace the red apple with a green pear"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>

  <Tab title="Reseason">
    **Endpoint:** `POST https://fal.run/bria/fibo-edit/reseason`
    **Endpoint ID:** `bria/fibo-edit/reseason`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-edit/reseason/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/fibo-edit/reseason",
          arguments={
              "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_realistic_image_of_a_green_field_in_the_spring__also_add_trees.png",
              "season": "winter"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/fibo-edit/reseason", {
        input: {
            image_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_realistic_image_of_a_green_field_in_the_spring__also_add_trees.png",
            season: "winter"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/fibo-edit/reseason \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_realistic_image_of_a_green_field_in_the_spring__also_add_trees.png",
        "season": "winter"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The source image.
    </ParamField>

    <ParamField body="season" type="SeasonEnum" required>
      The desired season.

      Possible values: `spring`, `summer`, `autumn`, `winter`
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Generated image.
    </ParamField>

    <ParamField body="images" type="list<Image>" default="">
      Generated images.
    </ParamField>

    <ParamField body="structured_instruction" type="Structured Instruction" required>
      Current instruction.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/Liza/create_a_realistic_image_of_a_green_field_in_the_spring__also_add_trees.png",
      "season": "winter"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      },
      "images": []
    }
    ```
  </Tab>
</Tabs>

## Related

* [Fibo Edit \[Restore\]](/model-api-reference/image-generation-api/fibo-edit) — Image Generation

## Limitations

* `steps_num` range: 20 to 50
* `light_direction` restricted to: `front`, `side`, `bottom`, `top-down`
* `color` restricted to: `contemporary color`, `vivid color`, `black and white colors`, `sepia vintage`
* `season` restricted to: `spring`, `summer`, `autumn`, `winter`


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-fibo-lite.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Fibo Lite API

> API reference for Bria Fibo Lite. Fibo Lite, the new addition to the Fibo model family, allows generating high-quality images with the same controllability of the JSON structured prompt with significa

**Endpoint:** `POST https://fal.run/bria/fibo-lite/generate`
**Endpoint ID:** `bria/fibo-lite/generate`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/fibo-lite/generate/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bria/fibo-lite/generate",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bria/fibo-lite/generate", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/bria/fibo-lite/generate \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Examples

> several coffee beans floating independently in mid air, the subject is red, in a red photo, red and black duotone image, red wash, red light, red lens, extreme close up, a dark black empty background, closeup, dramatic lighting with a strong red hue that gives the image a moody and intense atmospher...

<Frame>
  <img src="https://v3b.fal.media/files/b/0a8739b1/5PkOKEpdQu16ZkS3ovA92_e0d9e8ab6833478aa854cba5ca1c88ad.png" alt="Generated image: several coffee beans floating independently in mid air, the subject is red, in a" />
</Frame>

<Frame>
  <img src="https://v3b.fal.media/files/b/0a873af8/6YpzosRTtGfE40Iw28xvo_99cc31c90a474a42a3b64be2b1e6aacd.png" alt="Example output from Fibo Lite" />
</Frame>

<Frame>
  <img src="https://v3b.fal.media/files/b/0a873aed/b_8ygdKfq7HQnL5s8PD3J_5c4a1f3dca65408ba7bbc9cb45b1688a.png" alt="Example output from Fibo Lite" />
</Frame>

### Input Schema

<ParamField body="prompt" type="string">
  The prompt to generate.
</ParamField>

<ParamField body="structured_prompt" type="StructuredPrompt">
  The structured prompt to generate.
</ParamField>

<ParamField body="image_url" type="string">
  Input image URL
</ParamField>

<ParamField body="seed" type="integer" default="7">
  Seed for the random number generator. Default value: `7`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
  Aspect ratio. Options: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9 Default value: `"1:1"`

  Possible values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`
</ParamField>

<ParamField body="negative_prompt" type="string" default="">
  Negative prompt for image generation. Default value: `""`
</ParamField>

<ParamField body="steps_num" type="integer" default="8">
  Number of inference steps. Default value: `8`

  Range: `4` to `30`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If true, returns the image directly in the response (increases latency).
</ParamField>

### Output Schema

<ParamField body="image" type="Image" required>
  Generated image.
</ParamField>

<ParamField body="images" type="list<object>">
  Generated images.
</ParamField>

<ParamField body="structured_prompt" type="StructuredPrompt" required>
  Current prompt.
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "Oil painting of a fluffy, wide-eyed cat sitting upright, holding a small wooden sign reading \"Feed Me.\" Rich textures, dramatic brushstrokes, warm tones, and vintage charm.",
  "seed": 7,
  "aspect_ratio": "1:1",
  "negative_prompt": "",
  "steps_num": 8,
  "sync_mode": false
}
```

### Output Example

```json theme={null}
{
  "image": {
    "url": "",
    "content_type": "image/png",
    "file_name": "z9RV14K95DvU.png",
    "file_size": 4404019,
    "width": 1024,
    "height": 1024
  },
  "structured_prompt": {
    "short_description": "",
    "objects": [
      {
        "description": "",
        "location": "",
        "relationship": ""
      }
    ],
    "background_setting": "",
    "lighting": {
      "conditions": "",
      "direction": ""
    },
    "aesthetics": {
      "composition": "",
      "color_scheme": "",
      "mood_atmosphere": "",
      "aesthetic_score": "",
      "preference_score": ""
    },
    "text_render": [
      {
        "text": "",
        "location": "",
        "size": "",
        "color": "",
        "font": ""
      }
    ],
    "context": "",
    "artistic_style": ""
  }
}
```

**Overview**

Fibo Lite, the new addition to the Fibo model family, allows generating **high-quality** images with the same **controllability** of the JSON structured prompt, while using significantly fewer inference steps, resulting in significantly **improved latency.**

This is a two-stage distilled model for the [FIBO](https://huggingface.co/briaai/FIBO) text-to-image model, combining:

1. CFG Distillation: First, we distill classifier-free guidance into the model, enabling inference with Guidance Scale = 1.0 (skipping the negative prompt pass).
2. SCFM (Shortcutting Flow Matching): On top of the CFG-distilled merged model, we apply velocity field self-distillation to enable efficient few-step sampling.

### **🔑 Key Benefits**

* Two-Stage Distillation: Combines CFG distillation with SCFM for maximum efficiency—the SCFM was trained on top of the already CFG-distilled merged model.
* Few-Step Generation: SCFM enables efficient sampling in significantly fewer inference steps.
* No CFG Overhead: Running at guidance\_scale=1 means calculating the noise prediction only once per step instead of twice.
* Quality Tradeoff: As a distillation approach, there is a slight quality degradation compared to the full model at CFG=5, but the speed gains make it ideal for rapid iteration and production workflows.
* Drop-in Replacement: Works seamlessly with existing FIBO workflows—just set guidance\_scale=1.0.
* Memory Efficient: Minimal additional GPU memory overhead.

## Limitations

* `steps_num` range: 4 to 30


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-genfill.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Genfill API

> API reference for Bria Genfill. Bria GenFill enables high-quality object addition or visual transformation. Trained exclusively on licensed data for safe and risk-free commercial use. Access the model

**Endpoint:** `POST https://fal.run/fal-ai/bria/genfill`
**Endpoint ID:** `fal-ai/bria/genfill`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/genfill/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bria/genfill",
      arguments={
          "image_url": "https://storage.googleapis.com/falserverless/bria/bria_genfill_img.png",
          "mask_url": "https://storage.googleapis.com/falserverless/bria/bria_genfill_mask.png",
          "prompt": "A red delicious cherry"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bria/genfill", {
    input: {
        image_url: "https://storage.googleapis.com/falserverless/bria/bria_genfill_img.png",
        mask_url: "https://storage.googleapis.com/falserverless/bria/bria_genfill_mask.png",
        prompt: "A red delicious cherry"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bria/genfill \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://storage.googleapis.com/falserverless/bria/bria_genfill_img.png",
    "mask_url": "https://storage.googleapis.com/falserverless/bria/bria_genfill_mask.png",
    "prompt": "A red delicious cherry"
  }'
  ```
</CodeGroup>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation

## Capabilities

* Image input
* Inpainting (mask support)
* Text prompt input
* Negative prompts
* Reproducible generation (seed)
* Batch generation
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="image_url" type="string" required>
  Input Image to erase from
</ParamField>

<ParamField body="mask_url" type="string" required>
  The URL of the binary mask image that represents the area that will be cleaned.
</ParamField>

<ParamField body="prompt" type="string" required>
  The prompt you would like to use to generate images.
</ParamField>

<ParamField body="negative_prompt" type="string" default="">
  The negative prompt you would like to use to generate images. Default value: `""`
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.

  Range: `0` to `2147483647`
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  Number of Images to generate. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<Image>" required>
  Generated Images
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed value used for generation.
</ParamField>

## Input Example

```json theme={null}
{
  "image_url": "https://storage.googleapis.com/falserverless/bria/bria_genfill_img.png",
  "mask_url": "https://storage.googleapis.com/falserverless/bria/bria_genfill_mask.png",
  "prompt": "A red delicious cherry",
  "negative_prompt": "",
  "num_images": 1,
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "content_type": "image/png",
      "file_name": "a0d138e6820c4ad58f1fd3c758f16047.png",
      "file_size": 1064550,
      "height": 768,
      "url": "https://storage.googleapis.com/falserverless/bria/bria_genfill_res.png",
      "width": 1024
    }
  ]
}
```

## Limitations

* `seed` range: 0 to 2147483647
* `num_images` range: 1 to 4


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-product-shot.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Product Shot API

> API reference for Bria Product Shot. Place any product in any scenery with just a prompt or reference image while maintaining high integrity of the product. Trained exclusively on licensed data for sa

**Endpoint:** `POST https://fal.run/fal-ai/bria/product-shot`
**Endpoint ID:** `fal-ai/bria/product-shot`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/product-shot/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bria/product-shot",
      arguments={
          "image_url": "https://storage.googleapis.com/falserverless/bria/bria_product_fg.jpg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bria/product-shot", {
    input: {
        image_url: "https://storage.googleapis.com/falserverless/bria/bria_product_fg.jpg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bria/product-shot \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://storage.googleapis.com/falserverless/bria/bria_product_fg.jpg"
  }'
  ```
</CodeGroup>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation

## Capabilities

* Image input
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="image_url" type="string" required>
  The URL of the product shot to be placed in a lifestyle shot. If both image\_url and image\_file are provided, image\_url will be used. Accepted formats are jpeg, jpg, png, webp. Maximum file size 12MB.
</ParamField>

<ParamField body="scene_description" type="string">
  Text description of the new scene or background for the provided product shot. Bria currently supports prompts in English only, excluding special characters.
</ParamField>

<ParamField body="ref_image_url" type="string" default="">
  The URL of the reference image to be used for generating the new scene or background for the product shot. Use "" to leave empty.Either ref\_image\_url or scene\_description has to be provided but not both. If both ref\_image\_url and ref\_image\_file are provided, ref\_image\_url will be used. Accepted formats are jpeg, jpg, png, webp. Default value: `""`
</ParamField>

<ParamField body="optimize_description" type="boolean" default="true">
  Whether to optimize the scene description Default value: `true`
</ParamField>

<ParamField body="num_results" type="integer" default="1">
  The number of lifestyle product shots you would like to generate. You will get num\_results x 10 results when placement\_type=automatic and according to the number of required placements x num\_results if placement\_type=manual\_placement. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="fast" type="boolean" default="true">
  Whether to use the fast model Default value: `true`
</ParamField>

<ParamField body="placement_type" type="PlacementTypeEnum" default="manual_placement">
  This parameter allows you to control the positioning of the product in the image. Choosing 'original' will preserve the original position of the product in the image. Choosing 'automatic' will generate results with the 10 recommended positions for the product. Choosing 'manual\_placement' will allow you to select predefined positions (using the parameter 'manual\_placement\_selection'). Selecting 'manual\_padding' will allow you to control the position and size of the image by defining the desired padding in pixels around the product. Default value: `"manual_placement"`

  Possible values: `original`, `automatic`, `manual_placement`, `manual_padding`
</ParamField>

<ParamField body="original_quality" type="boolean" default="false">
  This flag is only relevant when placement\_type=original. If true, the output image retains the original input image's size; otherwise, the image is scaled to 1 megapixel (1MP) while preserving its aspect ratio.
</ParamField>

<ParamField body="shot_size" type="list<integer>" default="1000,1000">
  The desired size of the final product shot. For optimal results, the total number of pixels should be around 1,000,000. This parameter is only relevant when placement\_type=automatic or placement\_type=manual\_placement.
</ParamField>

<ParamField body="manual_placement_selection" type="ManualPlacementSelectionEnum" default="bottom_center">
  If you've selected placement\_type=manual\_placement, you should use this parameter to specify which placements/positions you would like to use from the list. You can select more than one placement in one request. Default value: `"bottom_center"`

  Possible values: `upper_left`, `upper_right`, `bottom_left`, `bottom_right`, `right_center`, `left_center`, `upper_center`, `bottom_center`, `center_vertical`, `center_horizontal`
</ParamField>

<ParamField body="padding_values" type="list<integer>">
  The desired padding in pixels around the product, when using placement\_type=manual\_padding. The order of the values is \[left, right, top, bottom]. For optimal results, the total number of pixels, including padding, should be around 1,000,000. It is recommended to first use the product cutout API, get the cutout and understand the size of the result, and then define the required padding and use the cutout as an input for this API.
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<Image>" required>
  The generated images
</ParamField>

## Input Example

```json theme={null}
{
  "image_url": "https://storage.googleapis.com/falserverless/bria/bria_product_fg.jpg",
  "scene_description": "on a rock, next to the ocean, dark theme",
  "ref_image_url": "https://storage.googleapis.com/falserverless/bria/bria_product_bg.jpg",
  "optimize_description": true,
  "num_results": 1,
  "fast": true,
  "placement_type": "manual_placement",
  "original_quality": false,
  "shot_size": [
    1000,
    1000
  ],
  "manual_placement_selection": "bottom_center",
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "content_type": "image/png",
      "url": "https://storage.googleapis.com/falserverless/bria/bria_product_res.png"
    }
  ]
}
```

## Limitations

* `num_results` range: 1 to 4
* `placement_type` restricted to: `original`, `automatic`, `manual_placement`, `manual_padding`


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-reimagine.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Reimagine API

> API reference for Bria Reimagine. Structure Reference allows generating new images while preserving the structure of an input image, guided by text prompts. Perfect for transforming sketches, illustra

**Endpoint:** `POST https://fal.run/fal-ai/bria/reimagine`
**Endpoint ID:** `fal-ai/bria/reimagine`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/reimagine/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bria/reimagine",
      arguments={
          "prompt": "A 2d illustration of a dog in a vibrant park"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bria/reimagine", {
    input: {
        prompt: "A 2d illustration of a dog in a vibrant park"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bria/reimagine \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A 2d illustration of a dog in a vibrant park"
  }'
  ```
</CodeGroup>

## Capabilities

* Text prompt input
* Reproducible generation (seed)
* Adjustable inference steps
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt you would like to use to generate images.
</ParamField>

<ParamField body="structure_image_url" type="string" default="">
  The URL of the structure reference image. Use "" to leave empty. Accepted formats are jpeg, jpg, png, webp. Default value: `""`
</ParamField>

<ParamField body="structure_ref_influence" type="float" default="0.75">
  The influence of the structure reference on the generated image. Default value: `0.75`
</ParamField>

<ParamField body="num_results" type="integer" default="1">
  How many images you would like to generate. When using any Guidance Method, Value is set to 1. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.

  Range: `0` to `2147483647`
</ParamField>

<ParamField body="fast" type="boolean" default="true">
  Whether to use the fast model Default value: `true`
</ParamField>

<ParamField body="num_inference_steps" type="integer" default="30">
  The number of iterations the model goes through to refine the generated image. This parameter is optional. Default value: `30`

  Range: `20` to `50`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<Image>" required>
  The generated images
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed value used for generation.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A 2d illustration of a dog in a vibrant park",
  "structure_image_url": "https://storage.googleapis.com/falserverless/bria/bria_reimagine_input.png",
  "structure_ref_influence": 0.15,
  "num_results": 1,
  "fast": true,
  "num_inference_steps": 30,
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "content_type": "image/png",
      "url": "https://storage.googleapis.com/falserverless/bria/bria_reimagine_output.png"
    }
  ]
}
```

## Limitations

* `num_results` range: 1 to 4
* `seed` range: 0 to 2147483647
* `num_inference_steps` range: 20 to 50


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-replace-background.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Replace Background API

> API reference for Bria Replace Background. Creates enriched product shots by placing them in various environments using textual descriptions.

**Endpoint:** `POST https://fal.run/bria/replace-background`
**Endpoint ID:** `bria/replace-background`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/replace-background/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bria/replace-background",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bria/replace-background", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/bria/replace-background \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation

## Capabilities

* Text prompt input
* Image input
* Reproducible generation (seed)
* Negative prompts
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="prompt" type="string">
  Prompt for background replacement.
</ParamField>

<ParamField body="image_url" type="string" default="https://v3b.fal.media/files/b/0a8bea8c/Mztgx0NG3HPdby-4iPqwH_a_coffee_machine_standing_in_the_kitchen.png">
  Reference image (file or URL). Default value: `"https://v3b.fal.media/files/b/0a8bea8c/Mztgx0NG3HPdby-4iPqwH_a_coffee_machine_standing_in_the_kitchen.png"`
</ParamField>

<ParamField body="seed" type="integer" default="4925634">
  Random seed for reproducibility. Default value: `4925634`
</ParamField>

<ParamField body="steps_num" type="integer" default="30">
  Number of inference steps. Default value: `30`
</ParamField>

<ParamField body="negative_prompt" type="string" default="">
  Negative prompt for background replacement. Default value: `""`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If true, returns the image directly in the response (increases latency).
</ParamField>

### Output Schema

<ParamField body="image" type="Image" required>
  Generated image.
</ParamField>

<ParamField body="images" type="list<object>">
  Generated images.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "On a smooth kitchen counter in front of a blue and white patterned ceramic tile wall. A yellow ceramic mug sits to the right. Shot from a straight-on front angle.",
  "image_url": "https://v3b.fal.media/files/b/0a8bea8c/Mztgx0NG3HPdby-4iPqwH_a_coffee_machine_standing_in_the_kitchen.png",
  "seed": 4925634,
  "steps_num": 30,
  "negative_prompt": "",
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "image": {
    "url": "",
    "content_type": "image/png",
    "file_name": "z9RV14K95DvU.png",
    "file_size": 4404019,
    "width": 1024,
    "height": 1024
  }
}
```


# https://fal.ai/docs/model-api-reference/image-generation-api/bria-text-to-image.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Text To Image API

> API reference for Bria Text To Image. Bria's Text-to-Image model for HD images. Trained exclusively on licensed data for safe and risk-free commercial use. Available also as source code and weights. F

<Tabs>
  <Tab title="Hd">
    **Endpoint:** `POST https://fal.run/fal-ai/bria/text-to-image/hd`
    **Endpoint ID:** `fal-ai/bria/text-to-image/hd`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/text-to-image/hd/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bria/text-to-image/hd",
          arguments={
              "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bria/text-to-image/hd", {
        input: {
            prompt: "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bria/text-to-image/hd \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt you would like to use to generate images.
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      The negative prompt you would like to use to generate images. Default value: `""`
    </ParamField>

    <ParamField body="num_images" type="integer" default="4">
      How many images you would like to generate. When using any Guidance Method, Value is set to 1. Default value: `4`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the image. When a guidance method is being used, the aspect ratio is defined by the guidance image and this parameter is ignored. Default value: `"1:1"`

      Possible values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.

      Range: `0` to `2147483647`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="30">
      The number of iterations the model goes through to refine the generated image. This parameter is optional. Default value: `30`

      Range: `20` to `50`
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `5`

      Range: `0` to `20`
    </ParamField>

    <ParamField body="prompt_enhancement" type="boolean" default="false">
      When set to true, enhances the provided prompt by generating additional, more descriptive variations, resulting in more diverse and creative output images.
    </ParamField>

    <ParamField body="medium" type="MediumEnum">
      Which medium should be included in your generated images. This parameter is optional.

      Possible values: `photography`, `art`
    </ParamField>

    <ParamField body="guidance" type="list<GuidanceInput>" default="">
      Guidance images to use for the generation. Up to 4 guidance methods can be combined during a single inference.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed value used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination.",
      "negative_prompt": "",
      "num_images": 4,
      "aspect_ratio": "1:1",
      "num_inference_steps": 30,
      "guidance_scale": 5,
      "prompt_enhancement": false,
      "guidance": [],
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "257cf8e7bd3a47c2959396343d5b38cf.png",
          "file_size": 3731290,
          "height": 1536,
          "url": "https://v3.fal.media/files/tiger/48e63e0K6C9XQYBuomoU-_257cf8e7bd3a47c2959396343d5b38cf.png",
          "width": 1536
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Base">
    **Endpoint:** `POST https://fal.run/fal-ai/bria/text-to-image/base`
    **Endpoint ID:** `fal-ai/bria/text-to-image/base`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/text-to-image/base/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bria/text-to-image/base",
          arguments={
              "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bria/text-to-image/base", {
        input: {
            prompt: "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bria/text-to-image/base \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt you would like to use to generate images.
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      The negative prompt you would like to use to generate images. Default value: `""`
    </ParamField>

    <ParamField body="num_images" type="integer" default="4">
      How many images you would like to generate. When using any Guidance Method, Value is set to 1. Default value: `4`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the image. When a guidance method is being used, the aspect ratio is defined by the guidance image and this parameter is ignored. Default value: `"1:1"`

      Possible values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.

      Range: `0` to `2147483647`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="30">
      The number of iterations the model goes through to refine the generated image. This parameter is optional. Default value: `30`

      Range: `20` to `50`
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `5`

      Range: `0` to `20`
    </ParamField>

    <ParamField body="prompt_enhancement" type="boolean" default="false">
      When set to true, enhances the provided prompt by generating additional, more descriptive variations, resulting in more diverse and creative output images.
    </ParamField>

    <ParamField body="medium" type="MediumEnum">
      Which medium should be included in your generated images. This parameter is optional.

      Possible values: `photography`, `art`
    </ParamField>

    <ParamField body="guidance" type="list<GuidanceInput>" default="">
      Guidance images to use for the generation. Up to 4 guidance methods can be combined during a single inference.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed value used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination.",
      "negative_prompt": "",
      "num_images": 4,
      "aspect_ratio": "1:1",
      "num_inference_steps": 30,
      "guidance_scale": 5,
      "prompt_enhancement": false,
      "guidance": [],
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "257cf8e7bd3a47c2959396343d5b38cf.png",
          "file_size": 3731290,
          "height": 1536,
          "url": "https://v3.fal.media/files/tiger/48e63e0K6C9XQYBuomoU-_257cf8e7bd3a47c2959396343d5b38cf.png",
          "width": 1536
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Fast">
    **Endpoint:** `POST https://fal.run/fal-ai/bria/text-to-image/fast`
    **Endpoint ID:** `fal-ai/bria/text-to-image/fast`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bria/text-to-image/fast/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bria/text-to-image/fast",
          arguments={
              "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bria/text-to-image/fast", {
        input: {
            prompt: "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bria/text-to-image/fast \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt you would like to use to generate images.
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      The negative prompt you would like to use to generate images. Default value: `""`
    </ParamField>

    <ParamField body="num_images" type="integer" default="4">
      How many images you would like to generate. When using any Guidance Method, Value is set to 1. Default value: `4`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the image. When a guidance method is being used, the aspect ratio is defined by the guidance image and this parameter is ignored. Default value: `"1:1"`

      Possible values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.

      Range: `0` to `2147483647`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of iterations the model goes through to refine the generated image. This parameter is optional. Default value: `8`

      Range: `4` to `10`
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `5`

      Range: `0` to `20`
    </ParamField>

    <ParamField body="prompt_enhancement" type="boolean" default="false">
      When set to true, enhances the provided prompt by generating additional, more descriptive variations, resulting in more diverse and creative output images.
    </ParamField>

    <ParamField body="medium" type="MediumEnum">
      Which medium should be included in your generated images. This parameter is optional.

      Possible values: `photography`, `art`
    </ParamField>

    <ParamField body="guidance" type="list<GuidanceInput>" default="">
      Guidance images to use for the generation. Up to 4 guidance methods can be combined during a single inference.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed value used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A lone figure stands on the edge of a serene cliff at sunset, gazing out over a vast, mystical valley. The figure is clad in flowing robes that ripple in the gentle breeze, silhouetted against the golden and lavender hues of the sky. Below, a cascading waterfall pours into a sparkling river winding through a forest of bioluminescent trees. The scene blends the awe of nature with a touch of otherworldly wonder, inviting reflection and imagination.",
      "negative_prompt": "",
      "num_images": 4,
      "aspect_ratio": "1:1",
      "num_inference_steps": 8,
      "guidance_scale": 5,
      "prompt_enhancement": false,
      "guidance": [],
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "257cf8e7bd3a47c2959396343d5b38cf.png",
          "file_size": 3731290,
          "height": 1536,
          "url": "https://v3.fal.media/files/tiger/48e63e0K6C9XQYBuomoU-_257cf8e7bd3a47c2959396343d5b38cf.png",
          "width": 1536
        }
      ]
    }
    ```
  </Tab>
</Tabs>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `seed` range: 0 to 2147483647
* `num_inference_steps` range: 20 to 50
* `guidance_scale` range: 0 to 20
* `medium` restricted to: `photography`, `art`
* `num_inference_steps` range: 4 to 10


# https://fal.ai/docs/model-api-reference/image-generation-api/bytedance-dreamina-v3.1.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Dreamina V3.1 API

> API reference for Bytedance Dreamina V3.1. Dreamina showcases superior picture effects, with significant improvements in picture aesthetics, precise and diverse styles, and rich details.

**Endpoint:** `POST https://fal.run/fal-ai/bytedance/dreamina/v3.1/text-to-image`
**Endpoint ID:** `fal-ai/bytedance/dreamina/v3.1/text-to-image`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/dreamina/v3.1/text-to-image/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bytedance/dreamina/v3.1/text-to-image",
      arguments={
          "prompt": "A 25-year-old korean woman selfie, front facing camera, lighting is soft and natural. If background is visible, it's a clean, modern apartment interior. The clothing color is clearly visible and distinct, adding a hint of color contrast"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bytedance/dreamina/v3.1/text-to-image", {
    input: {
        prompt: "A 25-year-old korean woman selfie, front facing camera, lighting is soft and natural. If background is visible, it's a clean, modern apartment interior. The clothing color is clearly visible and distinct, adding a hint of color contrast"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bytedance/dreamina/v3.1/text-to-image \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A 25-year-old korean woman selfie, front facing camera, lighting is soft and natural. If background is visible, it'\''s a clean, modern apartment interior. The clothing color is clearly visible and distinct, adding a hint of color contrast"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt used to generate the image
</ParamField>

<ParamField body="image_size" type="ImageSize | Enum" default="[object Object]">
  The size of the generated image. Width and height must be between 512 and 2048.

  Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
</ParamField>

<ParamField body="enhance_prompt" type="boolean" default="false">
  Whether to use an LLM to enhance the prompt
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  Number of images to generate Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="seed" type="integer">
  Random seed to control the stochasticity of image generation.
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<Image>" required>
  Generated images
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed used for generation
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "A 25-year-old korean woman selfie, front facing camera, lighting is soft and natural. If background is visible, it's a clean, modern apartment interior. The clothing color is clearly visible and distinct, adding a hint of color contrast",
  "image_size": {
    "width": 2048,
    "height": 1536
  },
  "enhance_prompt": false,
  "num_images": 1,
  "sync_mode": false
}
```

### Output Example

```json theme={null}
{
  "images": [
    {
      "url": "https://v3.fal.media/files/panda/4mddd7PmDvbbBZDs-xnUW_4294a9041c9d46eaa7b98d15ce6300fb.png"
    }
  ],
  "seed": 746406749
}
```

## Related

* [Bytedance Seedream v4 Edit](/model-api-reference/image-generation-api/bytedance-seedream-v4-edit) — Image Generation
* [Bytedance Seedream v4](/model-api-reference/image-generation-api/bytedance-seedream-v4) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_images` range: 1 to 4


# https://fal.ai/docs/model-api-reference/image-generation-api/bytedance-seedream-v3.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedream V3 API

> API reference for Bytedance Seedream V3. Seedream 3.0 is a bilingual (Chinese and English) text-to-image model that excels at text-to-image generation.

**Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedream/v3/text-to-image`
**Endpoint ID:** `fal-ai/bytedance/seedream/v3/text-to-image`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedream/v3/text-to-image/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bytedance/seedream/v3/text-to-image",
      arguments={
          "prompt": "Fisheye lens, the head of a cat, the image shows the effect that the facial features of the cat are distorted due to the shooting method."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bytedance/seedream/v3/text-to-image", {
    input: {
        prompt: "Fisheye lens, the head of a cat, the image shows the effect that the facial features of the cat are distorted due to the shooting method."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bytedance/seedream/v3/text-to-image \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Fisheye lens, the head of a cat, the image shows the effect that the facial features of the cat are distorted due to the shooting method."
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt used to generate the image
</ParamField>

<ParamField body="image_size" type="ImageSize | Enum">
  Use for finer control over the output image size. Will be used over aspect\_ratio, if both are provided. Width and height must be between 512 and 2048.

  Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
</ParamField>

<ParamField body="guidance_scale" type="float" default="2.5">
  Controls how closely the output image aligns with the input prompt. Higher values mean stronger prompt correlation. Default value: `2.5`

  Range: `1` to `10`
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  Number of images to generate Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="seed" type="integer">
  Random seed to control the stochasticity of image generation.
</ParamField>

<ParamField body="enable_safety_checker" type="boolean" default="true">
  If set to true, the safety checker will be enabled. Default value: `true`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<Image>" required>
  Generated images
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed used for generation
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "Fisheye lens, the head of a cat, the image shows the effect that the facial features of the cat are distorted due to the shooting method.",
  "guidance_scale": 2.5,
  "num_images": 1,
  "enable_safety_checker": true,
  "sync_mode": false
}
```

### Output Example

```json theme={null}
{
  "images": [
    {
      "url": "https://v3.fal.media/files/rabbit/EJqemc4hQlHKAtkkfTJqB_a2aaccab7ff84740b6323da580146087.png"
    }
  ],
  "seed": 42
}
```

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `guidance_scale` range: 1 to 10
* `num_images` range: 1 to 4
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/bytedance-seedream-v4.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedream V4 API

> API reference for Bytedance Seedream V4. A new-generation image creation model ByteDance, Seedream 4.0 integrates image generation and image editing capabilities into a single, unified architecture.

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedream/v4/edit`
    **Endpoint ID:** `fal-ai/bytedance/seedream/v4/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedream/v4/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedream/v4/edit",
          arguments={
              "prompt": "Dress the model in the clothes and hat. Add a cat to the scene and change the background to a Victorian era building.",
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_1.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_2.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_3.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_4.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedream/v4/edit", {
        input: {
            prompt: "Dress the model in the clothes and hat. Add a cat to the scene and change the background to a Victorian era building.",
            image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_1.png",
              "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_2.png",
              "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_3.png",
              "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_4.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedream/v4/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Dress the model in the clothes and hat. Add a cat to the scene and change the background to a Victorian era building.",
        "image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_1.png",
          "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_2.png",
          "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_3.png",
          "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_4.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to edit the image
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="[object Object]">
      The size of the generated image. The minimum total image area is 921600 pixels. Failing this, the image size will be adjusted to by scaling it up, while maintaining the aspect ratio.

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`, `auto_2K`, `auto_4K`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of separate model generations to be run with the prompt. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="max_images" type="integer" default="1">
      If set to a number greater than one, enables multi-image generation. The model will potentially return up to `max_images` images every generation, and in total, `num_images` generations will be carried out. In total, the number of images generated will be between `num_images` and `max_images*num_images`. The total number of images (image inputs + image outputs) must not exceed 15 Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control the stochasticity of image generation.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="enhance_prompt_mode" type="EnhancePromptModeEnum" default="standard">
      The mode to use for enhancing prompt enhancement. Standard mode provides higher quality results but takes longer to generate. Fast mode provides average quality results but takes less time to generate. Default value: `"standard"`

      Possible values: `standard`, `fast`
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      List of URLs of input images for editing. Presently, up to 10 image inputs are allowed. If over 10 images are sent, only the last 10 will be used.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      Generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Dress the model in the clothes and hat. Add a cat to the scene and change the background to a Victorian era building.",
      "image_size": {
        "height": 2160,
        "width": 3840
      },
      "num_images": 1,
      "max_images": 1,
      "sync_mode": false,
      "enable_safety_checker": true,
      "enhance_prompt_mode": "standard",
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_1.png",
        "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_2.png",
        "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_3.png",
        "https://storage.googleapis.com/falserverless/example_inputs/seedream4_edit_input_4.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://storage.googleapis.com/falserverless/example_outputs/seedream4_edit_output.png"
        }
      ],
      "seed": 746406749
    }
    ```
  </Tab>

  <Tab title="Text To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedream/v4/text-to-image`
    **Endpoint ID:** `fal-ai/bytedance/seedream/v4/text-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedream/v4/text-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedream/v4/text-to-image",
          arguments={
              "prompt": "A trendy restaurant with a digital menu board displaying \"Seedream 4.0 is available on fal\" in elegant script, with diners enjoying their meals."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedream/v4/text-to-image", {
        input: {
            prompt: "A trendy restaurant with a digital menu board displaying \"Seedream 4.0 is available on fal\" in elegant script, with diners enjoying their meals."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedream/v4/text-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A trendy restaurant with a digital menu board displaying \"Seedream 4.0 is available on fal\" in elegant script, with diners enjoying their meals."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the image
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="[object Object]">
      The size of the generated image. Total pixels must be between 960x960 and 4096x4096.

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`, `auto_2K`, `auto_4K`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of separate model generations to be run with the prompt. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="max_images" type="integer" default="1">
      If set to a number greater than one, enables multi-image generation. The model will potentially return up to `max_images` images every generation, and in total, `num_images` generations will be carried out. In total, the number of images generated will be between `num_images` and `max_images*num_images`. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control the stochasticity of image generation.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="enhance_prompt_mode" type="EnhancePromptModeEnum" default="standard">
      The mode to use for enhancing prompt enhancement. Standard mode provides higher quality results but takes longer to generate. Fast mode provides average quality results but takes less time to generate. Default value: `"standard"`

      Possible values: `standard`, `fast`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      Generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A trendy restaurant with a digital menu board displaying \"Seedream 4.0 is available on fal\" in elegant script, with diners enjoying their meals.",
      "image_size": {
        "height": 4096,
        "width": 4096
      },
      "num_images": 1,
      "max_images": 1,
      "sync_mode": false,
      "enable_safety_checker": true,
      "enhance_prompt_mode": "standard"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://storage.googleapis.com/falserverless/example_outputs/seedream4_t2i_output.png"
        }
      ],
      "seed": 746406749
    }
    ```
  </Tab>
</Tabs>

## Related

* [Bytedance Seedream v4](/model-api-reference/image-generation-api/bytedance-seedream-v4) — Image Generation
* [Bytedance](/model-api-reference/image-generation-api/bytedance) — Image Generation
* [Bytedance Seedream v4 Edit](/model-api-reference/image-generation-api/bytedance-seedream-v4-edit) — Image Generation

## Limitations

* `num_images` range: 1 to 6
* `max_images` range: 1 to 6
* `enhance_prompt_mode` restricted to: `standard`, `fast`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/bytedance-seedream-v4.5.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedream V4.5 API

> API reference for Bytedance Seedream V4.5. A new-generation image creation model ByteDance, Seedream 4.5 integrates image generation and image editing capabilities into a single, unified architecture.

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedream/v4.5/edit`
    **Endpoint ID:** `fal-ai/bytedance/seedream/v4.5/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedream/v4.5/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedream/v4.5/edit",
          arguments={
              "prompt": "Replace the product in Figure 1 with that in Figure 2. For the title copy the text in Figure 3 to the top of the screen, the title should have a clear contrast with the background but not be overly eye-catching.",
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_1.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_2.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_3.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedream/v4.5/edit", {
        input: {
            prompt: "Replace the product in Figure 1 with that in Figure 2. For the title copy the text in Figure 3 to the top of the screen, the title should have a clear contrast with the background but not be overly eye-catching.",
            image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_1.png",
              "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_2.png",
              "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_3.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedream/v4.5/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Replace the product in Figure 1 with that in Figure 2. For the title copy the text in Figure 3 to the top of the screen, the title should have a clear contrast with the background but not be overly eye-catching.",
        "image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_1.png",
          "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_2.png",
          "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_3.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to edit the image
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="[object Object]">
      The size of the generated image. Width and height must be between 1920 and 4096, or total number of pixels must be between 2560*1440 and 4096*4096.

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto_2K`, `auto_4K`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of separate model generations to be run with the prompt. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="max_images" type="integer" default="1">
      If set to a number greater than one, enables multi-image generation. The model will potentially return up to `max_images` images every generation, and in total, `num_images` generations will be carried out. In total, the number of images generated will be between `num_images` and `max_images*num_images`. The total number of images (image inputs + image outputs) must not exceed 15 Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control the stochasticity of image generation.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      List of URLs of input images for editing. Presently, up to 10 image inputs are allowed. If over 10 images are sent, only the last 10 will be used.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      Generated images
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Replace the product in Figure 1 with that in Figure 2. For the title copy the text in Figure 3 to the top of the screen, the title should have a clear contrast with the background but not be overly eye-catching.",
      "image_size": "auto_4K",
      "num_images": 1,
      "max_images": 1,
      "sync_mode": false,
      "enable_safety_checker": true,
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_1.png",
        "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_2.png",
        "https://storage.googleapis.com/falserverless/example_inputs/seedreamv45/seedream_v45_edit_input_3.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://storage.googleapis.com/falserverless/example_outputs/seedreamv45/seedream_v45_edit_output.png"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Text To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedream/v4.5/text-to-image`
    **Endpoint ID:** `fal-ai/bytedance/seedream/v4.5/text-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedream/v4.5/text-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedream/v4.5/text-to-image",
          arguments={
              "prompt": "A selfie of a cat, with the cat as the protagonist. The setting is twilight at the Eiffel Tower. The cat is happy, holding a piece of baklava in its paw. The photo has a slight motion blur and is slightly overexposed. From a selfie angle, with a bit of motion blur, the overall image presents a sense of calm madness. The text \"Seedream 4.5 is on fal\" should be written on the picture at the top in clearly visible font and crisp lettering. The image has a 4:3 aspect ratio"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedream/v4.5/text-to-image", {
        input: {
            prompt: "A selfie of a cat, with the cat as the protagonist. The setting is twilight at the Eiffel Tower. The cat is happy, holding a piece of baklava in its paw. The photo has a slight motion blur and is slightly overexposed. From a selfie angle, with a bit of motion blur, the overall image presents a sense of calm madness. The text \"Seedream 4.5 is on fal\" should be written on the picture at the top in clearly visible font and crisp lettering. The image has a 4:3 aspect ratio"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedream/v4.5/text-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A selfie of a cat, with the cat as the protagonist. The setting is twilight at the Eiffel Tower. The cat is happy, holding a piece of baklava in its paw. The photo has a slight motion blur and is slightly overexposed. From a selfie angle, with a bit of motion blur, the overall image presents a sense of calm madness. The text \"Seedream 4.5 is on fal\" should be written on the picture at the top in clearly visible font and crisp lettering. The image has a 4:3 aspect ratio"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the image
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="[object Object]">
      The size of the generated image. Width and height must be between 1920 and 4096, or total number of pixels must be between 2560*1440 and 4096*4096.

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto_2K`, `auto_4K`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of separate model generations to be run with the prompt. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="max_images" type="integer" default="1">
      If set to a number greater than one, enables multi-image generation. The model will potentially return up to `max_images` images every generation, and in total, `num_images` generations will be carried out. In total, the number of images generated will be between `num_images` and `max_images*num_images`. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control the stochasticity of image generation.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      Generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A selfie of a cat, with the cat as the protagonist. The setting is twilight at the Eiffel Tower. The cat is happy, holding a piece of baklava in its paw. The photo has a slight motion blur and is slightly overexposed. From a selfie angle, with a bit of motion blur, the overall image presents a sense of calm madness. The text \"Seedream 4.5 is on fal\" should be written on the picture at the top in clearly visible font and crisp lettering. The image has a 4:3 aspect ratio",
      "image_size": "auto_2K",
      "num_images": 1,
      "max_images": 1,
      "sync_mode": false,
      "enable_safety_checker": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://storage.googleapis.com/falserverless/example_outputs/seedreamv45/seedream_v45_t2i_output.png"
        }
      ],
      "seed": 42
    }
    ```
  </Tab>
</Tabs>

ByteDance's Seedream 4.5 transforms existing images through natural language instructions at \$0.04 per edit, processing up to 10 reference images simultaneously for complex multi-source compositions. Trading simple single-image workflows for sophisticated context-aware editing, this unified architecture references multiple sources, copies specific elements between images, and maintains spatial relationships without manual masking. Built for e-commerce teams assembling product composites, designers prototyping layout variations, and marketing workflows requiring consistent brand element integration across visuals.

**Built for:** Multi-image product composites | Layout prototyping with text overlays | Brand asset integration workflows

***

## Natural Language Editing Without Layers

Seedream 4.5 consolidates image generation and editing into a single architecture that interprets spatial references directly from your prompt. Instead of requiring layer masks or selection tools, you describe edits using natural language - "replace the product in Figure 1 with that in Figure 2" or "copy the text from Figure 3 to the top with clear contrast."

**What this means for you:**

* **Multi-source composition:** Reference up to 10 images per edit, enabling complex workflows like product swaps, text overlay copying, and element positioning across multiple source files
* **Context-aware transformations:** The model maintains depth, perspective, and lighting consistency when integrating elements from different sources - no manual blending required
* **Resolution flexibility:** Output up to 4 megapixels (2048x2048 maximum) with configurable dimensions between 1920px and 4096px on either axis
* **Batch generation control:** Run 1-6 separate generations per request, with optional multi-image output (up to 6 images per generation) for exploring variations

***

## Performance That Scales

Seedream 4.5 processes edits in approximately 60 seconds on [fal infrastructure](https://fal.ai/models/fal-ai/bytedance/seedream/v4.5/edit), with pricing structured for production workflows requiring multiple reference images.

| Metric                   | Result          | Context                                                             |
| :----------------------- | :-------------- | :------------------------------------------------------------------ |
| **Inference Speed**      | \~60 seconds    | Standard processing time per edit on fal                            |
| **Cost per Edit**        | \$0.04          | 25 edits per \$1.00 on fal                                          |
| **Max Reference Images** | 10 images       | Multi-source composition capability (last 10 used if more provided) |
| **Max Resolution**       | 4MP (2048x2048) | Configurable dimensions between 1920-4096px per axis                |

***

## Technical Specifications

| Spec                 | Details                                                   |
| :------------------- | :-------------------------------------------------------- |
| **Architecture**     | Seedream 4.5                                              |
| **Input Formats**    | Image URLs (up to 10), text prompt                        |
| **Output Formats**   | PNG images via URL or data URI                            |
| **Resolution Range** | 1920-4096px per axis, 2560×1440 to 4096×4096 total pixels |
| **License**          | Commercial use via fal Partner agreement                  |

[API Documentation](https://fal.ai/models/fal-ai/bytedance/seedream/v4.5/edit/api)

***

## How It Stacks Up

**[Bytedance Seedream v4 Edit](https://fal.ai/models/fal-ai/bytedance/seedream/v4/edit)** - Seedream 4.5 expands multi-image input capacity from v4's baseline while maintaining the unified editing architecture. Both versions handle natural language spatial instructions, with v4.5 prioritizing higher reference image limits for complex composition workflows.

**[Bytedance Seededit v3](https://fal.ai/models/fal-ai/bytedance/seededit/v3/edit-image)** - Seedream 4.5 consolidates generation and editing into a single model architecture, trading v3's specialized editing focus for broader capability coverage. Seededit v3 remains purpose-built for pure image-to-image transformation workflows without generation requirements.

**[NAFNet-deblur](https://fal.ai/models/fal-ai/nafnet/deblur)** - Seedream 4.5 handles multi-image composition and semantic editing through natural language, making it ideal for layout assembly and element integration. NAFNet-deblur specializes in single-image restoration tasks like blur removal and artifact correction where semantic understanding isn't required.

## Related

* [Bytedance](/model-api-reference/image-generation-api/bytedance) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto_2K`, `auto_4K`
* `num_images` range: 1 to 6
* `max_images` range: 1 to 6
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/bytedance-seedream-v5-lite.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedream V5 Lite API

> API reference for Bytedance Seedream V5 Lite. Image editing endpoint for the fast Lite version of Seedream 5.0, supporting high quality intelligent image editing with multiple inputs.

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedream/v5/lite/edit`
    **Endpoint ID:** `fal-ai/bytedance/seedream/v5/lite/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedream/v5/lite/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedream/v5/lite/edit",
          arguments={
              "prompt": "Replace the product in Figure 1 with that in Figure 2. Seamlessly render logo in Figure 3 into the product design, in frosted glass texture. Remove any extra text in Figure 1, and design a catchy tagline for the perfume.",
              "image_urls": [
                  "https://v3b.fal.media/files/b/0a8f9936/KOsb_qPB_W0ZJ0Ee2OsnU_586e2892841d46f09049ee7199b303d3.png",
                  "https://v3b.fal.media/files/b/0a8f994e/JroWTogO6jOTFk9b6B3XM_591ca38cef2f44bbba2843cbf80fb1b2.png",
                  "https://v3b.fal.media/files/b/0a8f9960/Q6pzwXAiFaFPOpSScoE-D_0eca5db19e5242739f127efe49b38922.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedream/v5/lite/edit", {
        input: {
            prompt: "Replace the product in Figure 1 with that in Figure 2. Seamlessly render logo in Figure 3 into the product design, in frosted glass texture. Remove any extra text in Figure 1, and design a catchy tagline for the perfume.",
            image_urls: [
              "https://v3b.fal.media/files/b/0a8f9936/KOsb_qPB_W0ZJ0Ee2OsnU_586e2892841d46f09049ee7199b303d3.png",
              "https://v3b.fal.media/files/b/0a8f994e/JroWTogO6jOTFk9b6B3XM_591ca38cef2f44bbba2843cbf80fb1b2.png",
              "https://v3b.fal.media/files/b/0a8f9960/Q6pzwXAiFaFPOpSScoE-D_0eca5db19e5242739f127efe49b38922.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedream/v5/lite/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Replace the product in Figure 1 with that in Figure 2. Seamlessly render logo in Figure 3 into the product design, in frosted glass texture. Remove any extra text in Figure 1, and design a catchy tagline for the perfume.",
        "image_urls": [
          "https://v3b.fal.media/files/b/0a8f9936/KOsb_qPB_W0ZJ0Ee2OsnU_586e2892841d46f09049ee7199b303d3.png",
          "https://v3b.fal.media/files/b/0a8f994e/JroWTogO6jOTFk9b6B3XM_591ca38cef2f44bbba2843cbf80fb1b2.png",
          "https://v3b.fal.media/files/b/0a8f9960/Q6pzwXAiFaFPOpSScoE-D_0eca5db19e5242739f127efe49b38922.png"
        ]
      }'
      ```
    </CodeGroup>

    ## Examples

    > Change the season to winter. Cover everything in fresh white snow. The trees should be bare with snow on branches. The fallen leaves are replaced by snow. Overcast grey sky. The red car has a thin layer of snow on the hood and roof. Tire tracks in the fresh snow on the road.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8fc1a0/MX84wRTkjQh3JwBRTnvwj_5f3fd60da05144579bd30ada3997da10.png" alt="Generated image: Change the season to winter. Cover everything in fresh white snow. The trees sho" />
    </Frame>

    > Transform these into fluffy Japanese souffle pancakes. Make them much thicker and jigglier looking, tall and wobbly. Add a scoop of vanilla ice cream on top with a drizzle of honey. A small ceramic cup of matcha on the side. Change the setting to a cute Japanese cafe table with a checkered placemat....

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8fc22e/yYBznQsdzYgLDcFlhVOMQ_152dac218a2549dda8c4b82c0b256718.png" alt="Generated image: Transform these into fluffy Japanese souffle pancakes. Make them much thicker an" />
    </Frame>

    > Change the weather to an approaching thunderstorm. Dark dramatic storm clouds rolling over the mountains. Lightning bolt striking one of the peaks in the distance. The lake surface is choppy with small waves. Wind bending the trees. The light is eerie and dramatic with a break in the clouds letting ...

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8fc222/jcpgLgFk3hbrWS_3N32km_89ced5799c884b7c9ba80d19a4e89229.png" alt="Generated image: Change the weather to an approaching thunderstorm. Dark dramatic storm clouds ro" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to edit the image
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto_2K">
      The size of the generated image. Total pixels must be between 2560x1440 and 3072x3072. In case the image size does not fall within these parameters, the image size will be adjusted to by scaling. Default value: `auto_2K`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto_2K`, `auto_3K`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of separate model generations to be run with the prompt. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="max_images" type="integer" default="1">
      If set to a number greater than one, enables multi-image generation. The model will potentially return up to `max_images` images every generation, and in total, `num_images` generations will be carried out. In total, the number of images generated will be between `num_images` and `max_images*num_images`. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      List of URLs of input images for editing. Presently, up to 10 image inputs are allowed. If over 10 images are sent, only the last 10 will be used.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      Generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Replace the product in Figure 1 with that in Figure 2. Seamlessly render logo in Figure 3 into the product design, in frosted glass texture. Remove any extra text in Figure 1, and design a catchy tagline for the perfume.",
      "image_size": "auto_2K",
      "num_images": 1,
      "max_images": 1,
      "sync_mode": false,
      "enable_safety_checker": true,
      "image_urls": [
        "https://v3b.fal.media/files/b/0a8f9936/KOsb_qPB_W0ZJ0Ee2OsnU_586e2892841d46f09049ee7199b303d3.png",
        "https://v3b.fal.media/files/b/0a8f994e/JroWTogO6jOTFk9b6B3XM_591ca38cef2f44bbba2843cbf80fb1b2.png",
        "https://v3b.fal.media/files/b/0a8f9960/Q6pzwXAiFaFPOpSScoE-D_0eca5db19e5242739f127efe49b38922.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3b.fal.media/files/b/0a8fbf56/wu9vcxO3xO6lkHv5zdiIs_7aa8564f6e4f4cc795ecb8e923deb2fb.png"
        }
      ],
      "seed": 42
    }
    ```
  </Tab>

  <Tab title="Text To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedream/v5/lite/text-to-image`
    **Endpoint ID:** `fal-ai/bytedance/seedream/v5/lite/text-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedream/v5/lite/text-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedream/v5/lite/text-to-image",
          arguments={
              "prompt": "Realistic DSLR photograph of anthropomorphic Penkingese dog enjoying a bowl of ramen on the Great Wall of China with the words \"Seedream 5.0 Lite available on fal\" visible at the top."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedream/v5/lite/text-to-image", {
        input: {
            prompt: "Realistic DSLR photograph of anthropomorphic Penkingese dog enjoying a bowl of ramen on the Great Wall of China with the words \"Seedream 5.0 Lite available on fal\" visible at the top."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedream/v5/lite/text-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Realistic DSLR photograph of anthropomorphic Penkingese dog enjoying a bowl of ramen on the Great Wall of China with the words \"Seedream 5.0 Lite available on fal\" visible at the top."
      }'
      ```
    </CodeGroup>

    ## Examples

    > A crumbling medieval stone castle floating on a massive chunk of earth above the clouds, thick roots dangling from the bottom, waterfalls cascading off the edges into the mist below, sunset sky painted in amber and violet, a flock of birds circling one tower, cinematic matte painting style, epic fan...

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8fc193/EKCKuHaYvSdxTaaD4lC0R_b0d7ebf49f1549e69be167d6c84b2070.png" alt="Generated image: A crumbling medieval stone castle floating on a massive chunk of earth above the" />
    </Frame>

    > A cozy attic reading nook on a rainy afternoon, warm watercolor illustration style. An overstuffed armchair with a patchwork quilt draped over it, a steaming mug of tea on a stack of books, a cat curled up on the windowsill watching rain streak down the glass. Soft warm lamplight, muted earth tones ...

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8fc193/Hisi7JfhJPercCx4ELfkd_f6878a536b4d4ad48421cdb4049851df.png" alt="Generated image: A cozy attic reading nook on a rainy afternoon, warm watercolor illustration sty" />
    </Frame>

    > On the left side of a small round marble cafe table, a man in a rust-colored linen shirt leaning forward with his chin on his hand. On the right side, a woman in an oversized cream knit sweater laughing with her head tilted back. Two steaming cappuccinos between them, a croissant on a plate. Warm Pa...

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8fc18e/8nwm9eNsIdO_pcJhyNc1P_40662ec4209a4dcf9601544a1e776465.png" alt="Generated image: On the left side of a small round marble cafe table, a man in a rust-colored lin" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the image
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto_2K">
      The size of the generated image. Total pixels must be between 2560x1440 and 3072x3072. In case the image size does not fall within these parameters, the image size will be adjusted to by scaling. Default value: `auto_2K`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto_2K`, `auto_3K`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of separate model generations to be run with the prompt. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="max_images" type="integer" default="1">
      If set to a number greater than one, enables multi-image generation. The model will potentially return up to `max_images` images every generation, and in total, `num_images` generations will be carried out. In total, the number of images generated will be between `num_images` and `max_images*num_images`. Default value: `1`

      Range: `1` to `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      Generated images
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Realistic DSLR photograph of anthropomorphic Penkingese dog enjoying a bowl of ramen on the Great Wall of China with the words \"Seedream 5.0 Lite available on fal\" visible at the top.",
      "image_size": "auto_2K",
      "num_images": 1,
      "max_images": 1,
      "sync_mode": false,
      "enable_safety_checker": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3b.fal.media/files/b/0a8fbf48/fv693UaOADKqnujJRZN90_4518fc5e1fed4fb29963b22a8cc3d5a6.png"
        }
      ],
      "seed": 42
    }
    ```
  </Tab>
</Tabs>

ByteDance's Seedream 5.0 Lite delivers fast, intelligent and high quality image editing suitable for creative advertising and real-world usecases. It can process up to 10 reference images simultaneously for complex multi-source compositions.

**Built for:** Product mockup generation | Marketing asset creation | Creative iteration workflows

***

**What this means for you:**

* **High-resolution output:** Generate images up to 3072x3072 pixels with flexible aspect ratios.
* **Multi-image generation:** Request up to 6 separate generations per API call, with the option to generate multiple variations per generation using `max_images`
* **Safety integration:** Built-in content filtering enabled by default, with the option to disable for controlled environments

***

| Metric                   | Result          | Context                                                             |
| :----------------------- | :-------------- | :------------------------------------------------------------------ |
| **Cost per Image**       | \$0.035         | Cheaper than Nano Banana and Seedream 4.5                           |
| **Max Resolution**       | 9MP (3072x3072) | Total pixel count between 3.7MP and 9.43MP supported                |
| **Batch Capability**     | 1-6 images      | Per generation, with multi-generation support via `max_images`      |
| **Max Reference Images** | 10 images       | Multi-source composition capability (last 10 used if more provided) |
| **Output Format**        | PNG via URL     | Async by default, sync mode available for data URI returns          |

***

## Technical Specifications

| Spec                 | Details                                             |
| :------------------- | :-------------------------------------------------- |
| **Architecture**     | Seedream 5.0 Lite                                   |
| **Input Formats**    | Text prompts with detailed natural language support |
| **Output Formats**   | PNG images delivered via HTTPS URL or data URI      |
| **Resolution Range** | 2560x1440 to 3072x3072 total pixels                 |
| **License**          | Commercial use permitted under partner agreement    |

## Related

* [Bytedance](/model-api-reference/image-generation-api/bytedance) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto_2K`, `auto_3K`
* `num_images` range: 1 to 6
* `max_images` range: 1 to 6
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/florence-2-large.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Florence 2 Large API

> API reference for Florence 2 Large. Florence-2 is an advanced vision foundation model that uses a prompt-based approach to handle a wide range of vision and vision-language tasks

<Tabs>
  <Tab title="Object Detection">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/object-detection`
    **Endpoint ID:** `fal-ai/florence-2-large/object-detection`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/object-detection/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/object-detection",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/object-detection", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/object-detection \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="BoundingBoxes" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "bboxes": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Open Vocabulary Detection">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/open-vocabulary-detection`
    **Endpoint ID:** `fal-ai/florence-2-large/open-vocabulary-detection`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/open-vocabulary-detection/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/open-vocabulary-detection",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
              "text_input": ""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/open-vocabulary-detection", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
            text_input: ""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/open-vocabulary-detection \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
        "text_input": ""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    <ParamField body="text_input" type="string" required>
      Text input for the task
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="BoundingBoxes" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
      "text_input": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "bboxes": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Ocr With Region">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/ocr-with-region`
    **Endpoint ID:** `fal-ai/florence-2-large/ocr-with-region`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/ocr-with-region/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/ocr-with-region",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/ocr-with-region", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/ocr-with-region \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="OCRBoundingBox" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "quad_boxes": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Caption To Phrase Grounding">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/caption-to-phrase-grounding`
    **Endpoint ID:** `fal-ai/florence-2-large/caption-to-phrase-grounding`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/caption-to-phrase-grounding/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/caption-to-phrase-grounding",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
              "text_input": ""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/caption-to-phrase-grounding", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
            text_input: ""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/caption-to-phrase-grounding \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
        "text_input": ""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    <ParamField body="text_input" type="string" required>
      Text input for the task
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="BoundingBoxes" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
      "text_input": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "bboxes": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Referring Expression Segmentation">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/referring-expression-segmentation`
    **Endpoint ID:** `fal-ai/florence-2-large/referring-expression-segmentation`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/referring-expression-segmentation/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/referring-expression-segmentation",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
              "text_input": ""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/referring-expression-segmentation", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
            text_input: ""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/referring-expression-segmentation \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
        "text_input": ""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    <ParamField body="text_input" type="string" required>
      Text input for the task
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="PolygonOutput" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
      "text_input": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "polygons": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Dense Region Caption">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/dense-region-caption`
    **Endpoint ID:** `fal-ai/florence-2-large/dense-region-caption`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/dense-region-caption/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/dense-region-caption",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/dense-region-caption", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/dense-region-caption \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="BoundingBoxes" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "bboxes": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Region To Segmentation">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/region-to-segmentation`
    **Endpoint ID:** `fal-ai/florence-2-large/region-to-segmentation`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/region-to-segmentation/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/region-to-segmentation",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
              "region": {
                  "x1": 100,
                  "x2": 200,
                  "y1": 100,
                  "y2": 200
              }
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/region-to-segmentation", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
            region: {
              x1: 100,
              x2: 200,
              y1: 100,
              y2: 200
            }
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/region-to-segmentation \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
        "region": {
          "x1": 100,
          "x2": 200,
          "y1": 100,
          "y2": 200
        }
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    <ParamField body="region" type="Region" required>
      The user input coordinates
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="PolygonOutput" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
      "region": {
        "x1": 100,
        "x2": 200,
        "y1": 100,
        "y2": 200
      }
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "polygons": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Region Proposal">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/region-proposal`
    **Endpoint ID:** `fal-ai/florence-2-large/region-proposal`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/region-proposal/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/region-proposal",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/region-proposal", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/region-proposal \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="BoundingBoxes" required>
      Results from the model
    </ParamField>

    <ParamField body="image" type="Image">
      Processed image
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": {
        "bboxes": [
          {
            "label": ""
          }
        ]
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Florence-2 Large](/model-api-reference/vision-api/florence-2-large) — Vision
* [Florence-2 Large](/model-api-reference/image-generation-api/florence-2-large) — Image Generation


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-2-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux 2 Pro API

> API reference for Flux 2 Pro. Image editing with FLUX.2 [pro] from Black Forest Labs. Ideal for high-quality image manipulation, style transfer, and sequential editing workflows

<Tabs>
  <Tab title="Flux 2 Pro">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-2-pro`
    **Endpoint ID:** `fal-ai/flux-2-pro`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-2-pro/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-2-pro",
          arguments={
              "prompt": "An intense close-up of knight's visor reflecting battle, sword raised, flames in background, chiaroscuro helmet shadows, hyper-detailed armor, square medieval, cinematic lighting"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-2-pro", {
        input: {
            prompt: "An intense close-up of knight's visor reflecting battle, sword raised, flames in background, chiaroscuro helmet shadows, hyper-detailed armor, square medieval, cinematic lighting"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-2-pro \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An intense close-up of knight'\''s visor reflecting battle, sword raised, flames in background, chiaroscuro helmet shadows, hyper-detailed armor, square medieval, cinematic lighting"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed to use for the generation.
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      Whether to enable the safety checker. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      The seed used for the generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An intense close-up of knight's visor reflecting battle, sword raised, flames in background, chiaroscuro helmet shadows, hyper-detailed armor, square medieval, cinematic lighting",
      "image_size": "landscape_4_3",
      "safety_tolerance": "2",
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://storage.googleapis.com/falserverless/example_outputs/flux2_pro_t2i_output.png"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-2-pro/edit`
    **Endpoint ID:** `fal-ai/flux-2-pro/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-2-pro/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-2-pro/edit",
          arguments={
              "prompt": "Place realistic flames emerging from the top of the coffee cup, dancing above the rim",
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/flux2_pro_edit_input.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-2-pro/edit", {
        input: {
            prompt: "Place realistic flames emerging from the top of the coffee cup, dancing above the rim",
            image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/flux2_pro_edit_input.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-2-pro/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Place realistic flames emerging from the top of the coffee cup, dancing above the rim",
        "image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/flux2_pro_edit_input.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto">
      The size of the generated image. If `auto`, the size will be determined by the model. Default value: `auto`

      Possible values: `auto`, `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed to use for the generation.
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      Whether to enable the safety checker. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      List of URLs of input images for editing
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      The seed used for the generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Place realistic flames emerging from the top of the coffee cup, dancing above the rim",
      "image_size": "auto",
      "safety_tolerance": "2",
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "sync_mode": false,
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/flux2_pro_edit_input.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://storage.googleapis.com/falserverless/example_outputs/flux2_pro_edit_output.png"
        }
      ]
    }
    ```
  </Tab>
</Tabs>

**Production-optimized generation** with professional quality out of the box. FLUX.2 \[pro] delivers studio-grade images through a streamlined pipeline that prioritizes consistency and speed over parameter tuning. No inference steps to configure, no guidance scales to adjust—just pure prompt-to-image conversion optimized for production workflows where reliability matters more than experimental control.

**Built for:** Production pipelines | High-volume generation | API integrations | Consistent brand outputs | Teams prioritizing speed over parameter experimentation

## Streamlined Professional Pipeline

FLUX.2 \[pro] removes generation complexity to focus on what matters: translating prompts into professional-quality images with predictable results. The model's fixed optimization delivers consistent output quality without requiring expertise in inference tuning.

**What this means for you:**

* **Zero-configuration quality**: Professional-grade outputs without tuning steps or guidance parameters. The model's internal optimization handles quality decisions
* **Production consistency**: Predictable results across batch generations make pro ideal for automated workflows and API integrations
* **Fast iteration cycles**: Streamlined pipeline prioritizes generation speed for teams moving quickly through creative development
* **Flexible output formats**: Choose between JPEG (optimized file sizes) or PNG (lossless quality) based on delivery requirements
* **Reproducible generations**: Seed control maintains consistency across variations without exposing low-level inference parameters
* **Prompt enhancement**: Automatic prompt upsampling refines instructions for optimal interpretation (enabled by default)

# Advanced Prompting Techniques

## JSON Structured Prompts

For precise control over complex generations, use structured JSON prompts instead of natural language. JSON prompting enables granular specification of scene elements, subjects, camera settings, and composition.

**Basic JSON structure:**

```json theme={null}
{
  "scene": "Overall setting description",
  "subjects": [
    {
      "type": "Subject category",
      "description": "Physical attributes and details",
      "pose": "Action or stance",
      "position": "foreground/midground/background"
    }
  ],
  "style": "Artistic rendering approach",
  "color_palette": ["color1", "color2", "color3"],
  "lighting": "Lighting conditions and direction",
  "mood": "Emotional atmosphere",
  "composition": "rule of thirds/centered/dynamic diagonal",
  "camera": {
    "angle": "eye level/low angle/high angle",
    "distance": "close-up/medium shot/wide shot",
    "lens": "35mm/50mm/85mm"
  }
}
```

JSON prompts excel at controlling multiple subjects, precise positioning, and maintaining specific attributes across complex compositions.

## HEX Color Code Control

Specify exact colors using HEX codes for precise color matching and brand consistency. Include the keyword "color" or "hex" before the code for best results.

**Examples:**

* `"a wall painted in color #2ECC71"`
* `"gradient from hex #FF6B6B to hex #4ECDC4"`
* `"the car in color #1A1A1A with accents in #FFD700"`

For enhanced accuracy, reference a color swatch image alongside the HEX code in your prompt.

## Image Referencing with @

Reference uploaded images directly in prompts using the `@` symbol for intuitive multi-image workflows.

**Usage patterns:**

* `"@image1 wearing the outfit from @image2"`
* `"combine the style of @image1 with the composition of @image2"`
* `"the person from @image1 in the setting from @image3"`

The `@` syntax provides a natural way to reference multiple images without explicit index notation, while maintaining support for traditional "image 1", "image 2" indexing.

## Related

* [Flux 2 Pro](/model-api-reference/image-generation-api/flux-2-pro) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`
* `output_format` restricted to: `jpeg`, `png`
* Content moderation via safety checker
* `image_size` restricted to: `auto`, `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-dev.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Dev API

> API reference for Flux Dev. FLUX.1 [dev] is a 12 billion parameter flow transformer that generates high-quality images from text. It is suitable for personal and commercial use.

<Tabs>
  <Tab title="Dev">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/dev`
    **Endpoint ID:** `fal-ai/flux/dev`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/dev/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/dev",
          arguments={
              "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/dev", {
        input: {
            prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/dev \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      }'
      ```
    </CodeGroup>

    ## Examples

    > portrait | wide angle shot of eyes off to one side of frame, lucid dream-like woman, looking off in distance ::8 style | daydreampunk with glowing skin and eyes, styled in headdress, beautiful, she is dripping in neon lights, very colorful blue, green, purple, bioluminescent, glowing ::8 background ...

    <Frame>
      <img src="https://v3.fal.media/files/koala/WF1Q_8cKxy7yC252zR59b.png" alt="Generated image: portrait | wide angle shot of eyes off to one side of frame, lucid dream-like wo" />
    </Frame>

    > a girl walking through a field, in the style of ethereal trees, dark yellow and azure, majestic, sweeping seascapes, photorealistic representation, graceful balance, wimmelbilder, orange

    <Frame>
      <img src="https://v3.fal.media/files/tiger/s99noBJtji7y3u1V60Dj6.png" alt="Generated image: a girl walking through a field, in the style of ethereal trees, dark yellow and " />
    </Frame>

    > Microscopic photograph of mites caught in a drop of water, green colored sparks raining from above across a gradient background, brightly shining sparks, emitting green light, shallow depth of field volumetric lighting, cinematic, intricate detail, ultra-realistic

    <Frame>
      <img src="https://v3.fal.media/files/kangaroo/0VRJN1EFfcyen5Bjf_gCs.png" alt="Generated image: Microscopic photograph of mites caught in a drop of water, green colored sparks " />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Image To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/dev/image-to-image`
    **Endpoint ID:** `fal-ai/flux/dev/image-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/dev/image-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/dev/image-to-image",
          arguments={
              "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
              "prompt": "A cat dressed as a wizard with a background of a mystic forest."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/dev/image-to-image", {
        input: {
            image_url: "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
            prompt: "A cat dressed as a wizard with a background of a mystic forest."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/dev/image-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
        "prompt": "A cat dressed as a wizard with a background of a mystic forest."
      }'
      ```
    </CodeGroup>

    ## Examples

    > a cat dressed as a wizard with a background of a mystic forest.

    <Frame>
      <img src="https://fal.media/files/tiger/n97jyGIpam7ZY5x8dpfZt.png" alt="Generated image: a cat dressed as a wizard with a background of a mystic forest." />
    </Frame>

    > woman, in cyberpunk city, purple, green, neon

    <Frame>
      <img src="https://fal.media/files/zebra/4ylIRCvHJDiD_hPLsoRIc.png" alt="Generated image: woman, in cyberpunk city, purple, green, neon" />
    </Frame>

    > cartoon tiger, anime style

    <Frame>
      <img src="https://fal.media/files/monkey/qxTAEasn1R3kJyEKlzqzi.png" alt="Generated image: cartoon tiger, anime style" />
    </Frame>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to generate an image from.
    </ParamField>

    <ParamField body="strength" type="float" default="0.95">
      The strength of the initial image. Higher strength values are better for this model. Default value: `0.95`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="40">
      The number of inference steps to perform. Default value: `40`

      Range: `10` to `50`
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
      "strength": 0.95,
      "num_inference_steps": 40,
      "prompt": "A cat dressed as a wizard with a background of a mystic forest.",
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Redux">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/dev/redux`
    **Endpoint ID:** `fal-ai/flux/dev/redux`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/dev/redux/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/dev/redux",
          arguments={
              "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/dev/redux", {
        input: {
            image_url: "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/dev/redux \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## FLUX.1 \[dev] - High-Performance Image Generation API

Transform your creative vision into stunning images with FLUX.1 \[dev], a state-of-the-art text-to-image generation model powered by a 12 billion parameter flow transformer. Built for both speed and quality, FLUX.1 \[dev] delivers professional-grade results suitable for personal and commercial use.

### Key Benefits

Create production-ready images faster and with greater control. FLUX.1 \[dev] enables you to:

* Generate high-fidelity images from natural language descriptions
* Achieve consistent results across multiple generations
* Scale from prototype to production with enterprise-grade reliability
* Access both personal and commercial licensing options
* Deploy anywhere with flexible API integration
* Use streaming capabilities for real-time generation

### Popular Use Cases

**Content Creation**
Generate marketing visuals, social media assets, and blog illustrations at scale. Perfect for agencies and content teams who need consistent, high-quality imagery.

**Product Development**\
Create concept art, UI mockups, and design variations for rapid prototyping. Ideal for designers exploring visual directions.

**E-commerce**
Generate product lifestyle images, seasonal campaigns, and A/B testing visuals to boost conversion rates.

**Entertainment**
Produce game assets, storyboard illustrations, and creative concept art for media projects.

### Technical Overview

FLUX.1 \[dev] is built on advanced flow transformer architecture that enables:

* **Performance**: 12B parameters optimized for rapid inference
* **Flexibility**: Support for multiple generation approaches including streaming
* **Quality**: Enhanced image coherence and composition
* **Licensing**: Suitable for both personal and commercial use

### Getting Started

Getting up and running with FLUX.1 \[dev] is straightforward. Here's how to begin:

1. Get your API key at [https://fal.ai/login](https://fal.ai/login)
2. Install the client library:

```bash theme={null}
# For JavaScript/TypeScript
npm install --save @fal-ai/client

# For Python
pip install fal-client
```

3. Make your first API call:

```javascript theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/flux/dev", {
  input: {
    prompt: "A serene mountain landscape at sunset, photorealistic style"
  }
});
```

### Streaming Support

FLUX.1 \[dev] supports streaming requests for real-time generation:

```javascript theme={null}
import { fal } from "@fal-ai/client";

const stream = await fal.stream("fal-ai/flux/dev", {
  input: {
    prompt: "Your detailed prompt here"
  }
});

for await (const event of stream) {
  console.log(event);
}

const result = await stream.done();
```

### Best Practices

For optimal results when using FLUX.1 \[dev]:

* Keep prompts clear and specific while maintaining natural language
* Start with default parameters and adjust based on results
* Consider using negative prompts to refine unwanted elements
* Monitor usage for cost-effective scaling
* Take advantage of streaming for interactive applications

### Advanced Features

#### Image Style Control

Fine-tune the artistic direction of your generations through comprehensive style parameters. Adjust attributes like composition, lighting, and artistic influence while maintaining consistent quality.

#### API Parameters

The model supports various configuration options:

* **CFG Scale**: Control prompt adherence (default: 3.5)
* **Safety Checker**: Enable content safety filtering
* **Output Format**: Choose between PNG and other formats
* **Number of Images**: Generate multiple variations
* **Speed Settings**: Optimize for generation speed

#### Batch Processing

Generate multiple variations efficiently with built-in batching support. Perfect for creating asset collections or exploring creative variations.

### Integration Support

Our comprehensive SDK support makes integration seamless across your technology stack:

* REST API for platform-agnostic integration
* Native SDKs for Python and JavaScript/TypeScript
* Streaming capabilities for real-time applications
* Detailed documentation and code examples
* Enterprise support options available

### Pricing and Usage

Your request will cost \$0.025 per megapixel. Images are billed by rounding up to the nearest megapixel. Our transparent, usage-based pricing scales with your needs:

* **Cost-effective**: \$0.025 per megapixel
* **Commercial usage rights** included
* **No subscription fees** or minimum commitments
* **Transparent billing** with clear pricing structure

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Licensing

FLUX.1 \[dev] is suitable for both personal and commercial use through fal.ai's platform. The model provides flexible licensing options that support various use cases from individual projects to enterprise deployments.

### Migration Guide

Moving from other platforms? Our migration tools and documentation help ensure a smooth transition to FLUX.1 \[dev]. Contact our support team for personalized migration assistance and best practices.

### Getting Help

We're here to support your success with FLUX.1 \[dev]:

* **Documentation**: Comprehensive guides at [https://docs.fal.ai](https://docs.fal.ai)
* **Support**: Technical assistance via [support@fal.ai](mailto:support@fal.ai)
* **Community**: Join our Discord for tips and discussions
* **Updates**: Regular model improvements and feature additions

Ready to transform your creative vision into reality? Get started at [https://fal.ai/models/fal-ai/flux/dev](https://fal.ai/models/fal-ai/flux/dev).

## Related

* [FLUX.1 \[schnell\]](/model-api-reference/image-generation-api/flux.1) — Image Generation
* [FLUX.1 \[dev\] Redux](/model-api-reference/image-generation-api/flux.1-redux) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_inference_steps` range: 1 to 50
* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `acceleration` restricted to: `none`, `regular`, `high`
* Content moderation via safety checker
* `strength` range: 0.01 to 1
* `num_inference_steps` range: 10 to 50


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-krea.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Krea API

> API reference for Flux Krea. FLUX.1 Krea [dev] is a 12 billion parameter flow transformer that generates high-quality images from text with incredible aesthetics. It is suitable for personal and comme

<Tabs>
  <Tab title="Krea">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/krea`
    **Endpoint ID:** `fal-ai/flux/krea`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/krea/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/krea",
          arguments={
              "prompt": "A candid street photo of a woman with a pink bob and bold eyeliner on a graffiti-covered subway platform. She wears a bright yellow patent leather coat over a black-and-white checkered turtleneck and platform boots. Natural subway lighting creates an authentic urban scene with a relaxed, unposed feel."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/krea", {
        input: {
            prompt: "A candid street photo of a woman with a pink bob and bold eyeliner on a graffiti-covered subway platform. She wears a bright yellow patent leather coat over a black-and-white checkered turtleneck and platform boots. Natural subway lighting creates an authentic urban scene with a relaxed, unposed feel."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/krea \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A candid street photo of a woman with a pink bob and bold eyeliner on a graffiti-covered subway platform. She wears a bright yellow patent leather coat over a black-and-white checkered turtleneck and platform boots. Natural subway lighting creates an authentic urban scene with a relaxed, unposed feel."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="4.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `4.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated images.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A candid street photo of a woman with a pink bob and bold eyeliner on a graffiti-covered subway platform. She wears a bright yellow patent leather coat over a black-and-white checkered turtleneck and platform boots. Natural subway lighting creates an authentic urban scene with a relaxed, unposed feel.",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 4.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/jpeg",
          "height": 768,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/flux_krea_t2i_output_1.jpg",
          "width": 1024
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Image To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/krea/image-to-image`
    **Endpoint ID:** `fal-ai/flux/krea/image-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/krea/image-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/krea/image-to-image",
          arguments={
              "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
              "prompt": "A cat dressed as a wizard with a background of a mystic forest."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/krea/image-to-image", {
        input: {
            image_url: "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
            prompt: "A cat dressed as a wizard with a background of a mystic forest."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/krea/image-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
        "prompt": "A cat dressed as a wizard with a background of a mystic forest."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to generate an image from.
    </ParamField>

    <ParamField body="strength" type="float" default="0.95">
      The strength of the initial image. Higher strength values are better for this model. Default value: `0.95`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="40">
      The number of inference steps to perform. Default value: `40`

      Range: `10` to `50`
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="4.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `4.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
      "strength": 0.95,
      "num_inference_steps": 40,
      "prompt": "A cat dressed as a wizard with a background of a mystic forest.",
      "guidance_scale": 4.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Redux">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/krea/redux`
    **Endpoint ID:** `fal-ai/flux/krea/redux`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/krea/redux/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/krea/redux",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/flux_krea_redux_output_1.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/krea/redux", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/flux_krea_redux_output_1.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/krea/redux \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/flux_krea_redux_output_1.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="4.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `4.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated images.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/flux_krea_redux_output_1.jpg",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 4.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/jpeg",
          "height": 768,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/flux_krea_redux_output_1.jpg",
          "width": 1024
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

Black Forest Labs' FLUX.1 Krea \[dev] delivers high-quality image generation from a **12 billion parameter flow transformer** at \$0.025 per megapixel. Trading raw parameter count for aesthetic refinement through collaboration with Krea AI, this model prioritizes visual quality and commercial viability over pure speed. Built for creators and enterprises needing production-ready images without the licensing restrictions of research-only alternatives.

**Use Cases:** Commercial Product Photography | Marketing Asset Generation | Creative Concept Visualization

***

## Performance

FLUX.1 Krea \[dev] is a commercially-licensed alternative in the FLUX family, offering flexible resolution scaling with per-megapixel pricing that becomes cost-competitive at lower resolutions, delivering 40 generations per \$1.00 at standard sizes.

| Metric                 | Result                                                                                                                 | Context                                                                             |
| :--------------------- | :--------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------- |
| **Parameter Count**    | 12 billion                                                                                                             | Flow transformer architecture optimized for aesthetic quality                       |
| **Inference Steps**    | 28 (default)                                                                                                           | Configurable 1-50 steps for speed/quality tradeoff                                  |
| **Cost per Megapixel** | \$0.025                                                                                                                | 40 generations per \$1.00 at 1MP; images billed by rounding up to nearest megapixel |
| **Max Resolution**     | Up to 4 megapixels                                                                                                     | Flexible aspect ratios via landscape/portrait/square presets                        |
| **Batch Generation**   | 1-4 images                                                                                                             | Single API call generates multiple variations                                       |
| **Related Endpoints**  | [FLUX.1 \[dev\]](https://fal.ai/models/fal-ai/flux/dev), [FLUX.1 SRPO \[dev\]](https://fal.ai/models/fal-ai/flux/srpo) | Standard dev vs aesthetic-tuned vs style-refined variants                           |

***

## Commercial-Ready Generation with Aesthetic Focus

FLUX.1 Krea \[dev] implements a 12 billion parameter flow transformer architecture tuned specifically for aesthetic quality through Black Forest Labs' collaboration with Krea AI. Unlike research-licensed models that restrict commercial use, this variant ships with full commercial permissions while maintaining the prompt interpretation capabilities of the base FLUX.1 architecture.

**What this means for you:**

* **Flexible Resolution Scaling:** Generate from sub-megapixel thumbnails to 4MP hero images with per-megapixel billing, paying only for the resolution you need rather than flat per-image costs

* **Configurable Quality Control:** Adjust inference steps (1-50) and guidance scale (1-20) to balance generation speed against prompt adherence for different production workflows

* **Built-in Safety Filtering:** Optional safety checker validates outputs against NSFW concepts before delivery, reducing moderation overhead for customer-facing applications

* **Batch Efficiency:** Generate up to 4 variations per API call with consistent seed control for A/B testing creative concepts without multiple requests

***

## Technical Specifications

| Spec               | Details                                                                                 |
| :----------------- | :-------------------------------------------------------------------------------------- |
| **Architecture**   | FLUX.1 Krea \[dev]                                                                      |
| **Input Formats**  | Text prompts with optional seed control                                                 |
| **Output Formats** | JPEG, PNG                                                                               |
| **Max Resolution** | 4 megapixels with preset aspect ratios (landscape\_4\_3, portrait\_16\_9, square\_1\_1) |
| **License**        | Commercial use permitted                                                                |

[API Documentation](https://fal.ai/models/fal-ai/flux/krea/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

**[FLUX.1 \[dev\]](https://fal.ai/models/fal-ai/flux/dev) (\$0.025/MP)** – FLUX.1 Krea \[dev] trades the base model's research-only license for commercial permissions while adding aesthetic tuning from Krea AI's dataset at identical pricing. FLUX.1 \[dev] remains ideal for research applications where licensing restrictions aren't a concern.

**[FLUX.1 SRPO \[dev\]](https://fal.ai/models/fal-ai/flux/srpo) (\$0.025/MP)** – FLUX.1 Krea \[dev] prioritizes aesthetic quality through Krea's training data, while SRPO emphasizes style refinement through reinforcement learning. Both share commercial licensing and per-megapixel pricing, with SRPO offering stronger stylistic control for brand-consistent generation.

\*\*[Flux 2 Pro](https://fal.ai/models/fal-ai/flux-2-pro) ($0.055/MP)** – FLUX.1 Krea [dev] delivers commercially-licensed generation at 2.2x lower cost ($0.025 vs \$0.055 per megapixel). Flux 2 Pro provides next-generation prompt understanding and detail preservation for applications where maximum quality justifies the premium pricing.

\*\*[Flux 2 Flex](https://fal.ai/models/fal-ai/flux-2-flex) ($0.035/MP)** – FLUX.1 Krea [dev] offers 1.4x cost savings ($0.025 vs \$0.035 per megapixel) while maintaining commercial licensing. Flux 2 Flex balances the quality improvements of Flux 2 architecture with more accessible pricing for high-volume generation workflows.

## Related

* [FLUX.1 Krea \[dev\]](/model-api-reference/image-generation-api/flux.1-krea) — Image Generation
* [FLUX.1 Krea \[dev\] Redux](/model-api-reference/image-generation-api/flux.1-krea-redux) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_inference_steps` range: 1 to 50
* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `acceleration` restricted to: `none`, `regular`, `high`
* Content moderation via safety checker
* `strength` range: 0.01 to 1
* `num_inference_steps` range: 10 to 50


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-lora.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Lora API

> API reference for Flux Lora. Super fast endpoint for the FLUX.1 [dev] model with LoRA support, enabling rapid and high-quality image generation using pre-trained LoRA adaptations for personalization, 

<Tabs>
  <Tab title="Flux Lora">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-lora`
    **Endpoint ID:** `fal-ai/flux-lora`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-lora/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-lora",
          arguments={
              "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-lora", {
        input: {
            prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-lora \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      }'
      ```
    </CodeGroup>

    ## Examples

    > Gal gadot, wearing jacket and tie

    <Frame>
      <img src="https://fal.media/files/penguin/hHhmyazpcSq_W8c0TzXl4_14015fe83e3541848e6b2e2e1c7e4968.jpg" alt="Generated image: Gal gadot, wearing jacket and tie" />
    </Frame>

    > a trtcrd of a person on a computer, on the computer you see a meme being made with an ancient looking trollface, "the shitposter" arcana, in the style of TOK a trtcrd, tarot style

    <Frame>
      <img src="https://fal.media/files/penguin/82xiDnqE_nRov7s5GuOAM_2654d4ddc62e4e2490207d2d8f115583.jpg" alt="Generated image: a trtcrd of a person on a computer, on the computer you see a meme being made wi" />
    </Frame>

    > two warriors fighting, in the middle, white background

    <Frame>
      <img src="https://fal.media/files/tiger/j48DGzlaA5ai3CmjDYkJ5_1b5ad1d0b6974989a196738d8c01211f.jpg" alt="Generated image: two warriors fighting, in the middle, white background" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="loras" type="list<LoraWeight>" default="">
      The LoRAs to use for the image generation. You can use any number of LoRAs
      and they will be merged together to generate the final image.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `0` to `35`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. This is always set to 1 for streaming output. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      Acceleration level for image generation. 'regular' balances speed and quality. Default value: `"none"`

      Possible values: `none`, `regular`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Image To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-lora/image-to-image`
    **Endpoint ID:** `fal-ai/flux-lora/image-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-lora/image-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-lora/image-to-image",
          arguments={
              "prompt": "A photo of a lion sitting on a stone bench",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/dog.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-lora/image-to-image", {
        input: {
            prompt: "A photo of a lion sitting on a stone bench",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/dog.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-lora/image-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A photo of a lion sitting on a stone bench",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/dog.png"
      }'
      ```
    </CodeGroup>

    ## Examples

    > Gal gadot looking at the camera

    <Frame>
      <img src="https://fal.media/files/penguin/W1MCCCS1mShfWJcGUadZ7_0feb0b615bb549ed9cd968069938e5e5.jpg" alt="Generated image: Gal gadot looking at the camera" />
    </Frame>

    > Bald man giving conference talk

    <Frame>
      <img src="https://fal.media/files/kangaroo/YWwOfoIP2uNd1C0_Smnd8_62166b4abd164f9794b651038c86c012.jpg" alt="Generated image: Bald man giving conference talk" />
    </Frame>

    > eh\_style, The image showcases a tiger

    <Frame>
      <img src="https://fal.media/files/zebra/--Ktg0V5aJPxKUFvHfyo1_a4b9ae4678a045189c1f4b5f9742511f.jpg" alt="Generated image: eh_style, The image showcases a tiger" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum">
      The size of the generated image.

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="loras" type="list<LoraWeight>" default="">
      The LoRAs to use for the image generation. You can use any number of LoRAs
      and they will be merged together to generate the final image.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `0` to `35`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. This is always set to 1 for streaming output. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      Acceleration level for image generation. 'regular' balances speed and quality. Default value: `"none"`

      Possible values: `none`, `regular`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of image to use for inpainting. or img2img
    </ParamField>

    <ParamField body="strength" type="float" default="0.85">
      The strength to use for inpainting/image-to-image. Only used if the image\_url is provided. 1.0 is completely remakes the image while 0.0 preserves the original. Default value: `0.85`

      Range: `0.01` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A photo of a lion sitting on a stone bench",
      "num_inference_steps": 28,
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none",
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/dog.png",
      "strength": 0.85
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Inpainting">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-lora/inpainting`
    **Endpoint ID:** `fal-ai/flux-lora/inpainting`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-lora/inpainting/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-lora/inpainting",
          arguments={
              "prompt": "A photo of a lion sitting on a stone bench",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/dog.png",
              "mask_url": "https://storage.googleapis.com/falserverless/example_inputs/dog_mask.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-lora/inpainting", {
        input: {
            prompt: "A photo of a lion sitting on a stone bench",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/dog.png",
            mask_url: "https://storage.googleapis.com/falserverless/example_inputs/dog_mask.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-lora/inpainting \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A photo of a lion sitting on a stone bench",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/dog.png",
        "mask_url": "https://storage.googleapis.com/falserverless/example_inputs/dog_mask.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum">
      The size of the generated image.

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="loras" type="list<LoraWeight>" default="">
      The LoRAs to use for the image generation. You can use any number of LoRAs
      and they will be merged together to generate the final image.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `0` to `35`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. This is always set to 1 for streaming output. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      Acceleration level for image generation. 'regular' balances speed and quality. Default value: `"none"`

      Possible values: `none`, `regular`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of image to use for inpainting. or img2img
    </ParamField>

    <ParamField body="strength" type="float" default="0.85">
      The strength to use for inpainting/image-to-image. Only used if the image\_url is provided. 1.0 is completely remakes the image while 0.0 preserves the original. Default value: `0.85`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="mask_url" type="string" required>
      The mask to area to Inpaint in.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A photo of a lion sitting on a stone bench",
      "num_inference_steps": 28,
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none",
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/dog.png",
      "strength": 0.85,
      "mask_url": "https://storage.googleapis.com/falserverless/example_inputs/dog_mask.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Stream">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-lora/stream`
    **Endpoint ID:** `fal-ai/flux-lora/stream`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-lora/stream/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-lora/stream",
          arguments={
              "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-lora/stream", {
        input: {
            prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-lora/stream \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="loras" type="list<LoraWeight>" default="">
      The LoRAs to use for the image generation. You can use any number of LoRAs
      and they will be merged together to generate the final image.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `0` to `35`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. This is always set to 1 for streaming output. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      Acceleration level for image generation. 'regular' balances speed and quality. Default value: `"none"`

      Possible values: `none`, `regular`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## FLUX.1 \[dev] with LoRAs - High-Performance Text-to-Image Generation

Transform your text descriptions into stunning images with FLUX.1 \[dev] with LoRA support, enabling rapid and high-quality image generation using pre-trained LoRA adaptations for personalization, specific styles, brand identities, and product-specific outputs.

### Overview

FLUX.1 \[dev] with LoRAs is a super fast endpoint powered by a 12 billion parameter flow transformer architecture that delivers exceptional image generation capabilities with LoRA support. Whether you're creating personalized content, generating marketing assets with specific styles, or exploring creative ideas with custom adaptations, FLUX LoRA provides the perfect balance of speed, quality, and customization.

### Key Features

Experience industry-leading capabilities designed for both personal and commercial projects:

#### Advanced LoRA Integration

Transform your vision with precise control over image generation through pre-trained LoRA adaptations. Apply custom styles, brand identities, and personalized elements seamlessly.

#### Lightning-Fast Generation

Generate high-quality images in seconds with our optimized inference pipeline, leveraging the power of the FLUX.1 \[dev] model architecture.

#### Commercial-Ready Output

All generated images are cleared for commercial use, making FLUX LoRA ideal for professional creative workflows and business applications.

### Getting Started

Getting started with FLUX LoRA is straightforward. Here's how to begin:

1. **Install the SDK**
   Choose your preferred language:

```bash theme={null}
# For JavaScript/TypeScript
npm install --save @fal-ai/client

# For Python
pip install fal-client
```

2. **Configure Authentication**

```typescript theme={null}
import { fal } from '@fal-ai/client'

fal.config({
  credentials: 'YOUR_FAL_KEY'
})
```

3. **Generate Your First Image**

```typescript theme={null}
const result = await fal.subscribe('fal-ai/flux-lora', {
  input: {
    prompt: 'A serene landscape at sunset, painted in watercolor style',
    loras: [
      {
        path: 'https://example.com/watercolor-style-lora.safetensors',
        scale: 1.0
      }
    ]
  }
})
```

### Best Practices

Maximize your results with these proven approaches:

#### Prompt Engineering

Write detailed, specific prompts that describe both content and style. For example, instead of "a cat," try "a Persian cat sitting in a sunlit window, painted in soft watercolor style."

#### LoRA Configuration

* Use appropriate LoRA scales (typically 0.5-1.5) to balance style application
* Combine multiple LoRAs for complex styling effects
* Test different LoRA combinations for unique results

#### Parameter Optimization

Start with default parameters and adjust based on your needs. The model is optimized for rapid generation while maintaining high quality output.

### Technical Specifications

#### Model Architecture

* 12 billion parameter FLUX.1 \[dev] model
* Flow transformer architecture
* LoRA adaptation support
* Support for multiple image dimensions
* Commercial use licensing

#### Input Capabilities

* Text prompts with detailed descriptions
* Multiple LoRA model support
* Negative prompts for content exclusion
* Resolution control and customization

#### Performance

* Super fast inference optimized for speed
* Concurrent request handling
* Reliable uptime and availability

### API Reference

The FLUX LoRA API accepts the following core parameters:

```typescript theme={null}
interface FluxLoRAParameters {
  prompt: string;              // Your detailed text description
  loras?: Array<{             // LoRA models to apply
    path: string;             // URL to LoRA model file
    scale: number;            // Application strength (0-2)
  }>;
  negative_prompt?: string;    // Elements to avoid in generation
  width?: number;             // Output image width
  height?: number;            // Output image height
  num_inference_steps?: number; // Generation steps
  guidance_scale?: number;     // Prompt adherence strength
  seed?: number;              // For reproducible results
}
```

### Pricing and Usage

Your request will cost \$0.035 per megapixel. Images are billed by rounding up to the nearest megapixel. Our transparent, usage-based pricing scales with your needs:

* Pay-per-use model based on image resolution
* No subscription fees or minimum commitments
* Commercial usage rights included
* Competitive rates for high-volume usage

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Support and Resources

Take advantage of our comprehensive support system:

#### Documentation

Access detailed guides and reference materials at our documentation portal at [https://docs.fal.ai/](https://docs.fal.ai/)

#### Community Support

Join our active developer community for tips, tricks, and troubleshooting help.

#### Professional Support

Enterprise users receive dedicated support channels and priority assistance.

Ready to transform your creative workflow with FLUX LoRA? Sign up for an API key and start generating stunning, personalized images today. Visit our dashboard to begin your journey with one of the most powerful text-to-image models with LoRA support available.

## Related

* [FLUX.1 \[dev\] with LoRAs](/model-api-reference/image-generation-api/flux.1-with-loras) — Image Generation
* [FLUX.1 \[dev\] Inpainting with LoRAs](/model-api-reference/image-generation-api/flux.1-inpainting-with-loras) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_inference_steps` range: 1 to 50
* `guidance_scale` range: 0 to 35
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `acceleration` restricted to: `none`, `regular`
* Content moderation via safety checker
* `strength` range: 0.01 to 1


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-kontext.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro Kontext API

> API reference for Flux Pro Kontext. FLUX.1 Kontext [pro] handles both text and reference images as inputs, seamlessly enabling targeted, local edits and complex transformations of entire scenes.

**Endpoint:** `POST https://fal.run/fal-ai/flux-pro/kontext`
**Endpoint ID:** `fal-ai/flux-pro/kontext`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/kontext/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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-pro/kontext",
      arguments={
          "prompt": "Put a donut next to the flour.",
          "image_url": "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/flux-pro/kontext", {
    input: {
        prompt: "Put a donut next to the flour.",
        image_url: "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/flux-pro/kontext \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Put a donut next to the flour.",
    "image_url": "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
  }'
  ```
</CodeGroup>

## Examples

> Change the car color to red

<Frame>
  <img src="https://fal.media/files/elephant/foZaaLzgc--Vlcy3XwrNQ_c51f2cc166534c5997dcc0b072e41e09.jpg" alt="Generated image: Change the car color to red" />
</Frame>

> Change to daytime while maintaining the same style of the painting

<Frame>
  <img src="https://fal.media/files/rabbit/GRI9hy9WsdNvdvwVTX7TP_4964a4d288b843c5a530e53a5466eaca.jpg" alt="Generated image: Change to daytime while maintaining the same style of the painting" />
</Frame>

> Convert to pencil sketch with natural graphite lines, cross-hatching, and visible paper texture

<Frame>
  <img src="https://fal.media/files/rabbit/GjGQSyySh5WG7HVsQNMyf_a24abeceb8cb4d2f9c31c55cd33b5c8c.jpg" alt="Generated image: Convert to pencil sketch with natural graphite lines, cross-hatching, and visibl" />
</Frame>

## FLUX.1 Kontext \[pro] - Advanced Image-to-Image Generation and Editing

Transform your images with intelligent editing using FLUX.1 Kontext \[pro], a powerful 12-billion parameter multimodal flow transformer designed for in-context image generation and editing. Seamlessly modify existing images with simple text instructions while preserving character consistency and visual quality.

### Overview

FLUX.1 Kontext \[pro] delivers exceptional image editing and generation capabilities through its multimodal architecture. Built to understand both text and visual context, it excels at intelligent image modifications, character preservation, and complex scene transformations without requiring fine-tuning or complex workflows.

#### Key Capabilities

* **In-context image editing** with simple text instructions
* **Character consistency** preservation across multiple edits
* **Local and global editing** capabilities in one unified model
* **Text-to-image generation** with state-of-the-art prompt following
* **Typography handling** for text editing within images
* **Commercial-ready output** quality with fast inference

### Popular Use Cases

**Creative Image Editing**
Modify existing images with natural language instructions. Change styles, swap objects, adjust lighting, or transform scenes while maintaining visual coherence.

**Character Consistency**
Preserve unique characters, objects, or styles across different scenes and environments without any fine-tuning required.

**Typography and Text Editing**
Seamlessly edit text within images - change signs, labels, posters, or any text elements with precision.

**Style Transfer and Remixing**
Transform images from one artistic style to another - oil painting to pencil sketch, modern poster to surreal collage.

### Getting Started

Getting up and running with FLUX.1 Kontext \[pro] takes just a few minutes. Here's how to begin:

1. Get your API key at [https://fal.ai/login](https://fal.ai/login)
2. Install the client library for your preferred language
3. Make your first API call

For JavaScript/TypeScript:

```javascript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY"
});

const result = await fal.subscribe("fal-ai/flux-pro/kontext", {
  input: {
    prompt: "Change the red car to blue while keeping everything else the same",
    image_url: "https://your-image-url.com/image.jpg"
  }
});
```

For Python:

```python theme={null}
from fal_client import FalClient

client = FalClient("YOUR_FAL_KEY")
result = client.subscribe("fal-ai/flux-pro/kontext", {
    "prompt": "Change the red car to blue while keeping everything else the same",
    "image_url": "https://your-image-url.com/image.jpg"
})
```

### Technical Specifications

#### Model Architecture

* 12 billion parameter multimodal flow transformer
* In-context image generation and editing capabilities
* Handles both text and reference images as inputs
* Supports targeted local edits and complex scene transformations

#### Input Capabilities

* **Image input**: jpg, jpeg, png, webp, gif, avif formats
* **Text prompts**: Natural language editing instructions
* **Multimodal processing**: Simultaneous text and image understanding

#### Performance

* Fast inference optimized for iterative editing
* Up to 8x faster than competing state-of-the-art models
* Minimal latency for real-time creative workflows
* 99.9% uptime guarantee

### Best Practices

Achieve optimal results with these proven approaches:

#### Write Clear Edit Instructions

Be specific about what you want to change and what should remain the same. Instead of "make it better," try "change the background to a sunset while keeping the person's pose and clothing identical."

#### Leverage Character Consistency

Use Kontext's strength in preserving characters across edits. You can modify lighting, backgrounds, or scenes while maintaining the same person, object, or style.

#### Handle Text Editing Precisely

When editing text in images, specify exactly what text to change and what it should become: "Change 'SALE' to 'SOLD OUT' on the storefront sign."

#### Iterative Refinement

Build upon previous edits through multiple turns while maintaining visual consistency and character identity.

### Advanced Features

#### Local and Global Editing

* **Targeted edits**: Modify specific regions or objects
* **Scene transformations**: Change entire backgrounds or contexts
* **Style preservation**: Maintain artistic consistency during modifications

#### Multi-turn Editing

Refine images through successive edits while preserving quality and character consistency across multiple editing sessions.

#### Context Understanding

The model reads both image context and text instructions to ensure edits make logical and visual sense.

### API Reference

The FLUX.1 Kontext \[pro] API accepts the following core parameters:

```typescript theme={null}
interface FluxKontextParameters {
  prompt: string;              // Your editing instruction
  image_url: string;          // Input image to edit
  guidance_scale?: number;     // Prompt adherence strength
  num_inference_steps?: number; // Generation steps
  seed?: number;              // For reproducible results
}
```

### Pricing and Usage

Your request will cost \$0.04 per image. Our transparent, per-image pricing makes it cost-effective for both experimentation and production use:

* Fixed \$0.04 cost per image edit
* No hidden fees or minimum commitments
* Commercial usage rights included
* Volume discounts available for enterprise users

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Support and Resources

We're here to help you succeed with FLUX.1 Kontext \[pro]:

* **Documentation**: Complete API reference at [https://docs.fal.ai/](https://docs.fal.ai/)
* **Community**: Join our Discord for support and creative showcases
* **Examples**: Browse our GitHub repository for sample implementations
* **Support**: Enterprise support available for production deployments

Ready to transform your images with intelligent editing? Sign up now at [https://fal.ai](https://fal.ai) and start creating with FLUX.1 Kontext \[pro].

[Get Started with FLUX Kontext Pro](https://fal.ai/login)

## Related

* [FLUX.1 Kontext \[max\]](/model-api-reference/image-generation-api/flux.1-kontext) — Image Generation

## Capabilities

* Text prompt input
* Reproducible generation (seed)
* CFG guidance scale
* Synchronous mode
* Batch generation
* Aspect ratio control
* Image input

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to generate an image from.
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.
</ParamField>

<ParamField body="guidance_scale" type="float" default="3.5">
  The CFG (Classifier Free Guidance) scale is a measure of how close you want
  the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

  Range: `1` to `20`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  The number of images to generate. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
  The format of the generated image. Default value: `"jpeg"`

  Possible values: `jpeg`, `png`
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
  The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="enhance_prompt" type="boolean" default="false">
  Whether to enhance the prompt for better results.
</ParamField>

<ParamField body="aspect_ratio" type="Enum">
  The aspect ratio of the generated image.

  Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
</ParamField>

<ParamField body="image_url" type="string" required>
  Image prompt for the omni model.
</ParamField>

### Output Schema

<ParamField body="images" type="list<fal__toolkit__image__image__Image>" required>
  The generated image files info.
</ParamField>

<ParamField body="timings" type="Timings" required />

<ParamField body="seed" type="integer" required>
  Seed of the generated Image. It will be the same value of the one passed in the
  input or the randomly generated that was used in case none was passed.
</ParamField>

<ParamField body="has_nsfw_concepts" type="list<boolean>" required>
  Whether the generated images contain NSFW concepts.
</ParamField>

<ParamField body="prompt" type="string" required>
  The prompt used for generating the image.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Put a donut next to the flour.",
  "guidance_scale": 3.5,
  "sync_mode": false,
  "num_images": 1,
  "output_format": "jpeg",
  "safety_tolerance": "2",
  "enhance_prompt": false,
  "image_url": "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "height": 1024,
      "url": "https://fal.media/files/tiger/7dSJbIU_Ni-0Zp9eaLsvR_fe56916811d84ac69c6ffc0d32dca151.jpg",
      "width": 1024
    }
  ],
  "prompt": ""
}
```

## Limitations

* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-kontext-max.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro Kontext Max API

> API reference for Flux Pro Kontext Max. FLUX.1 Kontext [max] is a model with greatly improved prompt adherence and typography generation meet premium consistency for editing without compromise on spee

<Tabs>
  <Tab title="Max">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/kontext/max`
    **Endpoint ID:** `fal-ai/flux-pro/kontext/max`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/kontext/max/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/kontext/max",
          arguments={
              "prompt": "Put a donut next to the flour.",
              "image_url": "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/kontext/max", {
        input: {
            prompt: "Put a donut next to the flour.",
            image_url: "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/kontext/max \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Put a donut next to the flour.",
        "image_url": "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
      }'
      ```
    </CodeGroup>

    ## Examples

    > Restyle to Claymation style

    <Frame>
      <img src="https://fal.media/files/tiger/NxnvoLdxc1p_3ljO7vMfo_dd512383bc0b40f482e3d69c29eee7dd.jpg" alt="Generated image: Restyle to Claymation style" />
    </Frame>

    > Change the car color to green

    <Frame>
      <img src="https://fal.media/files/monkey/DhxZDjTxGUjSWm0Av-uf2_d6fdab7825624bfd940fa26b6a739ac0.jpg" alt="Generated image: Change the car color to green" />
    </Frame>

    > replace ‘joy’ by ‘fal"

    <Frame>
      <img src="https://fal.media/files/koala/-hqPr8EPFnQjOKAx8qpBr_472b0b363e8d451aad4737b85fa67cfc.jpg" alt="Generated image: replace ‘joy’ by ‘fal'" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum">
      The aspect ratio of the generated image.

      Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      Image prompt for the omni model.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<fal__toolkit__image__image__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Put a donut next to the flour.",
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "image_url": "https://v3.fal.media/files/rabbit/rmgBxhwGYb2d3pl3x9sKf_output.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "height": 1024,
          "url": "https://fal.media/files/tiger/7dSJbIU_Ni-0Zp9eaLsvR_fe56916811d84ac69c6ffc0d32dca151.jpg",
          "width": 1024
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Multi">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/kontext/max/multi`
    **Endpoint ID:** `fal-ai/flux-pro/kontext/max/multi`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/kontext/max/multi/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/kontext/max/multi",
          arguments={
              "prompt": "Put the little duckling on top of the woman's t-shirt.",
              "image_urls": [
                  "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
                  "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/kontext/max/multi", {
        input: {
            prompt: "Put the little duckling on top of the woman's t-shirt.",
            image_urls: [
              "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
              "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/kontext/max/multi \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Put the little duckling on top of the woman'\''s t-shirt.",
        "image_urls": [
          "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
          "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum">
      The aspect ratio of the generated image.

      Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      Image prompt for the omni model.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Put the little duckling on top of the woman's t-shirt.",
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "image_urls": [
        "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
        "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Text To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/kontext/max/text-to-image`
    **Endpoint ID:** `fal-ai/flux-pro/kontext/max/text-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/kontext/max/text-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/kontext/max/text-to-image",
          arguments={
              "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/kontext/max/text-to-image", {
        input: {
            prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/kontext/max/text-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      }'
      ```
    </CodeGroup>

    ## Examples

    > A solo figure sits on a wooden stool in a dimly lit virtual reality dive bar with textured concrete walls and neon art by Nick Knight.

    <Frame>
      <img src="https://fal.media/files/rabbit/K-A-imOTZKtaWboFHPKTj_74805e96dd464edc901bcddd5ce07269.jpg" alt="Generated image: A solo figure sits on a wooden stool in a dimly lit virtual reality dive bar wit" />
    </Frame>

    > In the mystical realm of Aethereia, where moonlit rivers flowed with stardust and crystal forests pierced the sky, a serene marble bath tub sat at the river's edge, surrounded by luxury decor that shimmered with an ethereal glow, as if infused with the soft, sensual light of sun rays dancing through...

    <Frame>
      <img src="https://fal.media/files/kangaroo/WiEFDKf38mGbnJo37QUHy_84694c7394b54c23b99a9f082c1792d2.jpg" alt="Generated image: In the mystical realm of Aethereia, where moonlit rivers flowed with stardust an" />
    </Frame>

    > A woman stands centered in a secret underground city, surrounded by blurred foliage and a creek, under an overcast sky with natural light.

    <Frame>
      <img src="https://fal.media/files/panda/oDah6AfQ4PZBqPfVYYXxH_43189bb6989d47eaa994cee66829178f.jpg" alt="Generated image: A woman stands centered in a secret underground city, surrounded by blurred foli" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the generated image. Default value: `"1:1"`

      Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "aspect_ratio": "1:1"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [FLUX.1 Kontext \[pro\]](/model-api-reference/image-generation-api/flux.1-kontext) — Image Generation

## Limitations

* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-kontext-multi.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro Kontext Multi API

> API reference for Flux Pro Kontext Multi. Experimental version of FLUX.1 Kontext [pro] with multi image handling capabilities

**Endpoint:** `POST https://fal.run/fal-ai/flux-pro/kontext/multi`
**Endpoint ID:** `fal-ai/flux-pro/kontext/multi`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/kontext/multi/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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-pro/kontext/multi",
      arguments={
          "prompt": "Put the little duckling on top of the woman's t-shirt.",
          "image_urls": [
              "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
              "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
          ]
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/flux-pro/kontext/multi", {
    input: {
        prompt: "Put the little duckling on top of the woman's t-shirt.",
        image_urls: [
          "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
          "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
        ]
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/flux-pro/kontext/multi \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Put the little duckling on top of the woman'\''s t-shirt.",
    "image_urls": [
      "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
      "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
    ]
  }'
  ```
</CodeGroup>

## Related

* [FLUX.1 Kontext \[pro\]](/model-api-reference/image-generation-api/flux.1-kontext) — Image Generation

## Capabilities

* Text prompt input
* Reproducible generation (seed)
* CFG guidance scale
* Synchronous mode
* Batch generation
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to generate an image from.
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.
</ParamField>

<ParamField body="guidance_scale" type="float" default="3.5">
  The CFG (Classifier Free Guidance) scale is a measure of how close you want
  the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

  Range: `1` to `20`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  The number of images to generate. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
  The format of the generated image. Default value: `"jpeg"`

  Possible values: `jpeg`, `png`
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
  The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="enhance_prompt" type="boolean" default="false">
  Whether to enhance the prompt for better results.
</ParamField>

<ParamField body="aspect_ratio" type="Enum">
  The aspect ratio of the generated image.

  Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
</ParamField>

<ParamField body="image_urls" type="list<string>" required>
  Image prompt for the omni model.
</ParamField>

### Output Schema

<ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
  The generated image files info.
</ParamField>

<ParamField body="timings" type="Timings" required />

<ParamField body="seed" type="integer" required>
  Seed of the generated Image. It will be the same value of the one passed in the
  input or the randomly generated that was used in case none was passed.
</ParamField>

<ParamField body="has_nsfw_concepts" type="list<boolean>" required>
  Whether the generated images contain NSFW concepts.
</ParamField>

<ParamField body="prompt" type="string" required>
  The prompt used for generating the image.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Put the little duckling on top of the woman's t-shirt.",
  "guidance_scale": 3.5,
  "sync_mode": false,
  "num_images": 1,
  "output_format": "jpeg",
  "safety_tolerance": "2",
  "enhance_prompt": false,
  "image_urls": [
    "https://v3.fal.media/files/penguin/XoW0qavfF-ahg-jX4BMyL_image.webp",
    "https://v3.fal.media/files/tiger/bml6YA7DWJXOigadvxk75_image.webp"
  ]
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "",
      "content_type": "image/jpeg"
    }
  ],
  "prompt": ""
}
```

## Limitations

* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-kontext-text-to-image.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro Kontext Text To Image API

> API reference for Flux Pro Kontext Text To Image. The FLUX.1 Kontext [pro] text-to-image delivers state-of-the-art image generation results with unprecedented prompt following, photorealistic renderin

**Endpoint:** `POST https://fal.run/fal-ai/flux-pro/kontext/text-to-image`
**Endpoint ID:** `fal-ai/flux-pro/kontext/text-to-image`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/kontext/text-to-image/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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-pro/kontext/text-to-image",
      arguments={
          "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/flux-pro/kontext/text-to-image", {
    input: {
        prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/flux-pro/kontext/text-to-image \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
  }'
  ```
</CodeGroup>

## Examples

> A close-up artistic photograph of fresh blueberries on a white surface. The surface has a marbled, fluid texture with swirls of white and various shades of blue, creating an abstract, paint-like effect. The blueberries are scattered across the image, some sitting on the white areas and others nestle...

<Frame>
  <img src="https://fal.media/files/monkey/KK28aOq4SU5fvO4z07lVf_423e9f92d5f7468482fdb4a5cb687d9b.jpg" alt="Generated image: A close-up artistic photograph of fresh blueberries on a white surface. The surf" />
</Frame>

> A visually stunning image of the Turritopsis dohrnii jellyfish floating gracefully in clear water. Include a close-up of its unique, translucent body, showcasing the regeneration process. The background should have a serene underwater environment with soft lighting.

<Frame>
  <img src="https://fal.media/files/zebra/iQ_6a5f8FmqNf4hYKcdrc_9127559d25e4471cba85a3a4112c25f5.jpg" alt="Generated image: A visually stunning image of the Turritopsis dohrnii jellyfish floating graceful" />
</Frame>

> In the foreground is a pizza, in the background the word "Fal Pizzeria" is written in neon by a wood-fired pizza oven, next to the pizza pepper and mushrooms are artistically used to show freshness and freshness, a colorful and attractive color palette is used , dynamic image, food photography

<Frame>
  <img src="https://fal.media/files/zebra/h-KsemUBS-5Hm7_0x6Llr_7ded93416e2442feaf72311e1c8de78e.jpg" alt="Generated image: In the foreground is a pizza, in the background the word 'Fal Pizzeria' is writt" />
</Frame>

## Related

* [FLUX.1 Kontext \[pro\]](/model-api-reference/image-generation-api/flux.1-kontext) — Image Generation

## Capabilities

* Text prompt input
* Reproducible generation (seed)
* CFG guidance scale
* Synchronous mode
* Batch generation
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to generate an image from.
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.
</ParamField>

<ParamField body="guidance_scale" type="float" default="3.5">
  The CFG (Classifier Free Guidance) scale is a measure of how close you want
  the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

  Range: `1` to `20`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  The number of images to generate. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
  The format of the generated image. Default value: `"jpeg"`

  Possible values: `jpeg`, `png`
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
  The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="enhance_prompt" type="boolean" default="false">
  Whether to enhance the prompt for better results.
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
  The aspect ratio of the generated image. Default value: `"1:1"`

  Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
</ParamField>

### Output Schema

<ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
  The generated image files info.
</ParamField>

<ParamField body="timings" type="Timings" required />

<ParamField body="seed" type="integer" required>
  Seed of the generated Image. It will be the same value of the one passed in the
  input or the randomly generated that was used in case none was passed.
</ParamField>

<ParamField body="has_nsfw_concepts" type="list<boolean>" required>
  Whether the generated images contain NSFW concepts.
</ParamField>

<ParamField body="prompt" type="string" required>
  The prompt used for generating the image.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
  "guidance_scale": 3.5,
  "sync_mode": false,
  "num_images": 1,
  "output_format": "jpeg",
  "safety_tolerance": "2",
  "enhance_prompt": false,
  "aspect_ratio": "1:1"
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "",
      "content_type": "image/jpeg"
    }
  ],
  "prompt": ""
}
```

## Limitations

* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-v1.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro V1 API

> API reference for Flux Pro V1. FLUX.1 [pro] Fill is a high-performance endpoint for the FLUX.1 [pro] model that enables rapid transformation of existing images, delivering high-quality style transfers

<Tabs>
  <Tab title="Fill">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/v1/fill`
    **Endpoint ID:** `fal-ai/flux-pro/v1/fill`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/v1/fill/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/v1/fill",
          arguments={
              "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
              "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
              "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/v1/fill", {
        input: {
            prompt: "A knight in shining armour holding a greatshield with \"FAL\" on it",
            image_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
            mask_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/v1/fill \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
        "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
        "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to fill the masked part of the image.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to generate an image from. Needs to match the dimensions of the mask.
    </ParamField>

    <ParamField body="mask_url" type="string" required>
      The mask URL to inpaint the image. Needs to match the dimensions of the input image.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
      "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Fill Finetuned">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/v1/fill-finetuned`
    **Endpoint ID:** `fal-ai/flux-pro/v1/fill-finetuned`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/v1/fill-finetuned/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/v1/fill-finetuned",
          arguments={
              "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
              "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
              "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg",
              "finetune_id": ""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/v1/fill-finetuned", {
        input: {
            prompt: "A knight in shining armour holding a greatshield with \"FAL\" on it",
            image_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
            mask_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg",
            finetune_id: ""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/v1/fill-finetuned \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
        "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
        "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg",
        "finetune_id": ""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to fill the masked part of the image.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to generate an image from. Needs to match the dimensions of the mask.
    </ParamField>

    <ParamField body="mask_url" type="string" required>
      The mask URL to inpaint the image. Needs to match the dimensions of the input image.
    </ParamField>

    <ParamField body="finetune_id" type="string" required>
      References your specific model
    </ParamField>

    <ParamField body="finetune_strength" type="float" required>
      Controls finetune influence.
      Increase this value if your target concept isn't showing up strongly enough.
      The optimal setting depends on your finetune and prompt

      Range: `0` to `2`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
      "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg",
      "finetune_id": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

Black Forest Labs' FLUX.1 \[pro] delivers professional-grade inpainting at \$0.05 per megapixel. Trading broad creative generation for surgical precision, this endpoint excels at targeted modifications, replacing objects, filling gaps, or seamlessly blending new elements into existing compositions without regenerating entire images.

**Use Cases:** Product photo editing | Architectural visualization refinement | E-commerce asset modification

***

## Performance

FLUX.1 \[pro] Fill operates at competitive inference speeds while maintaining the quality standards of the full FLUX.1 \[pro] architecture, with cost scaling directly to output resolution rather than flat per-inference pricing.

| Metric                 | Result                                                                                                                                               | Context                                              |
| :--------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------- |
| **Cost per Megapixel** | \$0.05                                                                                                                                               | Billed by rounding up to nearest megapixel           |
| **Output Range**       | 1-4 images                                                                                                                                           | Single API call supports batch generation            |
| **Safety Tolerance**   | 6 levels (1-6)                                                                                                                                       | Configurable content moderation strictness           |
| **Output Formats**     | JPEG, PNG                                                                                                                                            | Standard web-optimized formats                       |
| **Related Endpoints**  | [FLUX.1 Kontext \[pro\]](https://fal.ai/models/fal-ai/flux-pro/kontext), [FLUX.1 Kontext \[max\]](https://fal.ai/models/fal-ai/flux-pro/kontext/max) | Context-aware variants for multi-reference workflows |

***

## Precision Inpainting Without Full Regeneration

FLUX.1 \[pro] Fill operates through mask-based editing rather than full image regeneration, requiring three inputs: your base image, a mask defining the edit region, and a text prompt describing the desired fill content. This approach preserves everything outside the mask untouched while applying FLUX.1 \[pro]'s generation quality only where needed.

**What this means for you:**

* **Surgical precision:** Modify specific objects or regions without risking changes to surrounding elements, critical for product photography where brand consistency matters

* **Dual-input control:** Mask URL and image URL parameters enable programmatic workflows where masks are generated separately (edge detection, object segmentation, manual selection tools)

* **Prompt enhancement option:** Optional `enhance_prompt` parameter applies FLUX's prompt optimization to your instructions, improving interpretation of complex editing requests

* **Batch efficiency:** Generate up to 4 variations per API call with different seeds, useful for A/B testing edits or exploring alternative fills for the same masked region

***

## Technical Specifications

| Spec                    | Details                                                                 |
| :---------------------- | :---------------------------------------------------------------------- |
| **Architecture**        | FLUX.1 \[pro]                                                           |
| **Input Formats**       | Image URL (JPEG, PNG, WebP, GIF, AVIF) + Mask URL (matching dimensions) |
| **Output Formats**      | JPEG, PNG                                                               |
| **Resolution Handling** | Variable (billed per megapixel, rounded up)                             |
| **License**             | Commercial use permitted via fal partnership                            |

[API Documentation](https://fal.ai/models/fal-ai/flux-pro/v1/fill/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

\*\*FLUX.1 Kontext \[pro] ($0.055/MP)** – FLUX.1 [pro] Fill ($0.05/MP) focuses on single-mask inpainting with straightforward prompt-based fills at 9% lower cost. [FLUX.1 Kontext \[pro\]](https://fal.ai/models/fal-ai/flux-pro/kontext) adds multi-reference image conditioning via URL arrays, enabling style transfer and context-aware fills for workflows requiring visual examples beyond text prompts.

\*\*FLUX.1 Kontext \[max] ($0.11/MP)** – FLUX.1 [pro] Fill delivers core inpainting functionality at 55% lower cost ($0.05 vs \$0.11 per megapixel). [FLUX.1 Kontext \[max\]](https://fal.ai/models/fal-ai/flux-pro/kontext/max) trades cost efficiency for maximum quality output and enhanced multi-reference capabilities, ideal for high-end commercial work where generation fidelity justifies premium pricing.

## Related

* [FLUX1.1 \[pro\] ultra](/model-api-reference/image-generation-api/flux1.1-ultra) — Image Generation
* [FLUX1.1 \[pro\]](/model-api-reference/image-generation-api/flux1.1) — Image Generation
* [FLUX1.1 \[pro\] Redux](/model-api-reference/image-generation-api/flux1.1-redux) — Image Generation
* [FLUX1.1 \[pro\] ultra Redux](/model-api-reference/image-generation-api/flux1.1-ultra-redux) — Image Generation
* [FLUX1.1 \[pro\] ultra Fine-tuned](/model-api-reference/image-generation-api/flux1.1-ultra-fine-tuned) — Image Generation
* [FLUX.1 \[pro\] Fill Fine-tuned](/model-api-reference/image-generation-api/flux.1-fill-fine-tuned) — Image Generation
* [FLUX.1 \[pro\] Fill](/model-api-reference/image-generation-api/flux.1-fill) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `finetune_strength` range: 0 to 2


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-v1.1.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro V1.1 API

> API reference for Flux Pro V1.1. FLUX1.1 [pro] is an enhanced version of FLUX.1 [pro], improved image generation capabilities, delivering superior composition, detail, and artistic fidelity compared t

<Tabs>
  <Tab title="V1.1">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/v1.1`
    **Endpoint ID:** `fal-ai/flux-pro/v1.1`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/v1.1/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/v1.1",
          arguments={
              "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/v1.1", {
        input: {
            prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/v1.1 \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      }'
      ```
    </CodeGroup>

    ## Examples

    > A close-up artistic photograph of fresh blueberries on a white surface. The surface has a marbled, fluid texture with swirls of white and various shades of blue, creating an abstract, paint-like effect. The blueberries are scattered across the image, some sitting on the white areas and others nestle...

    <Frame>
      <img src="https://fal.media/files/monkey/uc-qNBVx7VwfdOgxRWOTk_f9dccef1336846ebb6e5e9fb54d39102.jpg" alt="Generated image: A close-up artistic photograph of fresh blueberries on a white surface. The surf" />
    </Frame>

    > A visually stunning image of the Turritopsis dohrnii jellyfish floating gracefully in clear water. Include a close-up of its unique, translucent body, showcasing the regeneration process. The background should have a serene underwater environment with soft lighting.

    <Frame>
      <img src="https://fal.media/files/zebra/OSziSU95wFPfP342slckQ_ecbd433f9d034cfeaa9c064f7d207d2f.jpg" alt="Generated image: A visually stunning image of the Turritopsis dohrnii jellyfish floating graceful" />
    </Frame>

    > A cartoon character walking in autumn nature holding a phone and working on his phone
    > In autumn graphic style

    <Frame>
      <img src="https://fal.media/files/monkey/8-SB6BBmYYgYHAMZEj8Ra_6ee9375c0b58433095425d528a2b9f7c.jpg" alt="Generated image: A cartoon character walking in autumn nature holding a phone and working on his " />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
      "image_size": "landscape_4_3",
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Redux">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/v1.1/redux`
    **Endpoint ID:** `fal-ai/flux-pro/v1.1/redux`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/v1.1/redux/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/v1.1/redux",
          arguments={
              "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/v1.1/redux", {
        input: {
            image_url: "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/v1.1/redux \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" default="">
      The prompt to generate an image from. Default value: `""`
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to generate an image from. Needs to match the dimensions of the mask.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## FLUX1.1 \[pro] - Professional Text-to-Image Generation

Transform your text descriptions into stunning, high-quality images with FLUX1.1 \[pro], an enhanced version of FLUX.1 \[pro] with improved image generation capabilities, delivering superior composition, detail, and artistic fidelity compared to its predecessor.

### Overview

FLUX1.1 \[pro] generates professional-grade images from text descriptions with enhanced performance and speed. Built on a 12 billion parameter flow transformer architecture, it delivers exceptional quality while maintaining rapid generation speeds and superior prompt adherence.

#### Key Capabilities

* **Enhanced image generation** with superior composition and detail
* **Improved prompt adherence** and output diversity
* **Six times faster** than the original FLUX.1 \[pro]
* **Highest Elo score** on Artificial Analysis image arena
* **Commercial-ready image quality** with artistic fidelity
* **Professional-grade performance** optimized for production use

### Getting Started

Getting up and running with FLUX1.1 \[pro] takes just a few minutes. Here's how to begin:

1. Get your API key at [https://fal.ai/login](https://fal.ai/login)
2. Install the client library for your preferred language
3. Make your first API call

#### JavaScript/TypeScript Installation:

```bash theme={null}
npm install --save @fal-ai/client
```

#### Python Installation:

```bash theme={null}
pip install fal-client
```

### Simple Integration Example

Here's a basic example of generating an image using TypeScript:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY"
});

const result = await fal.subscribe("fal-ai/flux-pro/v1.1", {
  input: {
    prompt: "A serene mountain landscape at sunset, photorealistic style"
  }
});
```

### Advanced Features

FLUX1.1 \[pro] offers sophisticated controls for professional use cases:

#### Enhanced Performance

Six times faster generation than its predecessor while maintaining superior image quality and better prompt adherence.

#### Superior Composition

Delivers improved artistic fidelity with enhanced detail rendering and composition quality compared to previous versions.

#### Prompt Adherence

Excels at accurately interpreting and generating images based on complex prompts and specific requirements, making it highly versatile for various creative needs.

#### Output Diversity

Increased variety and creativity in generated outputs while maintaining consistency and quality.

### Best Practices

Maximize your results with these proven approaches:

#### Image Quality

Use detailed, specific prompts that describe both content and style. The enhanced prompt adherence means more precise descriptions yield better results.

#### Performance Optimization

Take advantage of the improved speed while maintaining high quality output. The model balances efficiency with superior visual fidelity.

#### Production Implementation

Implement proper error handling and retry logic for robust production deployments. The model's enhanced reliability makes it ideal for enterprise use.

### Technical Specifications

#### Model Architecture

* 12 billion parameter flow transformer
* Enhanced version of FLUX.1 \[pro]
* Hybrid architecture with multimodal and parallel diffusion transformer blocks
* Flow matching methodology with rotary positional embeddings

#### Performance Metrics

* **Speed**: 6x faster than original FLUX.1 \[pro]
* **Quality**: Superior composition, detail, and artistic fidelity
* **Benchmark**: Highest overall Elo score on Artificial Analysis arena
* **Commercial usage**: Approved for professional and commercial use

#### Codename "Blueberry"

FLUX1.1 \[pro] was tested under the codename "blueberry" and achieved the highest overall Elo score among all image models on the Artificial Analysis image arena, surpassing competing models in visual quality and prompt accuracy.

### API Reference

The FLUX1.1 \[pro] API accepts standard text-to-image parameters:

```typescript theme={null}
interface FluxProParameters {
  prompt: string;              // Your detailed text description
  width?: number;             // Output image width
  height?: number;            // Output image height
  num_inference_steps?: number; // Generation steps
  guidance_scale?: number;     // Prompt adherence strength
  seed?: number;              // For reproducible results
}
```

### Pricing and Usage

Your request will cost \$0.04 per megapixel. Images are billed by rounding up to the nearest megapixel. Our transparent, usage-based pricing offers excellent value:

* **Competitive pricing**: \$0.04 per megapixel
* **Commercial usage rights** included
* **No hidden fees** or minimum commitments
* **Enterprise-grade reliability** with cost-effective scaling

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Support and Resources

Additional resources to help you succeed:

#### Documentation

Complete API documentation available at [https://docs.fal.ai/](https://docs.fal.ai/)

#### Community

Join our active developer community for support and inspiration

#### Enterprise Support

Dedicated support channels for enterprise customers

Ready to transform your text into stunning images with the most advanced FLUX model available? Sign up now at [https://fal.ai](https://fal.ai) and start creating with FLUX1.1 \[pro].

[Get Started with FLUX1.1 Pro](https://fal.ai/login)

## Related

* [FLUX1.1 \[pro\] ultra](/model-api-reference/image-generation-api/flux1.1-ultra) — Image Generation
* [FLUX.1 \[pro\] Fill](/model-api-reference/image-generation-api/flux.1-fill) — Image Generation
* [FLUX1.1 \[pro\] Redux](/model-api-reference/image-generation-api/flux1.1-redux) — Image Generation
* [FLUX1.1 \[pro\] ultra Redux](/model-api-reference/image-generation-api/flux1.1-ultra-redux) — Image Generation
* [FLUX1.1 \[pro\] ultra Fine-tuned](/model-api-reference/image-generation-api/flux1.1-ultra-fine-tuned) — Image Generation
* [FLUX.1 \[pro\] Fill Fine-tuned](/model-api-reference/image-generation-api/flux.1-fill-fine-tuned) — Image Generation
* [FLUX1.1 \[pro\]](/model-api-reference/image-generation-api/flux1.1) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `num_inference_steps` range: 1 to 50
* `guidance_scale` range: 1 to 20


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-v1.1-ultra.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro V1.1 Ultra API

> API reference for Flux Pro V1.1 Ultra. FLUX1.1 [pro] ultra is the newest version of FLUX1.1 [pro], maintaining professional-grade image quality while delivering up to 2K resolution with improved photo

<Tabs>
  <Tab title="V1.1 Ultra">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/v1.1-ultra`
    **Endpoint ID:** `fal-ai/flux-pro/v1.1-ultra`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/v1.1-ultra/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/v1.1-ultra",
          arguments={
              "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/v1.1-ultra", {
        input: {
            prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/v1.1-ultra \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="image_url" type="string">
      The image URL to generate an image from.
    </ParamField>

    <ParamField body="image_prompt_strength" type="float" default="0.1">
      The strength of the image prompt, between 0 and 1. Default value: `0.1`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum | string" default="16:9">
      The aspect ratio of the generated image. Default value: `16:9`

      Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
    </ParamField>

    <ParamField body="raw" type="boolean" default="false">
      Generate less processed, more natural-looking images.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "image_prompt_strength": 0.1,
      "aspect_ratio": "16:9",
      "raw": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Redux">
    **Endpoint:** `POST https://fal.run/fal-ai/flux-pro/v1.1-ultra/redux`
    **Endpoint ID:** `fal-ai/flux-pro/v1.1-ultra/redux`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/v1.1-ultra/redux/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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-pro/v1.1-ultra/redux",
          arguments={
              "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux-pro/v1.1-ultra/redux", {
        input: {
            image_url: "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux-pro/v1.1-ultra/redux \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" default="">
      The prompt to generate an image from. Default value: `""`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
      The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="enhance_prompt" type="boolean" default="false">
      Whether to enhance the prompt for better results.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to generate an image from. Needs to match the dimensions of the mask.
    </ParamField>

    <ParamField body="image_prompt_strength" type="float" default="0.1">
      The strength of the image prompt, between 0 and 1. Default value: `0.1`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum | string" default="16:9">
      The aspect ratio of the generated image. Default value: `16:9`

      Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
    </ParamField>

    <ParamField body="raw" type="boolean" default="false">
      Generate less processed, more natural-looking images.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "",
      "sync_mode": false,
      "num_images": 1,
      "output_format": "jpeg",
      "safety_tolerance": "2",
      "enhance_prompt": false,
      "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png",
      "image_prompt_strength": 0.1,
      "aspect_ratio": "16:9",
      "raw": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

Black Forest Labs' FLUX1.1 \[pro] ultra delivers up to 2K resolution (4 megapixels) image generation at \$0.06 per image. With **4x the resolution detail**, this model extends FLUX1.1 \[pro]'s capabilities with enhanced photorealism while maintaining \~10 second generation times. Built for production workflows where resolution and visual fidelity directly impact deliverables.

**Use Cases:** High-resolution marketing assets | Product photography | Editorial illustrations

***

## Performance

At \$0.06 per image with 4-megapixel output capability, FLUX1.1 \[pro] ultra positions between standard-resolution alternatives and premium high-res solutions.

| Metric                | Result                                                                                                                                               | Context                                           |
| :-------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------ |
| **Max Resolution**    | 4 megapixels (2048×2048)                                                                                                                             | 4x standard FLUX1.1 \[pro] resolution             |
| **Inference Speed**   | \~10 seconds per sample                                                                                                                              | Ultra mode generation time from Black Forest Labs |
| **Cost per Image**    | \$0.06                                                                                                                                               | 16.7 images per \$1.00                            |
| **Batch Generation**  | Up to 4 images                                                                                                                                       | Parallel generation via `num_images` parameter    |
| **Related Endpoints** | [FLUX1.1 \[pro\]](https://fal.ai/models/fal-ai/flux-pro/v1.1), [FLUX.1 Kontext \[pro\]](https://fal.ai/models/fal-ai/flux-pro/kontext/text-to-image) | Standard resolution and context-aware variants    |

***

## Professional-Grade Resolution Without Compromise

FLUX1.1 \[pro] ultra extends Black Forest Labs' architecture to 4-megapixel generation while maintaining the **prompt interpretation and photorealism** that defined the standard version. Where most high-resolution models sacrifice inference speed or introduce quality degradation, ultra mode processes at comparable latency to standard-resolution alternatives.

**What this means for you:**

* **True 2K output:** Generate up to 2048×2048 images without upscaling artifacts or post-processing, delivering **print-ready assets** directly from the API

* **Optional image conditioning:** Use `image_url` and `image_prompt_strength` (0-1 range) to guide generation with reference images, enabling style transfer and composition control

* **Flexible aspect ratios:** Support for multiple aspect ratios with automatic megapixel-based billing, pay only for the resolution you actually use

* **Granular safety controls:** Six-level `safety_tolerance` parameter (1-6) lets you calibrate content filtering for your specific use case, from strict (1) to permissive (6)

***

## Technical Specifications

| Spec               | Details                                         |
| :----------------- | :---------------------------------------------- |
| **Architecture**   | FLUX1.1 \[pro] ultra                            |
| **Input Formats**  | Text prompts, optional reference images via URL |
| **Output Formats** | JPEG, PNG                                       |
| **Max Resolution** | 4 megapixels (up to 2048×2048)                  |
| **License**        | Commercial use enabled via fal partnership      |

[API Documentation](https://fal.ai/models/fal-ai/flux-pro/v1.1-ultra/api) | [Quickstart Guide](https://fal.ai/docs) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

\*\*FLUX1.1 \[pro] ($0.05)** – FLUX1.1 [pro] ultra trades cost efficiency for 4x resolution at $0.06 vs \$0.05 (20% premium). Standard [FLUX1.1 \[pro\]](https://fal.ai/models/fal-ai/flux-pro/v1.1) remains ideal for **high-volume workflows** where 1-megapixel output meets requirements and cost per image is the primary constraint.

**FLUX.1 Kontext \[pro] (\$0.05)** – FLUX1.1 \[pro] ultra prioritizes maximum resolution and photorealism for single-image generation. [FLUX.1 Kontext \[pro\]](https://fal.ai/models/fal-ai/flux-pro/kontext/text-to-image) emphasizes **multi-image context understanding** (up to 5 reference images) at standard resolution, optimized for workflows requiring consistent style or character preservation across generations.

\*\*AuraFlow ($0.012)** – FLUX1.1 [pro] ultra delivers professional-grade photorealism and 4-megapixel output at 5x the cost ($0.06 vs \$0.012). [AuraFlow](https://fal.ai/models/fal-ai/aura-flow) offers **open-weight flexibility** and cost efficiency for rapid iteration workflows where resolution and photorealism requirements are secondary to generation volume.

## Related

* [FLUX1.1 \[pro\]](/model-api-reference/image-generation-api/flux1.1) — Image Generation
* [FLUX.1 \[pro\] Fill](/model-api-reference/image-generation-api/flux.1-fill) — Image Generation
* [FLUX1.1 \[pro\] Redux](/model-api-reference/image-generation-api/flux1.1-redux) — Image Generation
* [FLUX1.1 \[pro\] ultra Redux](/model-api-reference/image-generation-api/flux1.1-ultra-redux) — Image Generation
* [FLUX1.1 \[pro\] ultra Fine-tuned](/model-api-reference/image-generation-api/flux1.1-ultra-fine-tuned) — Image Generation
* [FLUX.1 \[pro\] Fill Fine-tuned](/model-api-reference/image-generation-api/flux.1-fill-fine-tuned) — Image Generation
* [FLUX1.1 \[pro\] ultra](/model-api-reference/image-generation-api/flux1.1-ultra) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `image_prompt_strength` range: 0 to 1


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-pro-v1.1-ultra-finetuned.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Pro V1.1 Ultra Finetuned API

> API reference for Flux Pro V1.1 Ultra Finetuned. FLUX1.1 [pro] ultra fine-tuned is the newest version of FLUX1.1 [pro] with a fine-tuned LoRA, maintaining professional-grade image quality while delive

**Endpoint:** `POST https://fal.run/fal-ai/flux-pro/v1.1-ultra-finetuned`
**Endpoint ID:** `fal-ai/flux-pro/v1.1-ultra-finetuned`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux-pro/v1.1-ultra-finetuned/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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-pro/v1.1-ultra-finetuned",
      arguments={
          "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
          "finetune_id": ""
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/flux-pro/v1.1-ultra-finetuned", {
    input: {
        prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
        finetune_id: ""
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/flux-pro/v1.1-ultra-finetuned \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
    "finetune_id": ""
  }'
  ```
</CodeGroup>

## Related

* [FLUX1.1 \[pro\] ultra](/model-api-reference/image-generation-api/flux1.1-ultra) — Image Generation
* [FLUX1.1 \[pro\]](/model-api-reference/image-generation-api/flux1.1) — Image Generation
* [FLUX.1 \[pro\] Fill](/model-api-reference/image-generation-api/flux.1-fill) — Image Generation
* [FLUX1.1 \[pro\] Redux](/model-api-reference/image-generation-api/flux1.1-redux) — Image Generation
* [FLUX1.1 \[pro\] ultra Redux](/model-api-reference/image-generation-api/flux1.1-ultra-redux) — Image Generation
* [FLUX.1 \[pro\] Fill Fine-tuned](/model-api-reference/image-generation-api/flux.1-fill-fine-tuned) — Image Generation

## Capabilities

* Text prompt input
* Reproducible generation (seed)
* Synchronous mode
* Batch generation
* Image input
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to generate an image from.
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  The number of images to generate. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
  The format of the generated image. Default value: `"jpeg"`

  Possible values: `jpeg`, `png`
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="2">
  The safety tolerance level for the generated image. 1 being the most strict and 5 being the most permissive. Default value: `"2"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="enhance_prompt" type="boolean" default="false">
  Whether to enhance the prompt for better results.
</ParamField>

<ParamField body="image_url" type="string">
  The image URL to generate an image from.
</ParamField>

<ParamField body="image_prompt_strength" type="float" default="0.1">
  The strength of the image prompt, between 0 and 1. Default value: `0.1`

  Range: `0` to `1`
</ParamField>

<ParamField body="aspect_ratio" type="Enum | string" default="16:9">
  The aspect ratio of the generated image. Default value: `16:9`

  Possible values: `21:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:21`
</ParamField>

<ParamField body="raw" type="boolean" default="false">
  Generate less processed, more natural-looking images.
</ParamField>

<ParamField body="finetune_id" type="string" required>
  References your specific model
</ParamField>

<ParamField body="finetune_strength" type="float" required>
  Controls finetune influence.
  Increase this value if your target concept isn't showing up strongly enough.
  The optimal setting depends on your finetune and prompt

  Range: `0` to `2`
</ParamField>

### Output Schema

<ParamField body="images" type="list<registry__image__fast_sdxl__models__Image>" required>
  The generated image files info.
</ParamField>

<ParamField body="timings" type="Timings" required />

<ParamField body="seed" type="integer" required>
  Seed of the generated Image. It will be the same value of the one passed in the
  input or the randomly generated that was used in case none was passed.
</ParamField>

<ParamField body="has_nsfw_concepts" type="list<boolean>" required>
  Whether the generated images contain NSFW concepts.
</ParamField>

<ParamField body="prompt" type="string" required>
  The prompt used for generating the image.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
  "sync_mode": false,
  "num_images": 1,
  "output_format": "jpeg",
  "safety_tolerance": "2",
  "enhance_prompt": false,
  "image_prompt_strength": 0.1,
  "aspect_ratio": "16:9",
  "raw": false,
  "finetune_id": ""
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "",
      "content_type": "image/jpeg"
    }
  ],
  "prompt": ""
}
```

## Limitations

* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `image_prompt_strength` range: 0 to 1
* `finetune_strength` range: 0 to 2


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-schnell.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Schnell API

> API reference for Flux Schnell. FLUX.1 [schnell] is a 12 billion parameter flow transformer that generates high-quality images from text in 1 to 4 steps, suitable for personal and commercial use.

<Tabs>
  <Tab title="Schnell">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/schnell`
    **Endpoint ID:** `fal-ai/flux/schnell`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/schnell/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/schnell", {
        input: {
            prompt: "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/schnell \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture."
      }'
      ```
    </CodeGroup>

    ## Examples

    > portrait | wide angle shot of eyes off to one side of frame, lucid dream-like woman, looking off in distance ::8 style | daydreampunk with glowing skin and eyes, styled in headdress, beautiful, she is dripping in neon lights, very colorful blue, green, purple, bioluminescent, glowing ::8 background ...

    <Frame>
      <img src="https://fal.media/files/tiger/m0K3P3JUR_Brcf7mxk3tl.png" alt="Generated image: portrait | wide angle shot of eyes off to one side of frame, lucid dream-like wo" />
    </Frame>

    > Anime style portrait of a female samurai at a beautiful lake with cherry trees, mountain fuji background, spring, sunset

    <Frame>
      <img src="https://fal.media/files/panda/a7P7ZT9XQWNQJ20NP1P8S.png" alt="Generated image: Anime style portrait of a female samurai at a beautiful lake with cherry trees, " />
    </Frame>

    > A vibrant custom illustration, retro-style, featuring a vintage ice cream cart, by the beach, with palm trees. The text 'Gelato' is displayed in a retro, distressed style, with each letter in a different color, exuding a sense of nostalgia. The design is perfect for a t-shirt print, with an isolated...

    <Frame>
      <img src="https://fal.media/files/lion/aO029csoRCHt4RHWKn0UU.png" alt="Generated image: A vibrant custom illustration, retro-style, featuring a vintage ice cream cart, " />
    </Frame>

    ### Input Schema

    <ParamField body="num_inference_steps" type="integer" default="4">
      The number of inference steps to perform. Default value: `4`

      Range: `1` to `12`
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="3.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `3.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "num_inference_steps": 4,
      "prompt": "Extreme close-up of a single tiger eye, direct frontal view. Detailed iris and pupil. Sharp focus on eye texture and color. Natural lighting to capture authentic eye shine and depth. The word \"FLUX\" is painted over it in big, white brush strokes with visible texture.",
      "image_size": "landscape_4_3",
      "guidance_scale": 3.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Redux">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/schnell/redux`
    **Endpoint ID:** `fal-ai/flux/schnell/redux`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/schnell/redux/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/redux",
          arguments={
              "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/schnell/redux", {
        input: {
            image_url: "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/schnell/redux \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to generate an image from.
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="4">
      The number of inference steps to perform. Default value: `4`

      Range: `1` to `12`
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://fal.media/files/kangaroo/acQvq-Kmo2lajkgvcEHdv.png",
      "num_inference_steps": 4,
      "image_size": "landscape_4_3",
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## FLUX.1 \[schnell] - Ultra-Fast Text-to-Image Generation

Transform your ideas into stunning visuals in seconds with FLUX.1 \[schnell], a powerful 12 billion parameter flow transformer designed for production-ready image generation. Whether you're creating content for commercial projects or personal artwork, FLUX.1 \[schnell] delivers exceptional quality in just 1-4 inference steps with sub-second results.

### Key Capabilities

Create high-fidelity images with remarkable speed and precision. FLUX.1 \[schnell] excels at:

* Professional-grade image generation with precise detail control
* Lightning-fast inference (1-4 steps with sub-second results)
* Commercial-ready outputs with full usage rights
* Consistent style maintenance across multiple generations
* Advanced prompt interpretation for accurate results
* Text-to-image and image-to-image generation capabilities

### Popular Use Cases

**Content Creation**
Generate marketing visuals, social media assets, and blog illustrations at scale. Perfect for agencies and content teams who need consistent, high-quality imagery.

**Product Development**\
Create concept art, UI mockups, and design variations for rapid prototyping. Ideal for designers exploring visual directions.

**E-commerce**
Generate product lifestyle images, seasonal campaigns, and A/B testing visuals to boost conversion rates.

**Entertainment**
Produce game assets, storyboard illustrations, and creative concept art for media projects.

### Getting Started

Getting up and running with FLUX.1 \[schnell] is straightforward. Here's how to begin:

1. Install your preferred SDK:

For JavaScript/TypeScript:

```bash theme={null}
npm install --save @fal-ai/client
```

For Python:

```bash theme={null}
pip install fal-client
```

2. Configure your credentials:

```typescript theme={null}
import { fal } from '@fal-ai/client'

fal.config({
  credentials: 'YOUR_FAL_KEY'
})
```

3. Generate your first image:

```typescript theme={null}
const result = await fal.subscribe('fal-ai/flux/schnell', {
  input: {
    prompt: "A serene mountain landscape at sunset, hyperrealistic style",
    num_inference_steps: 4
  }
})
```

### Technical Specifications

FLUX.1 \[schnell] represents the latest in flow-based architecture:

#### Architecture

* **12B parameter flow transformer** optimized for speed
* **Flow-based distillation** for ultra-fast inference
* **1-4 inference steps** (default: 4 steps)
* **Sub-second response times** for fastest generation
* **Commercial usage rights** included

#### API Parameters

* **prompt**: Text description of desired image
* **image\_size**: Various preset sizes or custom dimensions
* **num\_inference\_steps**: Generation steps (default: 4)
* **num\_images**: Number of images to generate (default: 1)
* **seed**: For reproducible results
* **enable\_safety\_checker**: Content safety filtering (default: true)
* **output\_format**: Image format (default: PNG)

#### Performance

* **Sub-second response times** for rapid generation
* **Fastest AI image generation** among FLUX models
* **Concurrent request handling** capability
* **Enterprise-grade reliability** and uptime

### Best Practices

To achieve optimal results with FLUX.1 \[schnell]:

* Write detailed, specific prompts that describe both content and style
* Use 4 steps (default) for balanced speed/quality, adjust as needed
* Leverage the fastest generation for iterative workflows
* Monitor API usage through the dashboard for optimization
* Take advantage of sub-second generation for real-time applications

### Integration Guide

FLUX.1 \[schnell] integrates seamlessly into existing workflows:

1. Set up authentication using environment variables
2. Initialize the client in your application
3. Implement error handling and retries
4. Add response validation
5. Configure webhook endpoints for async processing

### Advanced Features

Take advantage of FLUX.1 \[schnell]'s advanced capabilities:

#### Speed Optimization

FLUX.1 \[schnell] is specifically optimized for ultra-fast generation, making it ideal for applications requiring rapid iteration and real-time image creation.

#### Image Size Control

Generate images at various dimensions with preset sizes or custom width/height configurations to match your specific requirements.

#### Batch Processing

Create multiple variations efficiently with built-in batching support for rapid prototyping and content generation.

#### Turbo Mode

The "schnell" (German for "fast") variant is the turbo mode of the FLUX.1 family, prioritizing speed while maintaining high image quality.

### Pricing and Usage

Your request will cost \$0.003 per megapixel. Images are billed by rounding up to the nearest megapixel. Our transparent, usage-based pricing scales with your needs:

* **Most cost-effective**: \$0.003 per megapixel
* **Commercial usage rights** included
* **No subscription fees** or minimum commitments
* **Fastest generation** with competitive pricing

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Support and Resources

We're here to help you succeed with FLUX.1 \[schnell]:

* **Documentation**: Comprehensive API references and guides
* **Community**: Active Discord community for peer support
* **Technical Support**: Direct assistance through support tickets
* **Examples**: Growing library of implementation examples
* **Updates**: Regular model improvements and feature additions

Get started today and experience the fastest AI image generation available. Create your API key now and begin transforming your ideas into stunning visuals with FLUX.1 \[schnell].

[Get Started Now](https://fal.ai/login) | [View Documentation](https://docs.fal.ai/) | [Try FLUX Schnell](https://fal.ai/models/fal-ai/flux/schnell)

## Related

* [FLUX.1 \[dev\]](/model-api-reference/image-generation-api/flux.1) — Image Generation
* [FLUX.1 \[dev\] Redux](/model-api-reference/image-generation-api/flux.1-redux) — Image Generation

## Limitations

* `num_inference_steps` range: 1 to 12
* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `acceleration` restricted to: `none`, `regular`, `high`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/flux-srpo.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux Srpo API

> API reference for Flux Srpo. FLUX.1 SRPO [dev] is a 12 billion parameter flow transformer that generates high-quality images from text with incredible aesthetics. It is suitable for personal and comme

<Tabs>
  <Tab title="Srpo">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/srpo`
    **Endpoint ID:** `fal-ai/flux/srpo`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/srpo/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/srpo",
          arguments={
              "prompt": "Mountain guide, sturdy build, wilderness wisdom, alert gaze, technical outdoor gear with rope coils, snow-capped peaks background, crisp mountain lighting, leading pose, wind-swept hair with full beard, weather-worn face with quiet confidence, alpine expert presence"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/srpo", {
        input: {
            prompt: "Mountain guide, sturdy build, wilderness wisdom, alert gaze, technical outdoor gear with rope coils, snow-capped peaks background, crisp mountain lighting, leading pose, wind-swept hair with full beard, weather-worn face with quiet confidence, alpine expert presence"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/srpo \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Mountain guide, sturdy build, wilderness wisdom, alert gaze, technical outdoor gear with rope coils, snow-capped peaks background, crisp mountain lighting, leading pose, wind-swept hair with full beard, weather-worn face with quiet confidence, alpine expert presence"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="4.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `4.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated images.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Mountain guide, sturdy build, wilderness wisdom, alert gaze, technical outdoor gear with rope coils, snow-capped peaks background, crisp mountain lighting, leading pose, wind-swept hair with full beard, weather-worn face with quiet confidence, alpine expert presence",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "guidance_scale": 4.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/jpeg",
          "height": 768,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/flux-srpo-output.jpeg",
          "width": 1024
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Image To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/flux/srpo/image-to-image`
    **Endpoint ID:** `fal-ai/flux/srpo/image-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/flux/srpo/image-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/srpo/image-to-image",
          arguments={
              "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
              "prompt": "A cat dressed as a wizard with a background of a mystic forest."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/flux/srpo/image-to-image", {
        input: {
            image_url: "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
            prompt: "A cat dressed as a wizard with a background of a mystic forest."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/flux/srpo/image-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
        "prompt": "A cat dressed as a wizard with a background of a mystic forest."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to generate an image from.
    </ParamField>

    <ParamField body="strength" type="float" default="0.95">
      The strength of the initial image. Higher strength values are better for this model. Default value: `0.95`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="40">
      The number of inference steps to perform. Default value: `40`

      Range: `10` to `50`
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="4.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt when looking for a related image to show you. Default value: `4.5`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="none">
      The speed of the generation. The higher the speed, the faster the generation. Default value: `"none"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<Image>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required />

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the
      input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://fal.media/files/koala/Chls9L2ZnvuipUTEwlnJC.png",
      "strength": 0.95,
      "num_inference_steps": 40,
      "prompt": "A cat dressed as a wizard with a background of a mystic forest.",
      "guidance_scale": 4.5,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "jpeg",
      "acceleration": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "",
          "content_type": "image/jpeg"
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [FLUX.1 SRPO \[dev\]](/model-api-reference/image-generation-api/flux.1-srpo) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_inference_steps` range: 1 to 50
* `guidance_scale` range: 1 to 20
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `acceleration` restricted to: `none`, `regular`, `high`
* Content moderation via safety checker
* `strength` range: 0.01 to 1
* `num_inference_steps` range: 10 to 50


# https://fal.ai/docs/model-api-reference/image-generation-api/gemini-3-pro-image-preview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Gemini 3 Pro Image Preview API

> API reference for Gemini 3 Pro Image Preview. Gemini 3 Pro Image (a.k.a Nano Banana Pro) is Google's state-of-the-art high-fidelity image generation and editing model

<Tabs>
  <Tab title="Gemini 3 Pro Image Preview">
    **Endpoint:** `POST https://fal.run/fal-ai/gemini-3-pro-image-preview`
    **Endpoint ID:** `fal-ai/gemini-3-pro-image-preview`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/gemini-3-pro-image-preview/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/gemini-3-pro-image-preview",
          arguments={
              "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/gemini-3-pro-image-preview", {
        input: {
            prompt: "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/gemini-3-pro-image-preview \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it'\''s mouth, and it'\''s paws paddling underwater."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt to generate an image from.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="1:1">
      The aspect ratio of the generated image. Default value: `1:1`

      Possible values: `auto`, `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1K">
      The resolution of the image to generate. Default value: `"1K"`

      Possible values: `1K`, `2K`, `4K`
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="false">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate.
    </ParamField>

    <ParamField body="enable_web_search" type="boolean" default="false">
      Enable web search for the image generation task. This will allow the model to use the latest information from the web to generate the image.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater.",
      "num_images": 1,
      "aspect_ratio": "1:1",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "resolution": "1K",
      "limit_generations": false,
      "enable_web_search": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-pro-t2i-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-pro-t2i-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/gemini-3-pro-image-preview/edit`
    **Endpoint ID:** `fal-ai/gemini-3-pro-image-preview/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/gemini-3-pro-image-preview/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/gemini-3-pro-image-preview/edit",
          arguments={
              "prompt": "make a photo of the man driving the car down the california coastline",
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/gemini-3-pro-image-preview/edit", {
        input: {
            prompt: "make a photo of the man driving the car down the california coastline",
            image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/gemini-3-pro-image-preview/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "make a photo of the man driving the car down the california coastline",
        "image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt for image editing.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="auto">
      The aspect ratio of the generated image. Default value: `auto`

      Possible values: `auto`, `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      The URLs of the images to use for image-to-image generation or image editing.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1K">
      The resolution of the image to generate. Default value: `"1K"`

      Possible values: `1K`, `2K`, `4K`
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="false">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate.
    </ParamField>

    <ParamField body="enable_web_search" type="boolean" default="false">
      Enable web search for the image generation task. This will allow the model to use the latest information from the web to generate the image.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The edited images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "make a photo of the man driving the car down the california coastline",
      "num_images": 1,
      "aspect_ratio": "auto",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
      ],
      "resolution": "1K",
      "limit_generations": false,
      "enable_web_search": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-pro-edit-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-pro-edit-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>
</Tabs>

Google's Nano Banana Pro (2) Preview delivers state-of-the-art image generation at \$0.15 per image, trading cost efficiency for advanced reasoning capabilities and prompt understanding. Built on Gemini 3 Pro's multimodal architecture, it handles complex natural language instructions that would trip up traditional diffusion models.

**Use Cases:** Complex Scene Composition | Typography-Heavy Designs | Natural Language-Driven Editing

***

## Performance

Nano Banana Pro prioritizes semantic understanding over raw speed, making it ideal for projects where prompt accuracy matters more than generation volume.

| Metric                     | Result            | Context                                                |
| :------------------------- | :---------------- | :----------------------------------------------------- |
| **Resolution Range**       | Up to 4K (4096px) | 4K outputs charged at 2x standard rate                 |
| **Cost per Image**         | \$0.15            | 6-7 generations per \$1.00 on fal                      |
| **Batch Generation**       | 1-4 images        | Per request via `num_images` parameter                 |
| **Web Search Integration** | Optional          | Enable via `enable_web_search` for current information |

***

## Advanced Prompt Understanding Through Gemini 3 Architecture

Gemini 3 Pro Image leverages Google's latest foundation model to interpret complex, conversational prompts rather than requiring carefully crafted keyword strings.

**What this means for you:**

* **Natural Language Processing:** Describe scenes conversationally ("meticulously placed camera on the water line, dividing the image in half") instead of keyword stuffing

* **Typography Excellence:** Tagged for realism and typography, making it particularly strong for text-heavy designs where letter accuracy matters

* **Flexible Output Control:** Generate up to 4 images per request with selectable aspect ratios (21:9 to 9:16) and formats (JPEG, PNG, WebP)

* **Resolution Scaling:** Choose 1K, 2K, or 4K output based on your quality-versus-cost tradeoff, with transparent 2x pricing for 4K

***

## Technical Specifications

| Spec                   | Details                                         |
| :--------------------- | :---------------------------------------------- |
| **Architecture**       | Gemini 3 Pro Image                              |
| **Input Formats**      | Text prompts with optional web search grounding |
| **Output Formats**     | JPEG, PNG, WebP                                 |
| **Resolution Options** | 1K, 2K, 4K (4K at 2x cost)                      |
| **License**            | Commercial use via partnership                  |

[API Documentation](https://fal.ai/models/fal-ai/gemini-3-pro-image-preview/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

**[Gemini 2.5 Flash Image](https://fal.ai/models/fal-ai/gemini-25-flash-image)** – Nano Banana Pro trades speed and cost efficiency for advanced reasoning and complex instruction following at 4x the cost ($0.15 vs $0.039). Gemini 2.5 Flash Image remains ideal for high-volume workflows where rapid iteration matters more than nuanced prompt interpretation.

\*\*[AuraFlow](https://fal.ai/models/fal-ai/aura-flow) ($0.012)** – Nano Banana Pro prioritizes semantic understanding and typography accuracy at 12.5x the cost ($0.15 vs \$0.012). AuraFlow offers maximum cost efficiency for straightforward text-to-image generation where natural language complexity isn't critical.

## Related

* [Gemini 3 Pro Image Preview](/model-api-reference/image-generation-api/gemini-3-pro-image-preview) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `resolution` restricted to: `1K`, `2K`, `4K`


# https://fal.ai/docs/model-api-reference/image-generation-api/gpt-image-1.5.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Gpt Image 1.5 API

> API reference for Gpt Image 1.5. GPT Image 1.5 generates high-fidelity images with strong prompt adherence, preserving composition, lighting, and fine-grained detail.

<Tabs>
  <Tab title="Gpt Image 1.5">
    **Endpoint:** `POST https://fal.run/fal-ai/gpt-image-1.5`
    **Endpoint ID:** `fal-ai/gpt-image-1.5`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/gpt-image-1.5/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/gpt-image-1.5",
          arguments={
              "prompt": "create a realistic image taken with iphone at these coordinates 41°43′32″N 49°56′49″W 15 April 1912"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/gpt-image-1.5", {
        input: {
            prompt: "create a realistic image taken with iphone at these coordinates 41°43′32″N 49°56′49″W 15 April 1912"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/gpt-image-1.5 \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "create a realistic image taken with iphone at these coordinates 41°43′32″N 49°56′49″W 15 April 1912"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt for image generation
    </ParamField>

    <ParamField body="image_size" type="ImageSizeEnum" default="1024x1024">
      Aspect ratio for the generated image Default value: `"1024x1024"`

      Possible values: `1024x1024`, `1536x1024`, `1024x1536`
    </ParamField>

    <ParamField body="background" type="BackgroundEnum" default="auto">
      Background for the generated image Default value: `"auto"`

      Possible values: `auto`, `transparent`, `opaque`
    </ParamField>

    <ParamField body="quality" type="QualityEnum" default="high">
      Quality for the generated image Default value: `"high"`

      Possible values: `low`, `medium`, `high`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      Output format for the images Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "create a realistic image taken with iphone at these coordinates 41°43′32″N 49°56′49″W 15 April 1912",
      "image_size": "1024x1024",
      "background": "auto",
      "quality": "high",
      "num_images": 1,
      "output_format": "png",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "EnWrO3XWjPE0nxBDpaQrj.png",
          "height": 1024,
          "url": "https://v3b.fal.media/files/b/0a869129/EnWrO3XWjPE0nxBDpaQrj.png",
          "width": 1024
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/gpt-image-1.5/edit`
    **Endpoint ID:** `fal-ai/gpt-image-1.5/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/gpt-image-1.5/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/gpt-image-1.5/edit",
          arguments={
              "prompt": "Same workers, same beam, same lunch boxes - but they're all on their phones now. One is taking a selfie. One is on a call looking annoyed. Same danger, new priorities. A hard hat has AirPods.",
              "image_urls": [
                  "https://v3b.fal.media/files/b/0a8691af/9Se_1_VX1wzTjjTOpWbs9_bb39c2eb-1a41-4749-b1d0-cf134abc8bbf.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/gpt-image-1.5/edit", {
        input: {
            prompt: "Same workers, same beam, same lunch boxes - but they're all on their phones now. One is taking a selfie. One is on a call looking annoyed. Same danger, new priorities. A hard hat has AirPods.",
            image_urls: [
              "https://v3b.fal.media/files/b/0a8691af/9Se_1_VX1wzTjjTOpWbs9_bb39c2eb-1a41-4749-b1d0-cf134abc8bbf.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/gpt-image-1.5/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Same workers, same beam, same lunch boxes - but they'\''re all on their phones now. One is taking a selfie. One is on a call looking annoyed. Same danger, new priorities. A hard hat has AirPods.",
        "image_urls": [
          "https://v3b.fal.media/files/b/0a8691af/9Se_1_VX1wzTjjTOpWbs9_bb39c2eb-1a41-4749-b1d0-cf134abc8bbf.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt for image generation
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      The URLs of the images to use as a reference for the generation.
    </ParamField>

    <ParamField body="image_size" type="ImageSizeEnum" default="auto">
      Aspect ratio for the generated image Default value: `"auto"`

      Possible values: `auto`, `1024x1024`, `1536x1024`, `1024x1536`
    </ParamField>

    <ParamField body="background" type="BackgroundEnum" default="auto">
      Background for the generated image Default value: `"auto"`

      Possible values: `auto`, `transparent`, `opaque`
    </ParamField>

    <ParamField body="quality" type="QualityEnum" default="high">
      Quality for the generated image Default value: `"high"`

      Possible values: `low`, `medium`, `high`
    </ParamField>

    <ParamField body="input_fidelity" type="InputFidelityEnum" default="high">
      Input fidelity for the generated image Default value: `"high"`

      Possible values: `low`, `high`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      Output format for the images Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="mask_image_url" type="string">
      The URL of the mask image to use for the generation. This indicates what part of the image to edit.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Same workers, same beam, same lunch boxes - but they're all on their phones now. One is taking a selfie. One is on a call looking annoyed. Same danger, new priorities. A hard hat has AirPods.",
      "image_urls": [
        "https://v3b.fal.media/files/b/0a8691af/9Se_1_VX1wzTjjTOpWbs9_bb39c2eb-1a41-4749-b1d0-cf134abc8bbf.png"
      ],
      "image_size": "auto",
      "background": "auto",
      "quality": "high",
      "input_fidelity": "high",
      "num_images": 1,
      "output_format": "png",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "yUt7tifLSbg1WzWWgfj2o.png",
          "height": 1024,
          "url": "https://v3b.fal.media/files/b/0a8691b0/yUt7tifLSbg1WzWWgfj2o.png",
          "width": 1024
        }
      ]
    }
    ```
  </Tab>
</Tabs>

## Related

* [GPT-Image 1.5](/model-api-reference/image-generation-api/gpt-image-1.5) — Image Generation

## Limitations

* `image_size` restricted to: `1024x1024`, `1536x1024`, `1024x1536`
* `background` restricted to: `auto`, `transparent`, `opaque`
* `quality` restricted to: `low`, `medium`, `high`
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `image_size` restricted to: `auto`, `1024x1024`, `1536x1024`, `1024x1536`
* `input_fidelity` restricted to: `low`, `high`


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-character.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram Character API

> API reference for Ideogram Character. Generate consistent character appearances across multiple images. Maintain facial features, proportions, and distinctive traits for cohesive storytelling and bran

<Tabs>
  <Tab title="Character">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/character`
    **Endpoint ID:** `fal-ai/ideogram/character`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/character/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/character",
          arguments={
              "prompt": "Place the woman leisurely enjoying a cup of espresso while relaxing at a sunlit café table in Siena, Italy. The café setting showcases vintage wooden furniture with peeling white paint, aged brick flooring, and sun-bleached stone walls decorated with trailing ivy and vibrant potted geraniums that capture Siena's medieval character. Golden late-morning light streams through overhead, creating soft shadows that highlight the weathered architectural details. The composition appears slightly off-center, conveying the unguarded tranquility and personal intimacy of a peaceful moment savoring the Tuscan morning ambiance.",
              "reference_image_urls": [
                  "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/character", {
        input: {
            prompt: "Place the woman leisurely enjoying a cup of espresso while relaxing at a sunlit café table in Siena, Italy. The café setting showcases vintage wooden furniture with peeling white paint, aged brick flooring, and sun-bleached stone walls decorated with trailing ivy and vibrant potted geraniums that capture Siena's medieval character. Golden late-morning light streams through overhead, creating soft shadows that highlight the weathered architectural details. The composition appears slightly off-center, conveying the unguarded tranquility and personal intimacy of a peaceful moment savoring the Tuscan morning ambiance.",
            reference_image_urls: [
              "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/character \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Place the woman leisurely enjoying a cup of espresso while relaxing at a sunlit café table in Siena, Italy. The café setting showcases vintage wooden furniture with peeling white paint, aged brick flooring, and sun-bleached stone walls decorated with trailing ivy and vibrant potted geraniums that capture Siena'\''s medieval character. Golden late-morning light streams through overhead, creating soft shadows that highlight the weathered architectural details. The composition appears slightly off-center, conveying the unguarded tranquility and personal intimacy of a peaceful moment savoring the Tuscan morning ambiance.",
        "reference_image_urls": [
          "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="style" type="StyleEnum" default="AUTO">
      The style type to generate with. Cannot be used with style\_codes. Default value: `"AUTO"`

      Possible values: `AUTO`, `REALISTIC`, `FICTION`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to fill the masked part of the image.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="square_hd">
      The resolution of the generated image Default value: `square_hd`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      Description of what to exclude from an image. Descriptions in the prompt take precedence to descriptions in the negative prompt. Default value: `""`
    </ParamField>

    <ParamField body="reference_image_urls" type="list<string>" required>
      A set of images to use as character references. Currently only 1 image is supported, rest will be ignored. (maximum total size 10MB across all character references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="reference_mask_urls" type="list<string>">
      A set of masks to apply to the character references. Currently only 1 mask is supported, rest will be ignored. (maximum total size 10MB across all character references). The masks should be in JPEG, PNG or WebP format
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "style": "AUTO",
      "expand_prompt": true,
      "num_images": 1,
      "sync_mode": false,
      "prompt": "Place the woman leisurely enjoying a cup of espresso while relaxing at a sunlit café table in Siena, Italy. The café setting showcases vintage wooden furniture with peeling white paint, aged brick flooring, and sun-bleached stone walls decorated with trailing ivy and vibrant potted geraniums that capture Siena's medieval character. Golden late-morning light streams through overhead, creating soft shadows that highlight the weathered architectural details. The composition appears slightly off-center, conveying the unguarded tranquility and personal intimacy of a peaceful moment savoring the Tuscan morning ambiance.",
      "image_size": "square_hd",
      "negative_prompt": "",
      "reference_image_urls": [
        "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/monkey/NC_1eo9ecE9fARcxviJ2R_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/character/edit`
    **Endpoint ID:** `fal-ai/ideogram/character/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/character/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/character/edit",
          arguments={
              "prompt": "woman holding bag",
              "image_url": "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
              "mask_url": "https://v3.fal.media/files/panda/jVDAgSkpsZFDP080ceSZJ_woman_face_mask.png",
              "reference_image_urls": [
                  "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/character/edit", {
        input: {
            prompt: "woman holding bag",
            image_url: "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
            mask_url: "https://v3.fal.media/files/panda/jVDAgSkpsZFDP080ceSZJ_woman_face_mask.png",
            reference_image_urls: [
              "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/character/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "woman holding bag",
        "image_url": "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
        "mask_url": "https://v3.fal.media/files/panda/jVDAgSkpsZFDP080ceSZJ_woman_face_mask.png",
        "reference_image_urls": [
          "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to fill the masked part of the image.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to generate an image from. MUST have the exact same dimensions (width and height) as the mask image.
    </ParamField>

    <ParamField body="mask_url" type="string" required>
      The mask URL to inpaint the image. MUST have the exact same dimensions (width and height) as the input image.
    </ParamField>

    <ParamField body="reference_image_urls" type="list<string>" required>
      A set of images to use as character references. Currently only 1 image is supported, rest will be ignored. (maximum total size 10MB across all character references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="reference_mask_urls" type="list<string>">
      A set of masks to apply to the character references. Currently only 1 mask is supported, rest will be ignored. (maximum total size 10MB across all character references). The masks should be in JPEG, PNG or WebP format
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "expand_prompt": true,
      "num_images": 1,
      "sync_mode": false,
      "prompt": "woman holding bag",
      "image_url": "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
      "mask_url": "https://v3.fal.media/files/panda/jVDAgSkpsZFDP080ceSZJ_woman_face_mask.png",
      "reference_image_urls": [
        "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/zebra/JJR2zayRdL3Pg7kr9cFyk_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Remix">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/character/remix`
    **Endpoint ID:** `fal-ai/ideogram/character/remix`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/character/remix/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/character/remix",
          arguments={
              "prompt": "A glamorous portrait photograph of a woman in an elegant ballroom setting. The subject wears a champagne-colored ball gown with a fitted bodice, long sleeves, and a full skirt adorned with delicate lace appliques. The dress features a crystal-embellished hair accessory and pearl drop earrings. The grand staircase has ornate gold railings and leads to an elaborate crystal chandelier hanging from an arched ceiling. The walls are decorated with classical paintings featuring floral motifs. The lighting is warm and dramatic, creating a soft glow throughout the space. The composition is shot in a formal portrait style with the subject positioned on the lower landing of the staircase, looking over her shoulder at the camera.",
              "image_url": "https://v3.fal.media/files/panda/mcxydS-_4ZjfBWFtgoo2z_XHLsl7khq6dC6Qp3cIdJl08rG0I.avif",
              "reference_image_urls": [
                  "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/character/remix", {
        input: {
            prompt: "A glamorous portrait photograph of a woman in an elegant ballroom setting. The subject wears a champagne-colored ball gown with a fitted bodice, long sleeves, and a full skirt adorned with delicate lace appliques. The dress features a crystal-embellished hair accessory and pearl drop earrings. The grand staircase has ornate gold railings and leads to an elaborate crystal chandelier hanging from an arched ceiling. The walls are decorated with classical paintings featuring floral motifs. The lighting is warm and dramatic, creating a soft glow throughout the space. The composition is shot in a formal portrait style with the subject positioned on the lower landing of the staircase, looking over her shoulder at the camera.",
            image_url: "https://v3.fal.media/files/panda/mcxydS-_4ZjfBWFtgoo2z_XHLsl7khq6dC6Qp3cIdJl08rG0I.avif",
            reference_image_urls: [
              "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/character/remix \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A glamorous portrait photograph of a woman in an elegant ballroom setting. The subject wears a champagne-colored ball gown with a fitted bodice, long sleeves, and a full skirt adorned with delicate lace appliques. The dress features a crystal-embellished hair accessory and pearl drop earrings. The grand staircase has ornate gold railings and leads to an elaborate crystal chandelier hanging from an arched ceiling. The walls are decorated with classical paintings featuring floral motifs. The lighting is warm and dramatic, creating a soft glow throughout the space. The composition is shot in a formal portrait style with the subject positioned on the lower landing of the staircase, looking over her shoulder at the camera.",
        "image_url": "https://v3.fal.media/files/panda/mcxydS-_4ZjfBWFtgoo2z_XHLsl7khq6dC6Qp3cIdJl08rG0I.avif",
        "reference_image_urls": [
          "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="style" type="StyleEnum" default="AUTO">
      The style type to generate with. Cannot be used with style\_codes. Default value: `"AUTO"`

      Possible values: `AUTO`, `REALISTIC`, `FICTION`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to remix the image with
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to remix
    </ParamField>

    <ParamField body="strength" type="float" default="0.8">
      Strength of the input image in the remix Default value: `0.8`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="square_hd">
      The resolution of the generated image Default value: `square_hd`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      Description of what to exclude from an image. Descriptions in the prompt take precedence to descriptions in the negative prompt. Default value: `""`
    </ParamField>

    <ParamField body="reference_image_urls" type="list<string>" required>
      A set of images to use as character references. Currently only 1 image is supported, rest will be ignored. (maximum total size 10MB across all character references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="reference_mask_urls" type="list<string>">
      A set of masks to apply to the character references. Currently only 1 mask is supported, rest will be ignored. (maximum total size 10MB across all character references). The masks should be in JPEG, PNG or WebP format
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "style": "AUTO",
      "expand_prompt": true,
      "num_images": 1,
      "sync_mode": false,
      "prompt": "A glamorous portrait photograph of a woman in an elegant ballroom setting. The subject wears a champagne-colored ball gown with a fitted bodice, long sleeves, and a full skirt adorned with delicate lace appliques. The dress features a crystal-embellished hair accessory and pearl drop earrings. The grand staircase has ornate gold railings and leads to an elaborate crystal chandelier hanging from an arched ceiling. The walls are decorated with classical paintings featuring floral motifs. The lighting is warm and dramatic, creating a soft glow throughout the space. The composition is shot in a formal portrait style with the subject positioned on the lower landing of the staircase, looking over her shoulder at the camera.",
      "image_url": "https://v3.fal.media/files/panda/mcxydS-_4ZjfBWFtgoo2z_XHLsl7khq6dC6Qp3cIdJl08rG0I.avif",
      "strength": 0.8,
      "image_size": "square_hd",
      "negative_prompt": "",
      "reference_image_urls": [
        "https://v3.fal.media/files/kangaroo/0rinwnj_Kn9Fsu2dK-aKm_image.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/zebra/4F1SvlaPbkZt-Mle4CTH9_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>
</Tabs>

## Related

* [Ideogram V3 Character Edit](/model-api-reference/image-generation-api/ideogram-v3-character-edit) — Image Generation
* [Ideogram V3 Character Remix](/model-api-reference/image-generation-api/ideogram-v3-character-remix) — Image Generation
* [Ideogram V3 Character](/model-api-reference/image-generation-api/ideogram-v3-character) — Image Generation

## Limitations

* `rendering_speed` restricted to: `TURBO`, `BALANCED`, `QUALITY`
* `style` restricted to: `AUTO`, `REALISTIC`, `FICTION`
* `num_images` range: 1 to 8
* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `strength` range: 0.01 to 1


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-upscale.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram Upscale API

> API reference for Ideogram Upscale. Ideogram Upscale enhances the resolution of the reference image by up to 2X and might enhance the reference image too. Optionally refine outputs with a prompt for g

**Endpoint:** `POST https://fal.run/fal-ai/ideogram/upscale`
**Endpoint ID:** `fal-ai/ideogram/upscale`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/upscale/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/ideogram/upscale",
      arguments={
          "image_url": "https://fal.media/files/monkey/e6RtJf_ue0vyWzeiEmTby.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/ideogram/upscale", {
    input: {
        image_url: "https://fal.media/files/monkey/e6RtJf_ue0vyWzeiEmTby.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/ideogram/upscale \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://fal.media/files/monkey/e6RtJf_ue0vyWzeiEmTby.png"
  }'
  ```
</CodeGroup>

## Capabilities

* Image input
* Text prompt input
* Reproducible generation (seed)
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="image_url" type="string" required>
  The image URL to upscale
</ParamField>

<ParamField body="prompt" type="string" default="">
  The prompt to upscale the image with Default value: `""`
</ParamField>

<ParamField body="resemblance" type="integer" default="50">
  The resemblance of the upscaled image to the original image Default value: `50`

  Range: `1` to `100`
</ParamField>

<ParamField body="detail" type="integer" default="50">
  The detail of the upscaled image Default value: `50`

  Range: `1` to `100`
</ParamField>

<ParamField body="expand_prompt" type="boolean" default="false">
  Whether to expand the prompt with MagicPrompt functionality.
</ParamField>

<ParamField body="seed" type="integer">
  Seed for the random number generator
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<File>" required />

<ParamField body="seed" type="integer" required>
  Seed used for the random number generator
</ParamField>

## Input Example

```json theme={null}
{
  "image_url": "https://fal.media/files/monkey/e6RtJf_ue0vyWzeiEmTby.png",
  "prompt": "",
  "resemblance": 50,
  "detail": 50,
  "expand_prompt": false,
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "content_type": "image/png",
      "file_name": "image.png",
      "file_size": 6548418,
      "url": "https://fal.media/files/lion/DxTSV6683MLl4VPAVUHR3_image.png"
    }
  ],
  "seed": 123456
}
```

## Limitations

* `resemblance` range: 1 to 100
* `detail` range: 1 to 100


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v2.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V2 API

> API reference for Ideogram V2. Generate high-quality images, posters, and logos with Ideogram V2. Features exceptional typography handling and realistic outputs optimized for commercial and creative u

**Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2`
**Endpoint ID:** `fal-ai/ideogram/v2`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/ideogram/v2",
      arguments={
          "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/ideogram/v2", {
    input: {
        prompt: "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/ideogram/v2 \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
  }'
  ```
</CodeGroup>

## Examples

> A playful cat is sitting on the right side of a vibrant beach ball, situated on a sunny, sandy beach. The beach is dotted with sunbathers and colorful umbrellas. Waves gently lap at the shore, and a pristine blue sky is adorned with a few fluffy white clouds. Seagulls soar overhead, adding to the li...

<Frame>
  <img src="https://fal.media/files/kangaroo/pBa0_WFY5AEO6Q_mnbtNB_image.png" alt="Generated image: A playful cat is sitting on the right side of a vibrant beach ball, situated on " />
</Frame>

> A warm, hyper-detailed, low-saturation scene in the style of David Lynch, set against a soft-focus suburban American backdrop with muted colors and soothing tones, evoking a sense of nostalgia. Two characters, a young, ethnically ambiguous woman with sun-kissed, golden-brown skin and a bright, enigm...

<Frame>
  <img src="https://fal.media/files/koala/dSrkX-nFdB_nDA3NaKkMB_image.png" alt="Generated image: A warm, hyper-detailed, low-saturation scene in the style of David Lynch, set ag" />
</Frame>

> A marble-skinned figure with neoclassical features, matte skin, and wrinkles, majestically strides forward on a serene tropical beach with a palm tree and green foliage, amidst a blurred bustling galactic trade hub background.

<Frame>
  <img src="https://fal.media/files/penguin/xYDHqdCkh_azyfWaY8Lsp_image.png" alt="Generated image: A marble-skinned figure with neoclassical features, matte skin, and wrinkles, ma" />
</Frame>

## Related

* [Ideogram V2 Remix](/model-api-reference/image-generation-api/ideogram-v2-remix) — Image Generation
* [Ideogram V2 Edit](/model-api-reference/image-generation-api/ideogram-v2-edit) — Image Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Reproducible generation (seed)
* Synchronous mode
* Negative prompts

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required />

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
  The aspect ratio of the generated image Default value: `"1:1"`

  Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
</ParamField>

<ParamField body="expand_prompt" type="boolean" default="true">
  Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  Seed for the random number generator
</ParamField>

<ParamField body="style" type="StyleEnum" default="auto">
  The style of the generated image Default value: `"auto"`

  Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="negative_prompt" type="string" default="">
  A negative prompt to avoid in the generated image Default value: `""`
</ParamField>

### Output Schema

<ParamField body="images" type="list<File>" required />

<ParamField body="seed" type="integer" required>
  Seed used for the random number generator
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\"",
  "aspect_ratio": "1:1",
  "expand_prompt": true,
  "style": "auto",
  "sync_mode": false,
  "negative_prompt": ""
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
    }
  ],
  "seed": 123456
}
```

## Limitations

* `style` restricted to: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v2-edit.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V2 Edit API

> API reference for Ideogram V2 Edit. Transform existing images with Ideogram V2's editing capabilities. Modify, adjust, and refine images while maintaining high fidelity and realistic outputs with prec

**Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2/edit`
**Endpoint ID:** `fal-ai/ideogram/v2/edit`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2/edit/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/ideogram/v2/edit",
      arguments={
          "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
          "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
          "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/ideogram/v2/edit", {
    input: {
        prompt: "A knight in shining armour holding a greatshield with \"FAL\" on it",
        image_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
        mask_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/ideogram/v2/edit \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
    "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
    "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
  }'
  ```
</CodeGroup>

## Related

* [Ideogram V2](/model-api-reference/image-generation-api/ideogram-v2) — Image Generation
* [Ideogram V2 Remix](/model-api-reference/image-generation-api/ideogram-v2-remix) — Image Generation

## Capabilities

* Text prompt input
* Image input
* Inpainting (mask support)
* Reproducible generation (seed)
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to fill the masked part of the image.
</ParamField>

<ParamField body="image_url" type="string" required>
  The image URL to generate an image from. Needs to match the dimensions of the mask.
</ParamField>

<ParamField body="mask_url" type="string" required>
  The mask URL to inpaint the image. Needs to match the dimensions of the input image.
</ParamField>

<ParamField body="seed" type="integer">
  Seed for the random number generator
</ParamField>

<ParamField body="style" type="StyleEnum" default="auto">
  The style of the generated image Default value: `"auto"`

  Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
</ParamField>

<ParamField body="expand_prompt" type="boolean" default="true">
  Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<File>" required />

<ParamField body="seed" type="integer" required>
  Seed used for the random number generator
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
  "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
  "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg",
  "style": "auto",
  "expand_prompt": true,
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
    }
  ],
  "seed": 123456
}
```

## Limitations

* `style` restricted to: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v2-remix.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V2 Remix API

> API reference for Ideogram V2 Remix. Reimagine existing images with Ideogram V2's remix feature. Create variations and adaptations while preserving core elements and adding new creative directions thr

**Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2/remix`
**Endpoint ID:** `fal-ai/ideogram/v2/remix`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2/remix/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/ideogram/v2/remix",
      arguments={
          "prompt": "An ice field in north atlantic",
          "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/ideogram/v2/remix", {
    input: {
        prompt: "An ice field in north atlantic",
        image_url: "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/ideogram/v2/remix \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "An ice field in north atlantic",
    "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
  }'
  ```
</CodeGroup>

## Related

* [Ideogram V2](/model-api-reference/image-generation-api/ideogram-v2) — Image Generation
* [Ideogram V2 Edit](/model-api-reference/image-generation-api/ideogram-v2-edit) — Image Generation

## Capabilities

* Text prompt input
* Image input
* Aspect ratio control
* Strength control
* Reproducible generation (seed)
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to remix the image with
</ParamField>

<ParamField body="image_url" type="string" required>
  The image URL to remix
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
  The aspect ratio of the generated image Default value: `"1:1"`

  Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
</ParamField>

<ParamField body="strength" type="float" default="0.8">
  Strength of the input image in the remix Default value: `0.8`

  Range: `0.01` to `1`
</ParamField>

<ParamField body="expand_prompt" type="boolean" default="true">
  Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  Seed for the random number generator
</ParamField>

<ParamField body="style" type="StyleEnum" default="auto">
  The style of the generated image Default value: `"auto"`

  Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<File>" required />

<ParamField body="seed" type="integer" required>
  Seed used for the random number generator
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "An ice field in north atlantic",
  "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png",
  "aspect_ratio": "1:1",
  "strength": 0.8,
  "expand_prompt": true,
  "style": "auto",
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
    }
  ],
  "seed": 123456
}
```

## Limitations

* `strength` range: 0.01 to 1
* `style` restricted to: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v2-turbo.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V2 Turbo API

> API reference for Ideogram V2 Turbo. Accelerated image generation with Ideogram V2 Turbo. Create high-quality visuals, posters, and logos with enhanced speed while maintaining Ideogram's signature qua

<Tabs>
  <Tab title="Turbo">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2/turbo`
    **Endpoint ID:** `fal-ai/ideogram/v2/turbo`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2/turbo/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v2/turbo",
          arguments={
              "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v2/turbo", {
        input: {
            prompt: "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v2/turbo \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the generated image Default value: `"1:1"`

      Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="style" type="StyleEnum" default="auto">
      The style of the generated image Default value: `"auto"`

      Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      A negative prompt to avoid in the generated image Default value: `""`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\"",
      "aspect_ratio": "1:1",
      "expand_prompt": true,
      "style": "auto",
      "sync_mode": false,
      "negative_prompt": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Remix">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2/turbo/remix`
    **Endpoint ID:** `fal-ai/ideogram/v2/turbo/remix`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2/turbo/remix/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v2/turbo/remix",
          arguments={
              "prompt": "An ice field in north atlantic",
              "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v2/turbo/remix", {
        input: {
            prompt: "An ice field in north atlantic",
            image_url: "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v2/turbo/remix \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An ice field in north atlantic",
        "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to remix the image with
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to remix
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the generated image Default value: `"1:1"`

      Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
    </ParamField>

    <ParamField body="strength" type="float" default="0.8">
      Strength of the input image in the remix Default value: `0.8`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="style" type="StyleEnum" default="auto">
      The style of the generated image Default value: `"auto"`

      Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An ice field in north atlantic",
      "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png",
      "aspect_ratio": "1:1",
      "strength": 0.8,
      "expand_prompt": true,
      "style": "auto",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2/turbo/edit`
    **Endpoint ID:** `fal-ai/ideogram/v2/turbo/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2/turbo/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v2/turbo/edit",
          arguments={
              "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
              "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
              "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v2/turbo/edit", {
        input: {
            prompt: "A knight in shining armour holding a greatshield with \"FAL\" on it",
            image_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
            mask_url: "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v2/turbo/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
        "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
        "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to fill the masked part of the image.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to generate an image from. Needs to match the dimensions of the mask.
    </ParamField>

    <ParamField body="mask_url" type="string" required>
      The mask URL to inpaint the image. Needs to match the dimensions of the input image.
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="style" type="StyleEnum" default="auto">
      The style of the generated image Default value: `"auto"`

      Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A knight in shining armour holding a greatshield with \"FAL\" on it",
      "image_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/knight.jpeg",
      "mask_url": "https://storage.googleapis.com/falserverless/flux-lora/example-images/mask_knight.jpeg",
      "style": "auto",
      "expand_prompt": true,
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>
</Tabs>

## Related

* [Ideogram V2 Turbo Remix](/model-api-reference/image-generation-api/ideogram-v2-turbo-remix) — Image Generation
* [Ideogram V2 Turbo Edit](/model-api-reference/image-generation-api/ideogram-v2-turbo-edit) — Image Generation
* [Ideogram V2 Turbo](/model-api-reference/image-generation-api/ideogram-v2-turbo) — Image Generation

## Limitations

* `style` restricted to: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
* `strength` range: 0.01 to 1


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v2a.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V2a API

> API reference for Ideogram V2a. Generate high-quality images, posters, and logos with Ideogram V2A. Features exceptional typography handling and realistic outputs optimized for commercial and creative

**Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2a`
**Endpoint ID:** `fal-ai/ideogram/v2a`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2a/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/ideogram/v2a",
      arguments={
          "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/ideogram/v2a", {
    input: {
        prompt: "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/ideogram/v2a \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
  }'
  ```
</CodeGroup>

## Related

* [Ideogram V2A Turbo](/model-api-reference/image-generation-api/ideogram-v2a-turbo) — Image Generation
* [Ideogram V2A Remix](/model-api-reference/image-generation-api/ideogram-v2a-remix) — Image Generation
* [Ideogram V2A Turbo Remix](/model-api-reference/image-generation-api/ideogram-v2a-turbo-remix) — Image Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Reproducible generation (seed)
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required />

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
  The aspect ratio of the generated image Default value: `"1:1"`

  Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
</ParamField>

<ParamField body="expand_prompt" type="boolean" default="true">
  Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  Seed for the random number generator
</ParamField>

<ParamField body="style" type="StyleEnum" default="auto">
  The style of the generated image Default value: `"auto"`

  Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<File>" required />

<ParamField body="seed" type="integer" required>
  Seed used for the random number generator
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\"",
  "aspect_ratio": "1:1",
  "expand_prompt": true,
  "style": "auto",
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
    }
  ],
  "seed": 123456
}
```

## Limitations

* `style` restricted to: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v2a-remix.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V2a Remix API

> API reference for Ideogram V2a Remix. Create variations of existing images with Ideogram V2A Remix while maintaining creative control through prompt guidance.

**Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2a/remix`
**Endpoint ID:** `fal-ai/ideogram/v2a/remix`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2a/remix/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/ideogram/v2a/remix",
      arguments={
          "prompt": "An ice field in north atlantic",
          "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/ideogram/v2a/remix", {
    input: {
        prompt: "An ice field in north atlantic",
        image_url: "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/ideogram/v2a/remix \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "An ice field in north atlantic",
    "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
  }'
  ```
</CodeGroup>

## Related

* [Ideogram V2A Turbo](/model-api-reference/image-generation-api/ideogram-v2a-turbo) — Image Generation
* [Ideogram V2A](/model-api-reference/image-generation-api/ideogram-v2a) — Image Generation
* [Ideogram V2A Turbo Remix](/model-api-reference/image-generation-api/ideogram-v2a-turbo-remix) — Image Generation

## Capabilities

* Text prompt input
* Image input
* Aspect ratio control
* Strength control
* Reproducible generation (seed)
* Synchronous mode

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to remix the image with
</ParamField>

<ParamField body="image_url" type="string" required>
  The image URL to remix
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
  The aspect ratio of the generated image Default value: `"1:1"`

  Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
</ParamField>

<ParamField body="strength" type="float" default="0.8">
  Strength of the input image in the remix Default value: `0.8`

  Range: `0.01` to `1`
</ParamField>

<ParamField body="expand_prompt" type="boolean" default="true">
  Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  Seed for the random number generator
</ParamField>

<ParamField body="style" type="StyleEnum" default="auto">
  The style of the generated image Default value: `"auto"`

  Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="images" type="list<File>" required />

<ParamField body="seed" type="integer" required>
  Seed used for the random number generator
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "An ice field in north atlantic",
  "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png",
  "aspect_ratio": "1:1",
  "strength": 0.8,
  "expand_prompt": true,
  "style": "auto",
  "sync_mode": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
    }
  ],
  "seed": 123456
}
```

## Limitations

* `strength` range: 0.01 to 1
* `style` restricted to: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v2a-turbo.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V2a Turbo API

> API reference for Ideogram V2a Turbo. Accelerated image generation with Ideogram V2A Turbo. Create high-quality visuals, posters, and logos with enhanced speed while maintaining Ideogram's signature q

<Tabs>
  <Tab title="Turbo">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2a/turbo`
    **Endpoint ID:** `fal-ai/ideogram/v2a/turbo`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2a/turbo/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v2a/turbo",
          arguments={
              "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v2a/turbo", {
        input: {
            prompt: "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v2a/turbo \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the generated image Default value: `"1:1"`

      Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="style" type="StyleEnum" default="auto">
      The style of the generated image Default value: `"auto"`

      Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A comic style illustration of a skeleton sitting on a toilet in a bathroom. The bathroom has a Halloween decoration with a pumpkin jack-o-lantern and bats flying around. There is a text above the skeleton that says \"Just Waiting for Halloween with Ideogram 2.0 at fal.ai\"",
      "aspect_ratio": "1:1",
      "expand_prompt": true,
      "style": "auto",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Remix">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v2a/turbo/remix`
    **Endpoint ID:** `fal-ai/ideogram/v2a/turbo/remix`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v2a/turbo/remix/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v2a/turbo/remix",
          arguments={
              "prompt": "An ice field in north atlantic",
              "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v2a/turbo/remix", {
        input: {
            prompt: "An ice field in north atlantic",
            image_url: "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v2a/turbo/remix \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An ice field in north atlantic",
        "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to remix the image with
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to remix
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the generated image Default value: `"1:1"`

      Possible values: `10:16`, `16:10`, `9:16`, `16:9`, `4:3`, `3:4`, `1:1`, `1:3`, `3:1`, `3:2`, `2:3`
    </ParamField>

    <ParamField body="strength" type="float" default="0.8">
      Strength of the input image in the remix Default value: `0.8`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Whether to expand the prompt with MagicPrompt functionality. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="style" type="StyleEnum" default="auto">
      The style of the generated image Default value: `"auto"`

      Possible values: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An ice field in north atlantic",
      "image_url": "https://fal.media/files/lion/FHOx4y4a0ef7Sgmo-sOUR_image.png",
      "aspect_ratio": "1:1",
      "strength": 0.8,
      "expand_prompt": true,
      "style": "auto",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://fal.media/files/monkey/cNaoxPl0YAWYb-QVBvO9F_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>
</Tabs>

## Related

* [Ideogram V2A](/model-api-reference/image-generation-api/ideogram-v2a) — Image Generation
* [Ideogram V2A Remix](/model-api-reference/image-generation-api/ideogram-v2a-remix) — Image Generation
* [Ideogram V2A Turbo Remix](/model-api-reference/image-generation-api/ideogram-v2a-turbo-remix) — Image Generation
* [Ideogram V2A Turbo](/model-api-reference/image-generation-api/ideogram-v2a-turbo) — Image Generation

## Limitations

* `style` restricted to: `auto`, `general`, `realistic`, `design`, `render_3D`, `anime`
* `strength` range: 0.01 to 1


# https://fal.ai/docs/model-api-reference/image-generation-api/ideogram-v3.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ideogram V3 API

> API reference for Ideogram V3. Generate high-quality images, posters, and logos with Ideogram V3. Features exceptional typography handling and realistic outputs optimized for commercial and creative u

<Tabs>
  <Tab title="V3">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v3`
    **Endpoint ID:** `fal-ai/ideogram/v3`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v3/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v3",
          arguments={
              "prompt": "The Bone Forest stretched across the horizon, its trees fashioned from the ossified remains of ancient leviathans that once swam through the sky. Shamans with antlers growing from their shoulders and eyes that revealed the true nature of any being they beheld conducted rituals to commune with the spirits that still inhabited the calcified grove. In sky writes \"Ideogram V3 in fal.ai\""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v3", {
        input: {
            prompt: "The Bone Forest stretched across the horizon, its trees fashioned from the ossified remains of ancient leviathans that once swam through the sky. Shamans with antlers growing from their shoulders and eyes that revealed the true nature of any being they beheld conducted rituals to commune with the spirits that still inhabited the calcified grove. In sky writes \"Ideogram V3 in fal.ai\""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v3 \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "The Bone Forest stretched across the horizon, its trees fashioned from the ossified remains of ancient leviathans that once swam through the sky. Shamans with antlers growing from their shoulders and eyes that revealed the true nature of any being they beheld conducted rituals to commune with the spirits that still inhabited the calcified grove. In sky writes \"Ideogram V3 in fal.ai\""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="style" type="Enum">
      The style type to generate with. Cannot be used with style\_codes.

      Possible values: `AUTO`, `GENERAL`, `REALISTIC`, `DESIGN`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="style_preset" type="Enum">
      Style preset for generation. The chosen style preset will guide the generation.

      Possible values: `80S_ILLUSTRATION`, `90S_NOSTALGIA`, `ABSTRACT_ORGANIC`, `ANALOG_NOSTALGIA`, `ART_BRUT`, `ART_DECO`, `ART_POSTER`, `AURA`, `AVANT_GARDE`, `BAUHAUS`, `BLUEPRINT`, `BLURRY_MOTION`, `BRIGHT_ART`, `C4D_CARTOON`, `CHILDRENS_BOOK`, `COLLAGE`, `COLORING_BOOK_I`, `COLORING_BOOK_II`, `CUBISM`, `DARK_AURA`, `DOODLE`, `DOUBLE_EXPOSURE`, `DRAMATIC_CINEMA`, `EDITORIAL`, `EMOTIONAL_MINIMAL`, `ETHEREAL_PARTY`, `EXPIRED_FILM`, `FLAT_ART`, `FLAT_VECTOR`, `FOREST_REVERIE`, `GEO_MINIMALIST`, `GLASS_PRISM`, `GOLDEN_HOUR`, `GRAFFITI_I`, `GRAFFITI_II`, `HALFTONE_PRINT`, `HIGH_CONTRAST`, `HIPPIE_ERA`, `ICONIC`, `JAPANDI_FUSION`, `JAZZY`, `LONG_EXPOSURE`, `MAGAZINE_EDITORIAL`, `MINIMAL_ILLUSTRATION`, `MIXED_MEDIA`, `MONOCHROME`, `NIGHTLIFE`, `OIL_PAINTING`, `OLD_CARTOONS`, `PAINT_GESTURE`, `POP_ART`, `RETRO_ETCHING`, `RIVIERA_POP`, `SPOTLIGHT_80S`, `STYLIZED_RED`, `SURREAL_COLLAGE`, `TRAVEL_POSTER`, `VINTAGE_GEO`, `VINTAGE_POSTER`, `WATERCOLOR`, `WEIRD`, `WOODBLOCK_PRINT`
    </ParamField>

    <ParamField body="prompt" type="string" required />

    <ParamField body="image_size" type="ImageSize | Enum" default="square_hd">
      The resolution of the generated image Default value: `square_hd`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      Description of what to exclude from an image. Descriptions in the prompt take precedence to descriptions in the negative prompt. Default value: `""`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "expand_prompt": true,
      "num_images": 1,
      "sync_mode": false,
      "prompt": "The Bone Forest stretched across the horizon, its trees fashioned from the ossified remains of ancient leviathans that once swam through the sky. Shamans with antlers growing from their shoulders and eyes that revealed the true nature of any being they beheld conducted rituals to commune with the spirits that still inhabited the calcified grove. In sky writes \"Ideogram V3 in fal.ai\"",
      "image_size": "square_hd",
      "negative_prompt": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/penguin/lHdRabS80guysb8Zw1kul_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Reframe">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v3/reframe`
    **Endpoint ID:** `fal-ai/ideogram/v3/reframe`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v3/reframe/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v3/reframe",
          arguments={
              "image_url": "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png",
              "image_size": "square_hd"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v3/reframe", {
        input: {
            image_url: "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png",
            image_size: "square_hd"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v3/reframe \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png",
        "image_size": "square_hd"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="style" type="Enum">
      The style type to generate with. Cannot be used with style\_codes.

      Possible values: `AUTO`, `GENERAL`, `REALISTIC`, `DESIGN`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="style_preset" type="Enum">
      Style preset for generation. The chosen style preset will guide the generation.

      Possible values: `80S_ILLUSTRATION`, `90S_NOSTALGIA`, `ABSTRACT_ORGANIC`, `ANALOG_NOSTALGIA`, `ART_BRUT`, `ART_DECO`, `ART_POSTER`, `AURA`, `AVANT_GARDE`, `BAUHAUS`, `BLUEPRINT`, `BLURRY_MOTION`, `BRIGHT_ART`, `C4D_CARTOON`, `CHILDRENS_BOOK`, `COLLAGE`, `COLORING_BOOK_I`, `COLORING_BOOK_II`, `CUBISM`, `DARK_AURA`, `DOODLE`, `DOUBLE_EXPOSURE`, `DRAMATIC_CINEMA`, `EDITORIAL`, `EMOTIONAL_MINIMAL`, `ETHEREAL_PARTY`, `EXPIRED_FILM`, `FLAT_ART`, `FLAT_VECTOR`, `FOREST_REVERIE`, `GEO_MINIMALIST`, `GLASS_PRISM`, `GOLDEN_HOUR`, `GRAFFITI_I`, `GRAFFITI_II`, `HALFTONE_PRINT`, `HIGH_CONTRAST`, `HIPPIE_ERA`, `ICONIC`, `JAPANDI_FUSION`, `JAZZY`, `LONG_EXPOSURE`, `MAGAZINE_EDITORIAL`, `MINIMAL_ILLUSTRATION`, `MIXED_MEDIA`, `MONOCHROME`, `NIGHTLIFE`, `OIL_PAINTING`, `OLD_CARTOONS`, `PAINT_GESTURE`, `POP_ART`, `RETRO_ETCHING`, `RIVIERA_POP`, `SPOTLIGHT_80S`, `STYLIZED_RED`, `SURREAL_COLLAGE`, `TRAVEL_POSTER`, `VINTAGE_GEO`, `VINTAGE_POSTER`, `WATERCOLOR`, `WEIRD`, `WOODBLOCK_PRINT`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to reframe
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" required>
      The resolution for the reframed output image

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "num_images": 1,
      "sync_mode": false,
      "image_url": "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png",
      "image_size": "square_hd"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/zebra/LVW4AhVs3sCxsVKdg3EfT_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Generate Transparent">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v3/generate-transparent`
    **Endpoint ID:** `fal-ai/ideogram/v3/generate-transparent`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v3/generate-transparent/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v3/generate-transparent",
          arguments={
              "prompt": "A logo for Ideogram Coffee."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v3/generate-transparent", {
        input: {
            prompt: "A logo for Ideogram Coffee."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v3/generate-transparent \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A logo for Ideogram Coffee."
      }'
      ```
    </CodeGroup>

    ## Examples

    > A low-poly 3D fox sitting upright, in warm orange and white geometric facets

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a954d91/792FF8-bFC7lEaJ5KQ1n8_image.png" alt="Generated image: A low-poly 3D fox sitting upright, in warm orange and white geometric facets" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the generated image. Default value: `"1:1"`

      Possible values: `1:3`, `3:1`, `1:2`, `2:1`, `9:16`, `16:9`, `10:16`, `16:10`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `1:1`
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `FLASH`, `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      Description of what to exclude from an image. Descriptions in the prompt take precedence to descriptions in the negative prompt. Default value: `""`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A logo for Ideogram Coffee.",
      "aspect_ratio": "1:1",
      "rendering_speed": "BALANCED",
      "expand_prompt": true,
      "negative_prompt": "",
      "num_images": 1,
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/lion/AUfCjtLkLOsdc9zEFrV-5_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v3/edit`
    **Endpoint ID:** `fal-ai/ideogram/v3/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v3/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v3/edit",
          arguments={
              "prompt": "black bag",
              "image_url": "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
              "mask_url": "https://v3.fal.media/files/kangaroo/1dd3zEL5MXQ3Kb4-mRi9d_indir%20(20).png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v3/edit", {
        input: {
            prompt: "black bag",
            image_url: "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
            mask_url: "https://v3.fal.media/files/kangaroo/1dd3zEL5MXQ3Kb4-mRi9d_indir%20(20).png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v3/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "black bag",
        "image_url": "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
        "mask_url": "https://v3.fal.media/files/kangaroo/1dd3zEL5MXQ3Kb4-mRi9d_indir%20(20).png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="style_preset" type="Enum">
      Style preset for generation. The chosen style preset will guide the generation.

      Possible values: `80S_ILLUSTRATION`, `90S_NOSTALGIA`, `ABSTRACT_ORGANIC`, `ANALOG_NOSTALGIA`, `ART_BRUT`, `ART_DECO`, `ART_POSTER`, `AURA`, `AVANT_GARDE`, `BAUHAUS`, `BLUEPRINT`, `BLURRY_MOTION`, `BRIGHT_ART`, `C4D_CARTOON`, `CHILDRENS_BOOK`, `COLLAGE`, `COLORING_BOOK_I`, `COLORING_BOOK_II`, `CUBISM`, `DARK_AURA`, `DOODLE`, `DOUBLE_EXPOSURE`, `DRAMATIC_CINEMA`, `EDITORIAL`, `EMOTIONAL_MINIMAL`, `ETHEREAL_PARTY`, `EXPIRED_FILM`, `FLAT_ART`, `FLAT_VECTOR`, `FOREST_REVERIE`, `GEO_MINIMALIST`, `GLASS_PRISM`, `GOLDEN_HOUR`, `GRAFFITI_I`, `GRAFFITI_II`, `HALFTONE_PRINT`, `HIGH_CONTRAST`, `HIPPIE_ERA`, `ICONIC`, `JAPANDI_FUSION`, `JAZZY`, `LONG_EXPOSURE`, `MAGAZINE_EDITORIAL`, `MINIMAL_ILLUSTRATION`, `MIXED_MEDIA`, `MONOCHROME`, `NIGHTLIFE`, `OIL_PAINTING`, `OLD_CARTOONS`, `PAINT_GESTURE`, `POP_ART`, `RETRO_ETCHING`, `RIVIERA_POP`, `SPOTLIGHT_80S`, `STYLIZED_RED`, `SURREAL_COLLAGE`, `TRAVEL_POSTER`, `VINTAGE_GEO`, `VINTAGE_POSTER`, `WATERCOLOR`, `WEIRD`, `WOODBLOCK_PRINT`
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to fill the masked part of the image.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to generate an image from. MUST have the exact same dimensions (width and height) as the mask image.
    </ParamField>

    <ParamField body="mask_url" type="string" required>
      The mask URL to inpaint the image. MUST have the exact same dimensions (width and height) as the input image.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "expand_prompt": true,
      "num_images": 1,
      "sync_mode": false,
      "prompt": "black bag",
      "image_url": "https://v3.fal.media/files/panda/-LC_gNNV3wUHaGMQT3klE_output.png",
      "mask_url": "https://v3.fal.media/files/kangaroo/1dd3zEL5MXQ3Kb4-mRi9d_indir%20(20).png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/panda/xr7EI_0X5kM8fDOjjcMei_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Layerize Text">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v3/layerize-text`
    **Endpoint ID:** `fal-ai/ideogram/v3/layerize-text`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v3/layerize-text/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v3/layerize-text",
          arguments={
              "image_url": "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v3/layerize-text", {
        input: {
            image_url: "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v3/layerize-text \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png"
      }'
      ```
    </CodeGroup>

    ## Examples

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a9552a2/Nw6eNYNT6_UzsiMsVI9f9_image.png" alt="Example output from Ideogram" />
    </Frame>

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a955269/sCOtM2vExnZl_Qk9bUBq5_image.png" alt="Example output from Ideogram" />
    </Frame>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      URL of the flat graphic image to layerize. Must be JPEG, PNG, or WebP (max 10MB).
    </ParamField>

    <ParamField body="prompt" type="string">
      Optional prompt to guide the layerization.
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator.
    </ParamField>

    <ParamField body="font_file_h1_url" type="string">
      URL of the font file to use for h1 text. Cannot be used with font\_name\_h1.
    </ParamField>

    <ParamField body="font_name_h1" type="string">
      Name of the font to use for h1 text. Cannot be used with font\_file\_h1\_url.
    </ParamField>

    <ParamField body="font_file_h2_url" type="string">
      URL of the font file to use for h2 text. Cannot be used with font\_name\_h2.
    </ParamField>

    <ParamField body="font_name_h2" type="string">
      Name of the font to use for h2 text. Cannot be used with font\_file\_h2\_url.
    </ParamField>

    <ParamField body="font_file_body_url" type="string">
      URL of the font file to use for body text. Cannot be used with font\_name\_body.
    </ParamField>

    <ParamField body="font_name_body" type="string">
      Name of the font to use for body text. Cannot be used with font\_file\_body\_url.
    </ParamField>

    <ParamField body="font_file_small_url" type="string">
      URL of the font file to use for small text. Cannot be used with font\_name\_small.
    </ParamField>

    <ParamField body="font_name_small" type="string">
      Name of the font to use for small text. Cannot be used with font\_file\_small\_url.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="File" required>
      The background image with text removed.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for layerization. May differ from the input prompt if MagicPrompt expanded it.
    </ParamField>

    <ParamField body="text_containers" type="list<object>">
      Structured text containers with hierarchical text data (container -> items -> spans).
    </ParamField>

    <ParamField body="text_html" type="string">
      Rendered overlay HTML for compositing text over the background image.
    </ParamField>

    <ParamField body="image_layers" type="list<object>">
      Image layers extracted from the design.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://v3.fal.media/files/lion/0qJs_qW8nz0wYsXhFa6Tk.png",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019
      },
      "prompt": "",
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Remix">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v3/remix`
    **Endpoint ID:** `fal-ai/ideogram/v3/remix`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v3/remix/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v3/remix",
          arguments={
              "prompt": "Old ancient city day light",
              "image_url": "https://v3.fal.media/files/lion/9-Yt8JfTw4OxrAjiUzwP9_output.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v3/remix", {
        input: {
            prompt: "Old ancient city day light",
            image_url: "https://v3.fal.media/files/lion/9-Yt8JfTw4OxrAjiUzwP9_output.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v3/remix \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Old ancient city day light",
        "image_url": "https://v3.fal.media/files/lion/9-Yt8JfTw4OxrAjiUzwP9_output.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="style" type="Enum">
      The style type to generate with. Cannot be used with style\_codes.

      Possible values: `AUTO`, `GENERAL`, `REALISTIC`, `DESIGN`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt to remix the image with
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL to remix
    </ParamField>

    <ParamField body="strength" type="float" default="0.8">
      Strength of the input image in the remix Default value: `0.8`

      Range: `0.01` to `1`
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="square_hd">
      The resolution of the generated image Default value: `square_hd`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      Description of what to exclude from an image. Descriptions in the prompt take precedence to descriptions in the negative prompt. Default value: `""`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "expand_prompt": true,
      "num_images": 1,
      "sync_mode": false,
      "prompt": "Old ancient city day light",
      "image_url": "https://v3.fal.media/files/lion/9-Yt8JfTw4OxrAjiUzwP9_output.png",
      "strength": 0.8,
      "image_size": "square_hd",
      "negative_prompt": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/koala/eYZG26O54NTdWzdpDWBL-_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>

  <Tab title="Replace Background">
    **Endpoint:** `POST https://fal.run/fal-ai/ideogram/v3/replace-background`
    **Endpoint ID:** `fal-ai/ideogram/v3/replace-background`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/ideogram/v3/replace-background/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/ideogram/v3/replace-background",
          arguments={
              "prompt": "A beautiful sunset over mountains that writes Ideogram v3 in fal.ai",
              "image_url": "https://v3.fal.media/files/rabbit/F6dvKPFL9VzKiM8asJOgm_MJj6yUB6rGjTsv_1YHIcA_image.webp"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/ideogram/v3/replace-background", {
        input: {
            prompt: "A beautiful sunset over mountains that writes Ideogram v3 in fal.ai",
            image_url: "https://v3.fal.media/files/rabbit/F6dvKPFL9VzKiM8asJOgm_MJj6yUB6rGjTsv_1YHIcA_image.webp"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/ideogram/v3/replace-background \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A beautiful sunset over mountains that writes Ideogram v3 in fal.ai",
        "image_url": "https://v3.fal.media/files/rabbit/F6dvKPFL9VzKiM8asJOgm_MJj6yUB6rGjTsv_1YHIcA_image.webp"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_urls" type="list<string>">
      A set of images to use as style references (maximum total size 10MB across all style references). The images should be in JPEG, PNG or WebP format
    </ParamField>

    <ParamField body="rendering_speed" type="RenderingSpeedEnum" default="BALANCED">
      The rendering speed to use. Default value: `"BALANCED"`

      Possible values: `TURBO`, `BALANCED`, `QUALITY`
    </ParamField>

    <ParamField body="color_palette" type="ColorPalette">
      A color palette for generation, must EITHER be specified via one of the presets (name) or explicitly via hexadecimal representations of the color with optional weights (members)
    </ParamField>

    <ParamField body="style_codes" type="list<string>">
      A list of 8 character hexadecimal codes representing the style of the image. Cannot be used in conjunction with style\_reference\_images or style
    </ParamField>

    <ParamField body="style" type="Enum">
      The style type to generate with. Cannot be used with style\_codes.

      Possible values: `AUTO`, `GENERAL`, `REALISTIC`, `DESIGN`
    </ParamField>

    <ParamField body="expand_prompt" type="boolean" default="true">
      Determine if MagicPrompt should be used in generating the request or not. Default value: `true`
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      Seed for the random number generator
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="style_preset" type="Enum">
      Style preset for generation. The chosen style preset will guide the generation.

      Possible values: `80S_ILLUSTRATION`, `90S_NOSTALGIA`, `ABSTRACT_ORGANIC`, `ANALOG_NOSTALGIA`, `ART_BRUT`, `ART_DECO`, `ART_POSTER`, `AURA`, `AVANT_GARDE`, `BAUHAUS`, `BLUEPRINT`, `BLURRY_MOTION`, `BRIGHT_ART`, `C4D_CARTOON`, `CHILDRENS_BOOK`, `COLLAGE`, `COLORING_BOOK_I`, `COLORING_BOOK_II`, `CUBISM`, `DARK_AURA`, `DOODLE`, `DOUBLE_EXPOSURE`, `DRAMATIC_CINEMA`, `EDITORIAL`, `EMOTIONAL_MINIMAL`, `ETHEREAL_PARTY`, `EXPIRED_FILM`, `FLAT_ART`, `FLAT_VECTOR`, `FOREST_REVERIE`, `GEO_MINIMALIST`, `GLASS_PRISM`, `GOLDEN_HOUR`, `GRAFFITI_I`, `GRAFFITI_II`, `HALFTONE_PRINT`, `HIGH_CONTRAST`, `HIPPIE_ERA`, `ICONIC`, `JAPANDI_FUSION`, `JAZZY`, `LONG_EXPOSURE`, `MAGAZINE_EDITORIAL`, `MINIMAL_ILLUSTRATION`, `MIXED_MEDIA`, `MONOCHROME`, `NIGHTLIFE`, `OIL_PAINTING`, `OLD_CARTOONS`, `PAINT_GESTURE`, `POP_ART`, `RETRO_ETCHING`, `RIVIERA_POP`, `SPOTLIGHT_80S`, `STYLIZED_RED`, `SURREAL_COLLAGE`, `TRAVEL_POSTER`, `VINTAGE_GEO`, `VINTAGE_POSTER`, `WATERCOLOR`, `WEIRD`, `WOODBLOCK_PRINT`
    </ParamField>

    <ParamField body="prompt" type="string" required>
      Cyber punk city with neon lights and skyscrappers
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The image URL whose background needs to be replaced
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<File>" required />

    <ParamField body="seed" type="integer" required>
      Seed used for the random number generator
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "rendering_speed": "BALANCED",
      "expand_prompt": true,
      "num_images": 1,
      "sync_mode": false,
      "prompt": "A beautiful sunset over mountains that writes Ideogram v3 in fal.ai",
      "image_url": "https://v3.fal.media/files/rabbit/F6dvKPFL9VzKiM8asJOgm_MJj6yUB6rGjTsv_1YHIcA_image.webp"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3.fal.media/files/lion/AUfCjtLkLOsdc9zEFrV-5_image.png"
        }
      ],
      "seed": 123456
    }
    ```
  </Tab>
</Tabs>

## Related

* [Ideogram](/model-api-reference/image-generation-api/ideogram) — Image Generation
* [Ideogram V3 Edit](/model-api-reference/image-generation-api/ideogram-v3-edit) — Image Generation
* [Ideogram Replace Background](/model-api-reference/image-generation-api/ideogram-replace-background) — Image Generation
* [Ideogram Text to Image](/model-api-reference/image-generation-api/ideogram-text-to-image) — Image Generation

## Limitations

* `rendering_speed` restricted to: `TURBO`, `BALANCED`, `QUALITY`
* `style` restricted to: `AUTO`, `GENERAL`, `REALISTIC`, `DESIGN`
* `num_images` range: 1 to 8
* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `rendering_speed` restricted to: `FLASH`, `TURBO`, `BALANCED`, `QUALITY`
* `strength` range: 0.01 to 1


# https://fal.ai/docs/model-api-reference/image-generation-api/imageutils.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Imageutils API

> API reference for Imageutils. Remove the background from an image.

<Tabs>
  <Tab title="Rembg">
    **Endpoint:** `POST https://fal.run/fal-ai/imageutils/rembg`
    **Endpoint ID:** `fal-ai/imageutils/rembg`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/imageutils/rembg/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/imageutils/rembg",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/imageutils/rembg", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/imageutils/rembg \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      Input image url.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="crop_to_bbox" type="boolean" default="false">
      If set to true, the resulting image be cropped to a bounding box around the subject
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      Background removed image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg",
      "sync_mode": false,
      "crop_to_bbox": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      }
    }
    ```
  </Tab>

  <Tab title="Depth">
    **Endpoint:** `POST https://fal.run/fal-ai/imageutils/depth`
    **Endpoint ID:** `fal-ai/imageutils/depth`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/imageutils/depth/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/imageutils/depth",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/imageutils/depth", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/imageutils/depth \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      Input image url.
    </ParamField>

    <ParamField body="a" type="float" default="6.283185307179586">
      a Default value: `6.283185307179586`
    </ParamField>

    <ParamField body="bg_th" type="float" default="0.1">
      bg\_th Default value: `0.1`
    </ParamField>

    <ParamField body="depth_and_normal" type="boolean" default="false">
      depth\_and\_normal
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      The depth map.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg",
      "a": 6.283185307179586,
      "bg_th": 0.1,
      "depth_and_normal": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      }
    }
    ```
  </Tab>

  <Tab title="Marigold Depth">
    **Endpoint:** `POST https://fal.run/fal-ai/imageutils/marigold-depth`
    **Endpoint ID:** `fal-ai/imageutils/marigold-depth`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/imageutils/marigold-depth/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/imageutils/marigold-depth",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/imageutils/marigold-depth", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/imageutils/marigold-depth \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
      }'
      ```
    </CodeGroup>

    ## Examples

    <Frame>
      <img src="https://v3.fal.media/files/rabbit/N0GgfUE25qCp850ji09pY_209fe579ff1045889f7f3513e5a6401f.png" alt="Example output from Marigold Depth Estimation" />
    </Frame>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      Input image url.
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="10">
      Number of denoising steps. Defaults to `10`. The higher the number, the more accurate the result, but the slower the inference. Default value: `10`

      Range: `2` to `50`
    </ParamField>

    <ParamField body="ensemble_size" type="integer" default="10">
      Number of predictions to average over. Defaults to `10`. The higher the number, the more accurate the result, but the slower the inference. Default value: `10`

      Range: `2` to `50`
    </ParamField>

    <ParamField body="processing_res" type="integer" default="0">
      Maximum processing resolution. Defaults `0` which means it uses the size of the input image.

      Range: `0` to `2048`
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="Image" required>
      The depth map.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg",
      "num_inference_steps": 10,
      "ensemble_size": 10,
      "processing_res": 0
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019,
        "width": 1024,
        "height": 1024
      }
    }
    ```
  </Tab>
</Tabs>

## Limitations

* `num_inference_steps` range: 2 to 50
* `ensemble_size` range: 2 to 50
* `processing_res` range: 0 to 2048


# https://fal.ai/docs/model-api-reference/image-generation-api/nano-banana.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Nano Banana API

> API reference for Nano Banana. Google's famous original image generation and editing model

<Tabs>
  <Tab title="Nano Banana">
    **Endpoint:** `POST https://fal.run/fal-ai/nano-banana`
    **Endpoint ID:** `fal-ai/nano-banana`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/nano-banana/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/nano-banana",
          arguments={
              "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/nano-banana", {
        input: {
            prompt: "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/nano-banana \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it'\''s mouth, and it'\''s paws paddling underwater."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt to generate an image from.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      The aspect ratio of the generated image. Default value: `"1:1"`

      Possible values: `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="false">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater.",
      "num_images": 1,
      "aspect_ratio": "1:1",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "limit_generations": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-t2i-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-t2i-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/nano-banana/edit`
    **Endpoint ID:** `fal-ai/nano-banana/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/nano-banana/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/nano-banana/edit",
          arguments={
              "prompt": "make a photo of the man driving the car down the california coastline",
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/nano-banana/edit", {
        input: {
            prompt: "make a photo of the man driving the car down the california coastline",
            image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/nano-banana/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "make a photo of the man driving the car down the california coastline",
        "image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
        ]
      }'
      ```
    </CodeGroup>

    ## Examples

    > make a photo of the man driving the car down the california coastline

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a95c085/S0ExtNZpsp_6xygCJ3MKG_Bj98CiYt.png" alt="Generated image: make a photo of the man driving the car down the california coastline" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt for image editing.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="auto">
      The aspect ratio of the generated image. Default value: `auto`

      Possible values: `auto`, `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      The URLs of the images to use for image-to-image generation or image editing.
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="false">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The edited images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "make a photo of the man driving the car down the california coastline",
      "num_images": 1,
      "aspect_ratio": "auto",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
      ],
      "limit_generations": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-multi-edit-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-multi-edit-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [Nano Banana](/model-api-reference/image-generation-api/nano-banana) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/image-generation-api/nano-banana-2.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Nano Banana 2 API

> API reference for Nano Banana 2. Nano Banana 2 is Google's new state-of-the-art fast image generation and editing model

<Tabs>
  <Tab title="Nano Banana 2">
    **Endpoint:** `POST https://fal.run/fal-ai/nano-banana-2`
    **Endpoint ID:** `fal-ai/nano-banana-2`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/nano-banana-2/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/nano-banana-2",
          arguments={
              "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/nano-banana-2", {
        input: {
            prompt: "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/nano-banana-2 \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it'\''s mouth, and it'\''s paws paddling underwater."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt to generate an image from.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="auto">
      The aspect ratio of the generated image. Supports extreme ratios: 4:1, 1:4, 8:1, 1:8. Use "auto" to let the model decide based on the prompt. Default value: `auto`

      Possible values: `auto`, `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`, `4:1`, `1:4`, `8:1`, `1:8`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1K">
      The resolution of the image to generate. Default value: `"1K"`

      Possible values: `0.5K`, `1K`, `2K`, `4K`
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="true">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate and ignore any intermediate images generated by the model. This may affect generation quality. Default value: `true`
    </ParamField>

    <ParamField body="enable_web_search" type="boolean" default="false">
      Enable web search for the image generation task. This will allow the model to use the latest information from the web to generate the image.
    </ParamField>

    <ParamField body="thinking_level" type="Enum">
      When set, enables model thinking with the given level ('minimal' or 'high') and includes thoughts in the generation. Omit to disable.

      Possible values: `minimal`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater.",
      "num_images": 1,
      "aspect_ratio": "auto",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "resolution": "1K",
      "limit_generations": true,
      "enable_web_search": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-2-t2i-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-2-t2i-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/nano-banana-2/edit`
    **Endpoint ID:** `fal-ai/nano-banana-2/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/nano-banana-2/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/nano-banana-2/edit",
          arguments={
              "prompt": "make a photo of the man driving the car down the california coastline",
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/nano-banana-2/edit", {
        input: {
            prompt: "make a photo of the man driving the car down the california coastline",
            image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/nano-banana-2/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "make a photo of the man driving the car down the california coastline",
        "image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
        ]
      }'
      ```
    </CodeGroup>

    ## Examples

    > make a photo of the man driving the car down the california coastline

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a95c08b/NQSC6eS_Ns1wyHUHslsB8_DIdSDU4X.png" alt="Generated image: make a photo of the man driving the car down the california coastline" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt for image editing.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="auto">
      The aspect ratio of the generated image. Supports extreme ratios: 4:1, 1:4, 8:1, 1:8. Default value: `auto`

      Possible values: `auto`, `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`, `4:1`, `1:4`, `8:1`, `1:8`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      The URLs of the images to use for image-to-image generation or image editing.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1K">
      The resolution of the image to generate. Default value: `"1K"`

      Possible values: `0.5K`, `1K`, `2K`, `4K`
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="true">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate and ignore any intermediate images generated by the model. This may affect generation quality. Default value: `true`
    </ParamField>

    <ParamField body="enable_web_search" type="boolean" default="false">
      Enable web search for the image generation task. This will allow the model to use the latest information from the web to generate the image.
    </ParamField>

    <ParamField body="thinking_level" type="Enum">
      When set, enables model thinking with the given level ('minimal' or 'high') and includes thoughts in the generation. Omit to disable.

      Possible values: `minimal`, `high`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The edited images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "make a photo of the man driving the car down the california coastline",
      "num_images": 1,
      "aspect_ratio": "auto",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
      ],
      "resolution": "1K",
      "limit_generations": true,
      "enable_web_search": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-2-edit-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-2-edit-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>
</Tabs>

## Nano Banana 2 \[text-to-image]

Google's Gemini 3.1 Flash Image architecture generates vibrant, high-fidelity visuals at speed, combining the reasoning capabilities of a multimodal foundation model with the efficiency of Flash-optimized inference. It understands creative intent holistically rather than matching keywords, producing images with accurate text rendering, character consistency, and coherent spatial composition in seconds.

**Built for:** Marketing campaigns and social media assets | Product photography and visualization | Designs requiring accurate in-image typography | Storyboarding with consistent characters across frames

### Reasoning-Guided, Flash-Fast

Built on Google's Gemini 3.1 Flash Image foundation, Nano Banana 2 reasons about composition, lighting, and spatial relationships before rendering. Unlike traditional diffusion models that treat prompts as weighted tokens, this architecture interprets creative direction as a multimodal language model would, capturing nuance and context that single-modality systems miss, then executes at Flash-tier speed.

**What this means for you:**

* **Vibrant output**: Rich color, punchy contrast, and visual coherence out of the box without post-processing
* **Accurate text rendering**: Character-by-character validated typography in multiple languages, directly in generated images
* **Character consistency**: Maintain identity for up to 5 people across generations for storyboarding and campaign work
* **Natural language control**: Describe mood, style, and context conversationally without mastering prompt engineering syntax
* **Web-grounded generation**: Optionally ground outputs in real-time web information for factually current visuals

### Technical Specifications

| Spec                      | Details                                                                |
| ------------------------- | ---------------------------------------------------------------------- |
| **Architecture**          | Gemini 3.1 Flash Image (Nano Banana 2)                                 |
| **Input**                 | Text prompts (natural language); up to 14 reference images for editing |
| **Output Formats**        | PNG, JPEG, WebP                                                        |
| **Resolution**            | 1K (default), 2K (1.5x rate), 4K (2x rate), 512x512 (0.75x rate)       |
| **Aspect Ratios**         | auto, 21:9, 16:9, 3:2, 4:3, 5:4, 1:1, 4:5, 3:4, 2:3, 9:16              |
| **Batch**                 | 1-4 images per request                                                 |
| **Character Consistency** | Up to 5 people across generations                                      |
| **Watermarking**          | SynthID digital watermarking on all outputs                            |
| **Web Search**            | Optional grounding via `enable_web_search` or `enable_google_search`   |
| **License**               | Commercial use enabled through fal.ai                                  |

[API Documentation](https://fal.ai/models/fal-ai/nano-banana-2/api)

### How It Stacks Up

**vs. Nano Banana Pro (Gemini 3 Pro Image)**: Nano Banana 2 prioritizes speed and vibrant output on the Flash architecture, generating in seconds where Pro optimizes for maximum reasoning depth at \$0.15/image. Choose Nano Banana 2 for fast iteration and production volume, Pro for maximum compositional complexity.

**vs. FLUX.2 \[dev]**: Nano Banana 2 delivers semantic-aware generation with native text rendering and character consistency through Gemini's multimodal reasoning. FLUX.2 \[dev] prioritizes resolution control and fine detail preservation for technical illustration workflows.

**vs. Original Nano Banana (Gemini 2.5 Flash Image)**: Nano Banana 2 adds reasoning-guided generation, dramatically improved text rendering, native multi-resolution output (1K/2K/4K), character consistency, multi-image compositing, and web search grounding. A generational leap in quality while maintaining Flash-tier speed.

## Related

* [Nano Banana 2](/model-api-reference/image-generation-api/nano-banana-2) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `resolution` restricted to: `0.5K`, `1K`, `2K`, `4K`
* `thinking_level` restricted to: `minimal`, `high`


# https://fal.ai/docs/model-api-reference/image-generation-api/nano-banana-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Nano Banana Pro API

> API reference for Nano Banana Pro. Nano Banana Pro is Google's new state-of-the-art image generation and editing model

<Tabs>
  <Tab title="Nano Banana Pro">
    **Endpoint:** `POST https://fal.run/fal-ai/nano-banana-pro`
    **Endpoint ID:** `fal-ai/nano-banana-pro`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/nano-banana-pro/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/nano-banana-pro",
          arguments={
              "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/nano-banana-pro", {
        input: {
            prompt: "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/nano-banana-pro \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it'\''s mouth, and it'\''s paws paddling underwater."
      }'
      ```
    </CodeGroup>

    ## Examples

    > An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a95c094/qGn_Uhoer-pmZ280bBLIl_uT30LWIl.png" alt="Generated image: An action shot of a black lab swimming in an inground suburban swimming pool. Th" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt to generate an image from.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="1:1">
      The aspect ratio of the generated image. Default value: `1:1`

      Possible values: `auto`, `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1K">
      The resolution of the image to generate. Default value: `"1K"`

      Possible values: `1K`, `2K`, `4K`
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="false">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate.
    </ParamField>

    <ParamField body="enable_web_search" type="boolean" default="false">
      Enable web search for the image generation task. This will allow the model to use the latest information from the web to generate the image.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater.",
      "num_images": 1,
      "aspect_ratio": "1:1",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "resolution": "1K",
      "limit_generations": false,
      "enable_web_search": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-pro-t2i-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-pro-t2i-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/nano-banana-pro/edit`
    **Endpoint ID:** `fal-ai/nano-banana-pro/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/nano-banana-pro/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/nano-banana-pro/edit",
          arguments={
              "prompt": "make a photo of the man driving the car down the california coastline",
              "image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
                  "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/nano-banana-pro/edit", {
        input: {
            prompt: "make a photo of the man driving the car down the california coastline",
            image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
              "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/nano-banana-pro/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "make a photo of the man driving the car down the california coastline",
        "image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
          "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
        ]
      }'
      ```
    </CodeGroup>

    ## Examples

    > make a photo of the man driving the car down the california coastline

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a95c097/cwrciOok_QqVLvkoEM3wp_Dj7uMWzg.png" alt="Generated image: make a photo of the man driving the car down the california coastline" />
    </Frame>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt for image editing.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="auto">
      The aspect ratio of the generated image. Default value: `auto`

      Possible values: `auto`, `21:9`, `16:9`, `3:2`, `4:3`, `5:4`, `1:1`, `4:5`, `3:4`, `2:3`, `9:16`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_urls" type="list<string>" required>
      The URLs of the images to use for image-to-image generation or image editing.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1K">
      The resolution of the image to generate. Default value: `"1K"`

      Possible values: `1K`, `2K`, `4K`
    </ParamField>

    <ParamField body="limit_generations" type="boolean" default="false">
      Experimental parameter to limit the number of generations from each round of prompting to 1. Set to `True` to to disregard any instructions in the prompt regarding the number of images to generate.
    </ParamField>

    <ParamField body="enable_web_search" type="boolean" default="false">
      Enable web search for the image generation task. This will allow the model to use the latest information from the web to generate the image.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The edited images.
    </ParamField>

    <ParamField body="description" type="string" required>
      The description of the generated images.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "make a photo of the man driving the car down the california coastline",
      "num_images": 1,
      "aspect_ratio": "auto",
      "output_format": "png",
      "safety_tolerance": "4",
      "sync_mode": false,
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png",
        "https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input-2.png"
      ],
      "resolution": "1K",
      "limit_generations": false,
      "enable_web_search": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "file_name": "nano-banana-pro-edit-output.png",
          "url": "https://storage.googleapis.com/falserverless/example_outputs/nano-banana-pro-edit-output.png"
        }
      ],
      "description": ""
    }
    ```
  </Tab>
</Tabs>

Google's Gemini 3 Pro Image architecture delivers production-quality visuals at \$0.15 per image—understanding context like a multimodal foundation model, not keyword matching like traditional diffusion systems. Trading raw speed for sophisticated semantic interpretation and enhanced reasoning capabilities, it transforms complex creative direction into accurate visuals without prompt engineering gymnastics, making it ideal for teams that need studio-quality results with advanced text rendering and character consistency.

**Built for:** Marketing campaign generation | Product visualization workflows | Creative content production requiring text accuracy | Infographic and diagram creation at scale

## Beyond CLIP: Multimodal Understanding

Built on Google's Gemini 3 Pro foundation, Nano Banana Pro processes prompts through the same multimodal architecture that powers conversational AI understanding nuance, context, and creative intent rather than simple keyword matching. Where traditional diffusion models treat prompts as collections of weighted tokens, this approach interprets your creative direction holistically, capturing relationships between concepts that single-modality systems miss.

**What this means for you:**

* **Semantic accuracy**: Generates images that match creative intent, not just literal prompt keywords understanding "1960s aesthetic" means grain, color palette, and composition choices
* **Reduced iteration cycles**: First-generation outputs align with complex briefs, cutting revision rounds compared to keyword-dependent models
* **Batch efficiency**: Process approximately 7 generations per dollar with consistent quality across variations, making A/B testing and campaign asset creation economically viable
* **Natural language control**: Direct the model with conversational prompts describing mood, style, and context without mastering prompt engineering syntax
* **Advanced text rendering**: Industry-leading text generation capabilities for creating legible text in multiple languages, fonts, and calligraphy styles directly within images

## Performance Optimized for Quality

Google's multimodal foundation prioritizes quality and reasoning depth over raw speed, optimized for production workflows requiring sophisticated outputs.

| Metric                    | Result                    | Context                                                                                     |
| ------------------------- | ------------------------- | ------------------------------------------------------------------------------------------- |
| **Cost per Image**        | \$0.15                    | \~7 generations per \$1.00 on fal.ai 4K outputs will be charged at double the standard rate |
| **Architecture**          | Gemini 3 Pro Image        | Multimodal foundation model with enhanced reasoning                                         |
| **Generation Philosophy** | Quality-first             | Prioritizes complex compositions and accuracy over speed                                    |
| **Batch Processing**      | Multiple images supported | Via `num_images` parameter in API                                                           |
| **Resolution Options**    | 1K, 2K, 4K                | Configurable via API                                                                        |

*Note: Generation times not publicly benchmarked by Google; model optimized for quality rather than speed metrics*

## Technical Specifications

| Spec                      | Details                                                                                  |
| ------------------------- | ---------------------------------------------------------------------------------------- |
| **Architecture**          | Gemini 3 Pro Image (Nano Banana Pro)                                                     |
| **Input Formats**         | Text prompts with natural language support; multi-image blending (up to 14 images)       |
| **Output Formats**        | PNG, JPEG, WebP image files                                                              |
| **Resolution Options**    | Multiple aspect ratios including 21:9, 16:9, 3:2, 4:3, 5:4, 1:1, 4:5, 3:4, 2:3, 9:16     |
| **Character Consistency** | Maintains consistency and resemblance for up to 5 people across generations              |
| **Watermarking**          | SynthID digital watermarking on all outputs; visible watermark for non-Ultra subscribers |
| **License**               | Commercial use enabled through fal.ai                                                    |
| **Launch Date**           | November 20, 2025                                                                        |

[API Documentation](https://fal.ai/models/fal-ai/nano-banana-pro/api)

## How It Stacks Up

**vs. FLUX.1 \[dev]**: Nano Banana Pro achieves semantic-aware generation with industry-leading text rendering through Gemini 3 Pro's multimodal reasoning, making it ideal for marketing materials requiring accurate typography. FLUX.1 \[dev] prioritizes maximum resolution control and fine detail preservation for technical illustration workflows.

**vs. Stable Diffusion 3.5**: Nano Banana Pro achieves natural language interpretation and real-world knowledge integration through Gemini architecture, making it ideal for teams creating infographics and data visualizations without prompt engineering expertise. Stable Diffusion 3.5 prioritizes open-source flexibility for custom fine-tuning and on-premise deployment scenarios.

**vs. Original Nano Banana (Gemini 2.5 Flash Image)**: Nano Banana Pro trades speed for quality, offering enhanced reasoning, superior text rendering, better character consistency, and advanced composition capabilities. Original Nano Banana remains available for rapid iterations and simple edits at lower cost (\$0.039/image).

## Related

* [Nano Banana Pro](/model-api-reference/image-generation-api/nano-banana-pro) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `resolution` restricted to: `1K`, `2K`, `4K`


# https://fal.ai/docs/model-api-reference/image-generation-api/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Image Generation API

> Image Generation API reference. Generate and edit images using state-of-the-art diffusion and transformer models.

## Overview

Generate and edit images using state-of-the-art diffusion and transformer models. fal.ai offers a wide range of models for text-to-image generation, image-to-image editing, style transfer, and context-aware transformations — optimized for different use cases from fast prototyping to production-quality output.

## Top Models

<CardGroup cols={2}>
  <Card title="Nano Banana 2 API" href="/model-api-reference/image-generation-api/nano-banana-2">
    Nano Banana 2 is Google's new state-of-the-art fast image generation and editing model

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a900b9e/ptbZcVWIQ_fXGGHfv8Zez_0ea5ca41bdf143a29e21e30a53120672.jpg" alt="Example output from Nano Banana 2" noZoom />
    </Frame>
  </Card>

  <Card title="Nano Banana Pro API" href="/model-api-reference/image-generation-api/nano-banana-pro">
    Nano Banana Pro is Google's new state-of-the-art image generation and editing model

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8691ce/SR0_u1zPJbx8jCIO6bJR0_8c83f0d66bbd48f3b55f825117941f84.jpg" alt="Example output from Nano Banana Pro" noZoom />
    </Frame>
  </Card>

  <Card title="Flux 2 Pro API" href="/model-api-reference/image-generation-api/flux-2-pro">
    Image editing with FLUX.2 \[pro] from Black Forest Labs. Ideal for high-quality image manipulation, style transfer, and sequential editing workflows

    <Frame>
      <img src="https://v3b.fal.media/files/b/penguin/UfryXXm9my6IM8HsoP9FL_054c2c2953dc491996904114c6e04836.jpg" alt="Example output from Flux 2 Pro" noZoom />
    </Frame>
  </Card>

  <Card title="FLUX1.1 [pro] ultra API" href="/model-api-reference/image-generation-api/flux-pro-v1.1-ultra">
    FLUX1.1 \[pro] ultra is the newest version of FLUX1.1 \[pro], maintaining professional-grade image quality while delivering up to 2K resolution with improved photo realism.

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/flux-pro-v1-1-ultra.webp" alt="Example output from FLUX1.1 [pro] ultra" noZoom />
    </Frame>
  </Card>

  <Card title="FLUX.1 [dev] API" href="/model-api-reference/image-generation-api/flux-dev">
    FLUX.1 \[dev] is a 12 billion parameter flow transformer that generates high-quality images from text. It is suitable for personal and commercial use.

    <Frame>
      <img src="https://storage.googleapis.com/fal_cdn/fal/Upscale-1.jpeg" alt="Example output from FLUX.1 [dev]" noZoom />
    </Frame>
  </Card>

  <Card title="FLUX.1 [dev] with LoRAs API" href="/model-api-reference/image-generation-api/flux-lora">
    Super fast endpoint for the FLUX.1 \[dev] model with LoRA support, enabling rapid and high-quality image generation using pre-trained LoRA adaptations for personalization, specific styles, brand identi

    <Frame>
      <img src="https://fal.media/files/penguin/hHhmyazpcSq_W8c0TzXl4_14015fe83e3541848e6b2e2e1c7e4968.jpg" alt="Example output from FLUX.1 [dev] with LoRAs" noZoom />
    </Frame>
  </Card>

  <Card title="Nano Banana API" href="/model-api-reference/image-generation-api/nano-banana">
    Google's famous original image generation and editing model

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a95c085/S0ExtNZpsp_6xygCJ3MKG_Bj98CiYt.png" alt="Example output from Nano Banana" noZoom />
    </Frame>
  </Card>

  <Card title="Bytedance API" href="/model-api-reference/image-generation-api/bytedance-seedream-v4.5">
    A new-generation image creation model ByteDance, Seedream 4.5 integrates image generation and image editing capabilities into a single, unified architecture.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a84910b/lDvWLqpxcFmzQHdadDA7t_4012f28b4f79444782d90d8927b42c29.jpg" alt="Example output from Bytedance" noZoom />
    </Frame>
  </Card>

  <Card title="Grok Imagine Image API" href="/model-api-reference/image-generation-api/xai-grok-imagine-image">
    Edit images precisely with xAI's Grok Imagine model

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8a0dc7/kv2XmZ5em8Kb2-7oXZndp_b897f79cbc564e1d8f4e5d5c71710c2b.jpg" alt="Example output from Grok Imagine Image" noZoom />
    </Frame>
  </Card>

  <Card title="GPT-Image 1.5 API" href="/model-api-reference/image-generation-api/gpt-image-1.5">
    GPT Image 1.5 generates high-fidelity images with strong prompt adherence, preserving composition, lighting, and fine-grained detail.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a875814/3KvlvWItvogHIOuPRWIVl_001c9e77742a4ff2a829a8ece127c0d1.jpg" alt="Example output from GPT-Image 1.5" noZoom />
    </Frame>
  </Card>

  <Card title="SeedVR2 API" href="/model-api-reference/image-generation-api/seedvr-upscale-image">
    Use SeedVR2 to upscale your images

    <Frame>
      <img src="https://v3.fal.media/files/panda/_-1rRy0_I6w-fbt3q0RDL_2f47fece6e2b433994dda482e8d20bb9.jpg" alt="Example output from SeedVR2" noZoom />
    </Frame>
  </Card>

  <Card title="Gemini 3 Pro Image Preview API" href="/model-api-reference/image-generation-api/gemini-3-pro-image-preview">
    Gemini 3 Pro Image (a.k.a Nano Banana Pro) is Google's state-of-the-art high-fidelity image generation and editing model

    <Frame>
      <img src="https://v3b.fal.media/files/b/penguin/Vp2KdBwHgd4Qp0ixnsOue_eb81afc63ac24064bc9d3e9ed48f9b74.jpg" alt="Example output from Gemini 3 Pro Image Preview" noZoom />
    </Frame>
  </Card>

  <Card title="Bria RMBG 2.0 API" href="/model-api-reference/image-generation-api/bria-background">
    Bria RMBG 2.0 enables seamless removal of backgrounds from images, ideal for professional editing tasks. Trained exclusively on licensed data for safe and risk-free commercial use. Model weights for c

    <Frame>
      <img src="https://v3.fal.media/files/lion/YBr6fXnaBoA_Hsy89qG6Q_44ab15cf50b0431fa4786c565c5b9032.png" alt="Example output from Bria RMBG 2.0" noZoom />
    </Frame>
  </Card>

  <Card title="Z-Image Turbo API" href="/model-api-reference/image-generation-api/z-image-turbo">
    Z-Image Turbo is a super fast text-to-image model of 6B parameters developed by Tongyi-MAI.

    <Frame>
      <img src="https://v3b.fal.media/files/b/koala/Pvji5sM6n6oNIo-p0Xsn__245f3d4eb5df4952aa80ec74f4afd7f2.jpg" alt="Example output from Z-Image Turbo" noZoom />
    </Frame>
  </Card>

  <Card title="Birefnet Background Removal API" href="/model-api-reference/image-generation-api/birefnet">
    bilateral reference framework (BiRefNet) for high-resolution dichotomous image segmentation (DIS)

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/birefnet.webp" alt="Example output from Birefnet Background Removal" noZoom />
    </Frame>
  </Card>

  <Card title="Topaz API" href="/model-api-reference/image-generation-api/topaz-upscale">
    Use the powerful and accurate topaz image enhancer to enhance your images.

    <Frame>
      <img src="https://storage.googleapis.com/fal_cdn/fal/Sound-3.jpg" alt="Example output from Topaz" noZoom />
    </Frame>
  </Card>

  <Card title="Ideogram Text to Image API" href="/model-api-reference/image-generation-api/ideogram-v3">
    Generate high-quality images, posters, and logos with Ideogram V3. Features exceptional typography handling and realistic outputs optimized for commercial and creative use.

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/image-5.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=a5eb3affecfe0e642fd722ebf728f088" alt="Example output from Ideogram Text to Image" noZoom width="512" height="512" data-path="images/image-5.png" />
    </Frame>
  </Card>

  <Card title="Remove Background API" href="/model-api-reference/image-generation-api/imageutils">
    Remove the background from an image.

    <Frame>
      <img src="https://mintcdn.com/fal-d8505a2e/_1QeqsRe91WUAOCJ/images/image-5.png?fit=max&auto=format&n=_1QeqsRe91WUAOCJ&q=85&s=a5eb3affecfe0e642fd722ebf728f088" alt="Example output from Remove Background" noZoom width="512" height="512" data-path="images/image-5.png" />
    </Frame>
  </Card>

  <Card title="Florence-2 Large API" href="/model-api-reference/image-generation-api/florence-2-large">
    Florence-2 is an advanced vision foundation model that uses a prompt-based approach to handle a wide range of vision and vision-language tasks

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/florence-2-large.jpeg" alt="Example output from Florence-2 Large" noZoom />
    </Frame>
  </Card>
</CardGroup>

Explore all image generation models on [fal.ai/models](https://fal.ai/models).

## Quick Start

Get started with **Nano Banana 2**:

<CodeGroup>
  ```python title="Python" theme={null}
  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/nano-banana-2",
      arguments={
          "prompt": "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/nano-banana-2", {
    input: {
        prompt: "An action shot of a black lab swimming in an inground suburban swimming pool. The camera is placed meticulously on the water line, dividing the image in half, revealing both the dogs head above water holding a tennis ball in it's mouth, and it's paws paddling underwater."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```
</CodeGroup>

## Pricing

For detailed pricing information, see the [fal.ai pricing page](https://fal.ai/pricing) or individual model pages.


# https://fal.ai/docs/model-api-reference/image-generation-api/seedvr-upscale-image.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Seedvr Upscale Image API

> API reference for Seedvr Upscale Image. Use SeedVR2 to upscale your images

<Tabs>
  <Tab title="Image">
    **Endpoint:** `POST https://fal.run/fal-ai/seedvr/upscale/image`
    **Endpoint ID:** `fal-ai/seedvr/upscale/image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/seedvr/upscale/image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/seedvr/upscale/image",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedvr2/image_in.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/seedvr/upscale/image", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/seedvr2/image_in.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/seedvr/upscale/image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedvr2/image_in.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The input image to be processed
    </ParamField>

    <ParamField body="upscale_mode" type="UpscaleModeEnum" default="factor">
      The mode to use for the upscale. If 'target', the upscale factor will be calculated based on the target resolution. If 'factor', the upscale factor will be used directly. Default value: `"factor"`

      Possible values: `target`, `factor`
    </ParamField>

    <ParamField body="upscale_factor" type="float" default="2">
      Upscaling factor to be used. Will multiply the dimensions with this factor when `upscale_mode` is `factor`. Default value: `2`

      Range: `1` to `10`
    </ParamField>

    <ParamField body="target_resolution" type="TargetResolutionEnum" default="1080p">
      The target resolution to upscale to when `upscale_mode` is `target`. Default value: `"1080p"`

      Possible values: `720p`, `1080p`, `1440p`, `2160p`
    </ParamField>

    <ParamField body="seed" type="integer">
      The random seed used for the generation process.
    </ParamField>

    <ParamField body="noise_scale" type="float" default="0.1">
      The noise scale to use for the generation process. Default value: `0.1`

      Range: `0` to `1`, step: `0.001`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpg">
      The format of the output image. Default value: `"jpg"`

      Possible values: `png`, `jpg`, `webp`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="ImageFile" required>
      Upscaled image file after processing
    </ParamField>

    <ParamField body="seed" type="integer" required>
      The random seed used for the generation process.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedvr2/image_in.png",
      "upscale_mode": "factor",
      "upscale_factor": 2,
      "target_resolution": "1080p",
      "noise_scale": 0.1,
      "output_format": "jpg",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "content_type": "image/png",
        "url": "https://storage.googleapis.com/falserverless/example_outputs/seedvr2/image_out.png"
      }
    }
    ```
  </Tab>

  <Tab title="Seamless">
    **Endpoint:** `POST https://fal.run/fal-ai/seedvr/upscale/image/seamless`
    **Endpoint ID:** `fal-ai/seedvr/upscale/image/seamless`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/seedvr/upscale/image/seamless/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/seedvr/upscale/image/seamless",
          arguments={
              "image_url": "https://v3b.fal.media/files/b/0a93eb33/dQ_ZwLyeu8P2UJYsa8RDW_seamless_image_in.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/seedvr/upscale/image/seamless", {
        input: {
            image_url: "https://v3b.fal.media/files/b/0a93eb33/dQ_ZwLyeu8P2UJYsa8RDW_seamless_image_in.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/seedvr/upscale/image/seamless \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://v3b.fal.media/files/b/0a93eb33/dQ_ZwLyeu8P2UJYsa8RDW_seamless_image_in.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The input image to be processed
    </ParamField>

    <ParamField body="upscale_mode" type="UpscaleModeEnum" default="factor">
      The mode to use for the upscale. If 'target', the upscale factor will be calculated based on the target resolution. If 'factor', the upscale factor will be used directly. Default value: `"factor"`

      Possible values: `target`, `factor`
    </ParamField>

    <ParamField body="upscale_factor" type="float" default="2">
      Upscaling factor to be used. Will multiply the dimensions with this factor when `upscale_mode` is `factor`. Default value: `2`

      Range: `1` to `10`
    </ParamField>

    <ParamField body="target_resolution" type="TargetResolutionEnum" default="1080p">
      The target resolution to upscale to when `upscale_mode` is `target`. Default value: `"1080p"`

      Possible values: `720p`, `1080p`, `1440p`, `2160p`
    </ParamField>

    <ParamField body="seed" type="integer">
      The random seed used for the generation process.
    </ParamField>

    <ParamField body="noise_scale" type="float" default="0.1">
      The noise scale to use for the generation process. Default value: `0.1`

      Range: `0` to `1`, step: `0.001`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the output image. Default value: `"png"`

      Possible values: `png`, `jpeg`, `webp`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="image" type="ImageFile" required>
      Upscaled image file after processing
    </ParamField>

    <ParamField body="seed" type="integer" required>
      The random seed used for the generation process.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://v3b.fal.media/files/b/0a93eb33/dQ_ZwLyeu8P2UJYsa8RDW_seamless_image_in.png",
      "upscale_mode": "factor",
      "upscale_factor": 2,
      "target_resolution": "1080p",
      "noise_scale": 0.1,
      "enable_safety_checker": true,
      "output_format": "png",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "image": {
        "content_type": "image/png",
        "url": "https://storage.googleapis.com/falserverless/example_outputs/seedvr2/image_out.png"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [SeedVR2](/model-api-reference/video-generation-api/seedvr2) — Video Generation

## Limitations

* `upscale_mode` restricted to: `target`, `factor`
* `upscale_factor` range: 1 to 10
* `target_resolution` restricted to: `720p`, `1080p`, `1440p`, `2160p`
* `noise_scale` range: 0 to 1 (step 0.001)
* `output_format` restricted to: `png`, `jpg`, `webp`
* `output_format` restricted to: `png`, `jpeg`, `webp`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/topaz-upscale.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Topaz Upscale API

> API reference for Topaz Upscale. Use the powerful and accurate topaz image enhancer to enhance your images.

**Endpoint:** `POST https://fal.run/fal-ai/topaz/upscale/image`
**Endpoint ID:** `fal-ai/topaz/upscale/image`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/topaz/upscale/image/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/topaz/upscale/image",
      arguments={
          "image_url": "https://storage.googleapis.com/falserverless/model_tests/codeformer/codeformer_poor_1.jpeg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/topaz/upscale/image", {
    input: {
        image_url: "https://storage.googleapis.com/falserverless/model_tests/codeformer/codeformer_poor_1.jpeg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/topaz/upscale/image \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://storage.googleapis.com/falserverless/model_tests/codeformer/codeformer_poor_1.jpeg"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="model" type="ModelEnum" default="Standard V2">
  Model to use for image enhancement. Default value: `"Standard V2"`

  Possible values: `Low Resolution V2`, `Standard V2`, `CGI`, `High Fidelity V2`, `Text Refine`, `Recovery`, `Redefine`, `Recovery V2`, `Standard MAX`, `Wonder`
</ParamField>

<ParamField body="upscale_factor" type="float" default="2">
  Factor to upscale the image by (e.g. 2.0 doubles width and height) Default value: `2`

  Range: `1` to `4`
</ParamField>

<ParamField body="crop_to_fill" type="boolean" default="false" />

<ParamField body="image_url" type="string" required>
  Url of the image to be upscaled
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
  Output format of the upscaled image. Default value: `"jpeg"`

  Possible values: `jpeg`, `png`
</ParamField>

<ParamField body="subject_detection" type="SubjectDetectionEnum" default="All">
  Subject detection mode for the image enhancement. Applies to standard enhance and Recovery V2 models. Default value: `"All"`

  Possible values: `All`, `Foreground`, `Background`
</ParamField>

<ParamField body="face_enhancement" type="boolean" default="true">
  Whether to apply face enhancement to the image. Applies to standard enhance and Recovery V2 models. Default value: `true`
</ParamField>

<ParamField body="face_enhancement_creativity" type="float" default="0">
  Creativity level for face enhancement. 0.0 means no creativity, 1.0 means maximum creativity. Ignored if face enhancement is disabled.

  Range: `0` to `1`
</ParamField>

<ParamField body="face_enhancement_strength" type="float" default="0.8">
  Strength of the face enhancement. 0.0 means no enhancement, 1.0 means maximum enhancement. Ignored if face enhancement is disabled. Default value: `0.8`

  Range: `0` to `1`
</ParamField>

<ParamField body="sharpen" type="float">
  Sharpening level (0.0-1.0). Applies to Standard V2, Low Resolution V2, CGI, High Fidelity V2, Text Refine, and Redefine models.

  Range: `0` to `1`
</ParamField>

<ParamField body="denoise" type="float">
  Denoising level (0.0-1.0). Applies to Standard V2, Low Resolution V2, CGI, High Fidelity V2, Text Refine, and Redefine models.

  Range: `0` to `1`
</ParamField>

<ParamField body="fix_compression" type="float">
  Compression artifact removal level (0.0-1.0). Applies to Standard V2, Low Resolution V2, High Fidelity V2, and Text Refine models.

  Range: `0` to `1`
</ParamField>

<ParamField body="strength" type="float">
  Enhancement strength (0.01-1.0). Applies to Text Refine model only.

  Range: `0.01` to `1`
</ParamField>

<ParamField body="creativity" type="integer">
  Creativity level for generative upscaling (1-6). Higher values produce more creative/hallucinated details. Applies to Redefine model only.

  Range: `1` to `6`
</ParamField>

<ParamField body="texture" type="integer">
  Texture detail level for generative upscaling (1-5). Applies to Redefine model only.

  Range: `1` to `5`
</ParamField>

<ParamField body="prompt" type="string">
  Text prompt to guide generative upscaling (max 1024 chars). Applies to Redefine model only.
</ParamField>

<ParamField body="autoprompt" type="boolean">
  Enable automatic prompt generation for generative upscaling. Applies to Redefine model only.
</ParamField>

<ParamField body="detail" type="float">
  Detail recovery level (0.0-1.0). Applies to Recovery V2 model only.

  Range: `0` to `1`
</ParamField>

### Output Schema

<ParamField body="image" type="File" required>
  The upscaled image.
</ParamField>

### Input Example

```json theme={null}
{
  "model": "Standard V2",
  "upscale_factor": 2,
  "crop_to_fill": false,
  "image_url": "https://storage.googleapis.com/falserverless/model_tests/codeformer/codeformer_poor_1.jpeg",
  "output_format": "jpeg",
  "subject_detection": "All",
  "face_enhancement": true,
  "face_enhancement_creativity": 0,
  "face_enhancement_strength": 0.8
}
```

### Output Example

```json theme={null}
{
  "image": {
    "url": "",
    "content_type": "image/png",
    "file_name": "z9RV14K95DvU.png",
    "file_size": 4404019
  }
}
```

## Limitations

* `upscale_factor` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`
* `subject_detection` restricted to: `All`, `Foreground`, `Background`
* `face_enhancement_creativity` range: 0 to 1
* `face_enhancement_strength` range: 0 to 1
* `sharpen` range: 0 to 1
* `denoise` range: 0 to 1
* `fix_compression` range: 0 to 1
* `strength` range: 0.01 to 1
* `creativity` range: 1 to 6
* `texture` range: 1 to 5
* `detail` range: 0 to 1


# https://fal.ai/docs/model-api-reference/image-generation-api/xai-grok-imagine-image.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Xai Grok Imagine Image API

> API reference for Xai Grok Imagine Image. Generate highly aesthetic images with xAI's Grok Imagine Image generation model.

<Tabs>
  <Tab title="Grok Imagine Image">
    **Endpoint:** `POST https://fal.run/xai/grok-imagine-image`
    **Endpoint ID:** `xai/grok-imagine-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/grok-imagine-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "xai/grok-imagine-image",
          arguments={
              "prompt": "Abstract human silhouette, golden particles ready to burst outward representing joy, data visualization style, emotional expression through particles, artistic scientific"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("xai/grok-imagine-image", {
        input: {
            prompt: "Abstract human silhouette, golden particles ready to burst outward representing joy, data visualization style, emotional expression through particles, artistic scientific"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/xai/grok-imagine-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Abstract human silhouette, golden particles ready to burst outward representing joy, data visualization style, emotional expression through particles, artistic scientific"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of the desired image.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="1:1">
      Aspect ratio of the generated image. Default value: `"1:1"`

      Possible values: `2:1`, `20:9`, `19.5:9`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`, `9:19.5`, `9:20`, `1:2`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1k">
      Resolution of the generated image. `1k` for standard resolution, `2k` for high resolution. Default value: `"1k"`

      Possible values: `1k`, `2k`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The URL of the generated image.
    </ParamField>

    <ParamField body="revised_prompt" type="string" required>
      The enhanced prompt that was used to generate the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Abstract human silhouette, golden particles ready to burst outward representing joy, data visualization style, emotional expression through particles, artistic scientific",
      "num_images": 1,
      "aspect_ratio": "1:1",
      "resolution": "1k",
      "output_format": "jpeg",
      "sync_mode": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3b.fal.media/files/b/0a8b90b7/9avg_nKJmcVinjQHJR_Ja.jpg"
        }
      ],
      "revised_prompt": ""
    }
    ```
  </Tab>

  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/xai/grok-imagine-image/edit`
    **Endpoint ID:** `xai/grok-imagine-image/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/grok-imagine-image/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "xai/grok-imagine-image/edit",
          arguments={
              "prompt": "Make this scene more realistic but still keep the game vibes"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("xai/grok-imagine-image/edit", {
        input: {
            prompt: "Make this scene more realistic but still keep the game vibes"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/xai/grok-imagine-image/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Make this scene more realistic but still keep the game vibes"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of the desired image.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      Number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1k">
      Resolution of the generated image. `1k` for standard resolution, `2k` for high resolution. Default value: `"1k"`

      Possible values: `1k`, `2k`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="jpeg">
      The format of the generated image. Default value: `"jpeg"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      List of URLs of the images to edit. A maximum of 3 images are supported.
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The URL of the edited image.
    </ParamField>

    <ParamField body="revised_prompt" type="string" required>
      The enhanced prompt that was used to generate the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Make this scene more realistic but still keep the game vibes",
      "num_images": 1,
      "resolution": "1k",
      "output_format": "jpeg",
      "sync_mode": false,
      "image_urls": [
        "https://v3b.fal.media/files/b/0a8b911d/Abk8vStrvmSPlzUqI_NN3_image_043.png"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "url": "https://v3b.fal.media/files/b/0a8b911d/XMqiVoO2ECXUZEUYmPl2l.jpg"
        }
      ],
      "revised_prompt": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [Grok Imagine Image](/model-api-reference/image-generation-api/grok-imagine-image) — Image Generation

## Limitations

* `num_images` range: 1 to 4
* `resolution` restricted to: `1k`, `2k`
* `output_format` restricted to: `jpeg`, `png`, `webp`


# https://fal.ai/docs/model-api-reference/image-generation-api/z-image-base.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Z Image Base API

> API reference for Z Image Base. Z-Image is the foundation model of the Z- Image family, engineered for good quality, robust generative diversity, broad stylistic coverage, and precise prompt adherence

<Tabs>
  <Tab title="Base">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/base`
    **Endpoint ID:** `fal-ai/z-image/base`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/base/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/base",
          arguments={
              "prompt": "Grandmother knitting by a window, an empty chair by her"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/base", {
        input: {
            prompt: "Grandmother knitting by a window, an empty chair by her"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/base \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Grandmother knitting by a window, an empty chair by her"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="4">
      The guidance scale to use for the image generation. Default value: `4`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      The negative prompt to use for the image generation. Default value: `""`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Grandmother knitting by a window, an empty chair by her",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "guidance_scale": 4,
      "negative_prompt": ""
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 768,
          "url": "https://v3b.fal.media/files/b/0a8c18a5/1z0k9F1YLgz4qCr64jCBa_r2uqRyDg.png",
          "width": 1024
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Lora">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/base/lora`
    **Endpoint ID:** `fal-ai/z-image/base/lora`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/base/lora/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/base/lora",
          arguments={
              "prompt": "Grandmother knitting by a window, an empty chair by her"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/base/lora", {
        input: {
            prompt: "Grandmother knitting by a window, an empty chair by her"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/base/lora \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Grandmother knitting by a window, an empty chair by her"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
      The size of the generated image. Default value: `landscape_4_3`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="28">
      The number of inference steps to perform. Default value: `28`

      Range: `1` to `50`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="guidance_scale" type="float" default="4">
      The guidance scale to use for the image generation. Default value: `4`

      Range: `1` to `20`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="">
      The negative prompt to use for the image generation. Default value: `""`
    </ParamField>

    <ParamField body="loras" type="list<LoRAInput>" default="">
      List of LoRA weights to apply (maximum 3).
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Grandmother knitting by a window, an empty chair by her",
      "image_size": "landscape_4_3",
      "num_inference_steps": 28,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "guidance_scale": 4,
      "negative_prompt": "",
      "loras": []
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 768,
          "url": "https://v3b.fal.media/files/b/0a8c18a5/1z0k9F1YLgz4qCr64jCBa_r2uqRyDg.png",
          "width": 1024
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [Z-Image Turbo](/model-api-reference/image-generation-api/z-image-turbo) — Image Generation
* [Z Image Base (LoRA)](/model-api-reference/image-generation-api/z-image-base-lora) — Image Generation
* [Z-Image Turbo Seamless Tiling](/model-api-reference/image-generation-api/z-image-turbo-seamless-tiling) — Image Generation
* [Z Image Base](/model-api-reference/image-generation-api/z-image-base) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_inference_steps` range: 1 to 50
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `acceleration` restricted to: `none`, `regular`, `high`
* `guidance_scale` range: 1 to 20
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/z-image-turbo.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Z Image Turbo API

> API reference for Z Image Turbo. Z-Image Turbo is a super fast text-to-image model of 6B parameters developed by Tongyi-MAI.

**Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo`
**Endpoint ID:** `fal-ai/z-image/turbo`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/z-image/turbo",
      arguments={
          "prompt": "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject's dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/z-image/turbo", {
    input: {
        prompt: "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject's dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/z-image/turbo \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject'\''s dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic."
  }'
  ```
</CodeGroup>

Tongyi-MAI's Z-Image Turbo delivers 6B-parameter text-to-image generation at \$0.005 per megapixel. Trading model size for raw speed through an 8-step inference pipeline, it optimizes for high-volume applications where cost efficiency and throughput matter more than maximum detail fidelity.

**Built for:** Rapid prototyping | Content variation testing | High-volume asset generation

***

## Speed-First Architecture for Volume Workflows

Z-Image Turbo compresses inference to 8 steps maximum (configurable down to 1), contrasting with standard diffusion models that typically require 20-50 steps for comparable output quality. The 6B parameter count keeps memory footprint lean while maintaining prompt adherence.

**What this means for you:**

* **Flexible resolution up to 4 megapixels:** Generate images from portrait to landscape orientations without resolution caps limiting your workflow
* **Batch generation up to 4 images:** Test multiple variations in a single API call for faster iteration cycles
* **Configurable inference steps (1-8):** Trade quality for speed based on your specific use case, use 1-step for thumbnails, 8-step for final assets
* **Optional prompt expansion:** Automatically enhance brief prompts with descriptive detail when you need richer outputs (adds \$0.0025 per request)

***

## Performance That Scales

Z-Image Turbo optimizes for cost-per-image economics in production environments where you're generating hundreds or thousands of assets.

| Metric                 | Result           | Context                                                  |
| :--------------------- | :--------------- | :------------------------------------------------------- |
| **Cost per Megapixel** | \$0.005          | 200 megapixels per \$1.00 on fal                         |
| **Inference Steps**    | 1-8 configurable | Default 8 steps balances speed/quality                   |
| **Max Resolution**     | Up to 4MP        | Supports standard aspect ratios from square to ultrawide |
| **Batch Size**         | 1-4 images       | Generate variations in single request                    |

***

## Technical Specifications

| Spec               | Details                                                                                        |
| :----------------- | :--------------------------------------------------------------------------------------------- |
| **Architecture**   | Z-Image Turbo (6B parameters)                                                                  |
| **Input Formats**  | Text prompts with optional seed control                                                        |
| **Output Formats** | JPEG, PNG, WebP                                                                                |
| **Max Resolution** | 4 megapixels (configurable aspect ratios)                                                      |
| **Training**       | [Z-Image Trainer](https://fal.ai/models/fal-ai/z-image-trainer) available for LoRA fine-tuning |
| **License**        | Commercial use permitted                                                                       |

[API Documentation](https://fal.ai/models/fal-ai/z-image/turbo/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart)

***

## How It Stacks Up

**[AuraFlow](https://fal.ai/models/fal-ai/aura-flow)** – Z-Image Turbo prioritizes inference speed and cost efficiency through its 8-step maximum pipeline, making it ideal for high-volume generation workflows where throughput matters. [AuraFlow](https://fal.ai/models/fal-ai/aura-flow) emphasizes prompt interpretation depth for complex creative briefs requiring nuanced understanding.

**[FLUX.2 \[dev\]](https://fal.ai/models/fal-ai/flux-2)** – Z-Image Turbo trades parameter count (6B vs FLUX.2's larger architecture) for faster inference and lower cost per megapixel ($0.005 vs $0.012), positioning it for production environments generating thousands of assets. [FLUX.2 \[dev\]](https://fal.ai/models/fal-ai/flux-2) offers higher detail fidelity and more sophisticated prompt following for applications where output quality justifies higher per-image costs.

**[FLUX.2 \[pro\]](https://fal.ai/models/fal-ai/flux-2-pro)** – Z-Image Turbo delivers 8-step generation at $0.005/MP for rapid iteration workflows. [FLUX.2 [pro]](https://fal.ai/models/fal-ai/flux-2-pro) provides enhanced photorealism and detail preservation at $0.03 for the first megapixel, designed for final production assets where maximum quality matters more than generation speed.

## Related

* [Z-Image Turbo](/model-api-reference/image-generation-api/z-image-turbo) — Image Generation
* [Z Image Base](/model-api-reference/image-generation-api/z-image-base) — Image Generation
* [Z Image Base (LoRA)](/model-api-reference/image-generation-api/z-image-base-lora) — Image Generation
* [Z-Image Turbo Seamless Tiling](/model-api-reference/image-generation-api/z-image-turbo-seamless-tiling) — Image Generation

## Capabilities

* Text prompt input
* Configurable resolution
* Adjustable inference steps
* Reproducible generation (seed)
* Synchronous mode
* Batch generation
* Safety checker

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to generate an image from.
</ParamField>

<ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
  The size of the generated image. Default value: `landscape_4_3`

  Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
</ParamField>

<ParamField body="num_inference_steps" type="integer" default="8">
  The number of inference steps to perform. Default value: `8`

  Range: `1` to `8`
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  The number of images to generate. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="enable_safety_checker" type="boolean" default="true">
  If set to true, the safety checker will be enabled. Default value: `true`
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="png">
  The format of the generated image. Default value: `"png"`

  Possible values: `jpeg`, `png`, `webp`
</ParamField>

<ParamField body="acceleration" type="AccelerationEnum" default="regular">
  The acceleration level to use. Default value: `"regular"`

  Possible values: `none`, `regular`, `high`
</ParamField>

<ParamField body="enable_prompt_expansion" type="boolean" default="false">
  Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
</ParamField>

### Output Schema

<ParamField body="images" type="list<ImageFile>" required>
  The generated image files info.
</ParamField>

<ParamField body="timings" type="Timings" required>
  The timings of the generation process.
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
</ParamField>

<ParamField body="has_nsfw_concepts" type="list<boolean>" required>
  Whether the generated images contain NSFW concepts.
</ParamField>

<ParamField body="prompt" type="string" required>
  The prompt used for generating the image.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject's dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic.",
  "image_size": "landscape_4_3",
  "num_inference_steps": 8,
  "sync_mode": false,
  "num_images": 1,
  "enable_safety_checker": true,
  "output_format": "png",
  "acceleration": "regular",
  "enable_prompt_expansion": false
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "content_type": "image/png",
      "height": 768,
      "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-turbo-output.png",
      "width": 1024
    }
  ],
  "prompt": ""
}
```

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_inference_steps` range: 1 to 8
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `acceleration` restricted to: `none`, `regular`, `high`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/z-image-turbo-controlnet.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Z Image Turbo Controlnet API

> API reference for Z Image Turbo Controlnet. Generate images from text and edge, depth or pose images using Z-Image Turbo, Tongyi-MAI's super-fast 6B model.

<Tabs>
  <Tab title="Controlnet">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/controlnet`
    **Endpoint ID:** `fal-ai/z-image/turbo/controlnet`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/controlnet/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/controlnet",
          arguments={
              "prompt": "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/controlnet", {
        input: {
            prompt: "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/controlnet \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto">
      The size of the generated image. Default value: `auto`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of Image for ControlNet generation.
    </ParamField>

    <ParamField body="control_scale" type="float" default="0.75">
      The scale of the controlnet conditioning. Default value: `0.75`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_start" type="float" default="0">
      The start of the controlnet conditioning.

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_end" type="float" default="0.8">
      The end of the controlnet conditioning. Default value: `0.8`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="preprocess" type="Enum" default="none">
      What kind of preprocessing to apply to the image, if any. Default value: `none`

      Possible values: `none`, `canny`, `depth`, `pose`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
      "image_size": "auto",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg",
      "control_scale": 0.75,
      "control_start": 0,
      "control_end": 0.8,
      "preprocess": "none"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 1024,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-turbo-controlnet-output.jpg",
          "width": 1536
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Lora">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/controlnet/lora`
    **Endpoint ID:** `fal-ai/z-image/turbo/controlnet/lora`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/controlnet/lora/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/controlnet/lora",
          arguments={
              "prompt": "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/controlnet/lora", {
        input: {
            prompt: "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/controlnet/lora \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto">
      The size of the generated image. Default value: `auto`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of Image for ControlNet generation.
    </ParamField>

    <ParamField body="control_scale" type="float" default="0.75">
      The scale of the controlnet conditioning. Default value: `0.75`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_start" type="float" default="0">
      The start of the controlnet conditioning.

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_end" type="float" default="0.8">
      The end of the controlnet conditioning. Default value: `0.8`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="preprocess" type="Enum" default="none">
      What kind of preprocessing to apply to the image, if any. Default value: `none`

      Possible values: `none`, `canny`, `depth`, `pose`
    </ParamField>

    <ParamField body="loras" type="list<LoRAInput>" default="">
      List of LoRA weights to apply (maximum 3).
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A single leopard, its spotted golden coat detailed with black rosettes, cautiously peeks its head through dense green foliage. The leopard’s eyes are alert and focused forward, ears perked, whiskers slightly visible. The bushes consist of thick, leafy shrubs with varying shades of green, some leaves partially obscuring the leopard’s muzzle and forehead. Soft natural daylight filters through the canopy above, casting dappled shadows across the animal’s fur and surrounding leaves. The composition is a medium close-up, centered on the leopard’s head emerging from the undergrowth, with shallow depth of field blurring the background vegetation.",
      "image_size": "auto",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-controlnet-input.jpg",
      "control_scale": 0.75,
      "control_start": 0,
      "control_end": 0.8,
      "preprocess": "none",
      "loras": []
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 1024,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-turbo-controlnet-output.jpg",
          "width": 1536
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

Tongyi-MAI's Z-Image Turbo delivers ControlNet-guided image generation at \$0.0065 per megapixel through a 6-billion parameter architecture. This model trades raw parameter count for specialized control mechanisms, canny edge detection, depth mapping, and pose guidance, that preserve structural fidelity during image-to-image transformations. Built for designers and developers who need precise spatial control without the inference overhead of larger diffusion models.

**Use Cases:** Product visualization with reference geometry | Character pose transfer workflows | Architectural rendering from depth maps

***

## Performance

Z-Image Turbo operates at roughly 3-5x more cost-effective rates than traditional ControlNet implementations by optimizing the 6B parameter base for rapid inference. At \$0.0065 per megapixel, you're running 153 megapixels per dollar, ideal for batch processing workflows where structural guidance matters more than photorealistic perfection.

| Metric                 | Result                                                                                                                                                            | Context                                                |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------- |
| **Model Size**         | 6 billion parameters                                                                                                                                              | Optimized for inference speed vs 70B+ alternatives     |
| **Inference Steps**    | 1-8 configurable                                                                                                                                                  | Default 8 steps balances quality and latency           |
| **Cost per Megapixel** | \$0.0065                                                                                                                                                          | 153 megapixels per \$1.00 on fal                       |
| **Control Methods**    | 4 preprocessing modes                                                                                                                                             | None, canny edge, depth map, pose detection            |
| **Batch Generation**   | Up to 4 images per request                                                                                                                                        | Parallel generation with shared control input          |
| **Related Endpoints**  | [Standard image-to-image](https://fal.ai/models/fal-ai/z-image/turbo/image-to-image), [LoRA variants](https://fal.ai/models/fal-ai/z-image/turbo/controlnet/lora) | ControlNet vs direct transformation vs custom training |

***

## Structural Control Without Compromise

Z-Image Turbo routes your prompt through three parallel conditioning pathways: text embedding, reference image structure, and optional preprocessing filters. Unlike pure text-to-image models that hallucinate spatial relationships, this architecture extracts edge maps, depth channels, or skeletal poses from your input, then enforces those constraints during diffusion.

**What this means for you:**

* **Configurable control strength (0-1 scale):** Dial conditioning intensity from 0.9 for strict adherence to 0.3 for loose interpretation, critical when your reference image has good composition but needs significant style deviation
* **Temporal control windowing:** Apply ControlNet guidance only during steps 0-40% of generation (configurable start/end), letting early diffusion lock structure while late steps refine aesthetics
* **Four preprocessing modes:** Feed raw images directly or auto-extract canny edges (sharp boundaries), depth maps (spatial layering), or pose skeletons (human/character positioning) without external tools
* **Multi-format output with safety:** Generate 1-4 variants simultaneously in JPEG, PNG, or WebP with optional built-in safety filtering, batch testing style variations while maintaining structural consistency

***

## Technical Specifications

| Spec                      | Details                                                          |
| :------------------------ | :--------------------------------------------------------------- |
| **Architecture**          | Z-Image Turbo 6B                                                 |
| **Input Formats**         | Text prompt + reference image URL (JPEG, PNG, WebP, GIF, AVIF)   |
| **Output Formats**        | JPEG, PNG, WebP with configurable dimensions                     |
| **Preprocessing Options** | None, Canny edge detection, Depth estimation, Pose detection     |
| **Control Parameters**    | Scale (0-1), temporal start/end windowing, inference steps (1-8) |
| **License**               | Commercial use permitted                                         |

[API Documentation](https://fal.ai/models/fal-ai/z-image/turbo/controlnet/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

\*\*Z-Image Turbo Standard ($0.0065/MP)** – The [ControlNet variant](https://fal.ai/models/fal-ai/z-image/turbo/controlnet) adds structural guidance preprocessing for $0.0065 per megapixel, same base cost. [Standard image-to-image](https://fal.ai/models/fal-ai/z-image/turbo/image-to-image) prioritizes direct style transfer without intermediate edge/depth extraction, ideal for texture swaps and color grading where spatial relationships already match your target. ControlNet trades processing simplicity for precise geometric control when your reference structure needs enforcement.

**FASHN Virtual Try-On V1.5** – Z-Image Turbo ControlNet offers general-purpose structural conditioning across edge, depth, and pose modalities for diverse creative workflows. [FASHN](https://fal.ai/models/fal-ai/fashn/tryon/v1.5) specializes in garment-to-body fitting with proprietary try-on algorithms optimized for fashion e-commerce, trading generality for domain-specific accuracy in clothing visualization.

## Related

* [Z-Image Turbo](/model-api-reference/image-generation-api/z-image-turbo) — Image Generation
* [Z Image Base](/model-api-reference/image-generation-api/z-image-base) — Image Generation
* [Z Image Base (LoRA)](/model-api-reference/image-generation-api/z-image-base-lora) — Image Generation
* [Z-Image Turbo Seamless Tiling](/model-api-reference/image-generation-api/z-image-turbo-seamless-tiling) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
* `num_inference_steps` range: 1 to 8
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `acceleration` restricted to: `none`, `regular`, `high`
* `control_scale` range: 0 to 1
* `control_start` range: 0 to 1
* `control_end` range: 0 to 1
* `preprocess` restricted to: `none`, `canny`, `depth`, `pose`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/z-image-turbo-image-to-image.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Z Image Turbo Image To Image API

> API reference for Z Image Turbo Image To Image. Generate images from text and images using Z-Image Turbo, Tongyi-MAI's super-fast 6B model.

<Tabs>
  <Tab title="Image To Image">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/image-to-image`
    **Endpoint ID:** `fal-ai/z-image/turbo/image-to-image`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/image-to-image/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/image-to-image",
          arguments={
              "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/image-to-image", {
        input: {
            prompt: "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/image-to-image \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto">
      The size of the generated image. Default value: `auto`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of Image for Image-to-Image generation.
    </ParamField>

    <ParamField body="strength" type="float" default="0.6">
      The strength of the image-to-image conditioning. Default value: `0.6`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
      "image_size": "auto",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png",
      "strength": 0.6
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 1728,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-turbo-i2i-output.png",
          "width": 992
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Lora">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/image-to-image/lora`
    **Endpoint ID:** `fal-ai/z-image/turbo/image-to-image/lora`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/image-to-image/lora/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/image-to-image/lora",
          arguments={
              "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/image-to-image/lora", {
        input: {
            prompt: "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/image-to-image/lora \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto">
      The size of the generated image. Default value: `auto`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of Image for Image-to-Image generation.
    </ParamField>

    <ParamField body="strength" type="float" default="0.6">
      The strength of the image-to-image conditioning. Default value: `0.6`
    </ParamField>

    <ParamField body="loras" type="list<LoRAInput>" default="">
      List of LoRA weights to apply (maximum 3).
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
      "image_size": "auto",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/z-image-turbo-i2i-input.png",
      "strength": 0.6,
      "loras": []
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 1728,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-turbo-i2i-output.png",
          "width": 992
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

Tongyi-MAI's Z-Image Turbo delivers image-to-image generation at \$0.005 per megapixel through a 6-billion parameter architecture. Trading raw parameter count for inference optimization, this model processes transformations in 8 steps or fewer while maintaining commercial-grade output quality. Built for developers who need cost-effective image modification at scale without sacrificing control over the transformation process.

**Built for:** Product variant generation | Style transfer workflows | Rapid prototyping iterations

***

## Performance That Scales

At \$0.005 per megapixel, Z-Image Turbo positions 10-15x more cost-effectively than premium image generation alternatives while maintaining the flexibility of adjustable inference steps.

| Metric                 | Result                                                                               | Context                                                          |
| :--------------------- | :----------------------------------------------------------------------------------- | :--------------------------------------------------------------- |
| **Inference Steps**    | 1-8 steps                                                                            | Configurable via API, default 8 steps balances quality and speed |
| **Cost per Megapixel** | \$0.005                                                                              | 200 megapixels per \$1.00 on fal                                 |
| **Batch Size**         | Up to 4 images                                                                       | Per request via `num_images` parameter                           |
| **Strength Range**     | 0.0-1.0                                                                              | Default 0.6, lower values preserve more source structure         |
| **Related Endpoints**  | [Z-Image Turbo LoRA](https://fal.ai/models/fal-ai/z-image/turbo/image-to-image/lora) | LoRA variant for custom style training                           |

***

## Image Transformation With Strength Control

Z-Image Turbo uses a diffusion-based architecture optimized for image-to-image conditioning, where you provide both a reference image and a text prompt to guide the transformation. Unlike pure text-to-image models that start from noise, this approach preserves structural elements from your input while applying the changes you specify.

**What this means for you:**

* **Adjustable transformation intensity:** Control how much the output diverges from your source image via the strength parameter (0-1 range), letting you dial in anything from subtle refinements to dramatic reimaginings
* **Multi-image batch processing:** Generate up to 4 variations per request, useful for A/B testing different prompt variations or exploring creative options without separate API calls
* **Flexible resolution handling:** Auto-sizing adapts to your input dimensions, with support for custom image sizes to match your workflow requirements
* **Accelerated inference options:** Three acceleration levels (none, regular, high) let you trade generation time for cost based on your use case, prototype fast, then refine at full quality

***

## Technical Specifications

| Spec               | Details                                              |
| :----------------- | :--------------------------------------------------- |
| **Architecture**   | Z-Image Turbo                                        |
| **Input Formats**  | Image URL (JPEG, PNG, WebP, GIF, AVIF) + text prompt |
| **Output Formats** | JPEG, PNG, WebP (configurable via `output_format`)   |
| **Model Size**     | 6B parameters                                        |
| **License**        | Commercial use enabled                               |

[API Documentation](https://fal.ai/models/fal-ai/z-image/turbo/image-to-image/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

**Z-Image Turbo LoRA** – Z-Image Turbo provides the base transformation engine at \$0.005/megapixel, while the [LoRA variant](https://fal.ai/models/fal-ai/z-image/turbo/image-to-image/lora) adds custom style training capabilities for specialized visual treatments. The LoRA endpoint trades base model simplicity for fine-tuned control when you need consistent brand aesthetics or specific artistic styles across multiple generations.

**FASHN Virtual Try-On V1.5** – Z-Image Turbo handles general-purpose image transformation with flexible prompt control for \$0.005/megapixel. [FASHN](https://fal.ai/models/fal-ai/fashn/tryon/v1.5) specializes in garment placement and fit visualization for e-commerce workflows where product accuracy matters more than creative flexibility.

**Image Editing endpoints (Age Progression, Wojak Style)** – Z-Image Turbo offers broad transformation flexibility through natural language prompts, while [specialized editing endpoints](https://fal.ai/models/fal-ai/image-editing/age-progression) provide single-function transformations optimized for specific use cases. Choose Z-Image Turbo when you need multi-purpose image modification without switching between task-specific models.

## Related

* [Z-Image Turbo](/model-api-reference/image-generation-api/z-image-turbo) — Image Generation
* [Z Image Base](/model-api-reference/image-generation-api/z-image-base) — Image Generation
* [Z Image Base (LoRA)](/model-api-reference/image-generation-api/z-image-base-lora) — Image Generation
* [Z-Image Turbo Seamless Tiling](/model-api-reference/image-generation-api/z-image-turbo-seamless-tiling) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
* `num_inference_steps` range: 1 to 8
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `acceleration` restricted to: `none`, `regular`, `high`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/z-image-turbo-inpaint.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Z Image Turbo Inpaint API

> API reference for Z Image Turbo Inpaint. Generate images from text, an image and a mask using Z-Image Turbo, Tongyi-MAI's super-fast 6B model.

<Tabs>
  <Tab title="Inpaint">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/inpaint`
    **Endpoint ID:** `fal-ai/z-image/turbo/inpaint`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/inpaint/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/inpaint",
          arguments={
              "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
              "mask_image_url": "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/inpaint", {
        input: {
            prompt: "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
            mask_image_url: "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/inpaint \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
        "mask_image_url": "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto">
      The size of the generated image. Default value: `auto`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of Image for Inpaint generation.
    </ParamField>

    <ParamField body="control_scale" type="float" default="0.75">
      The scale of the controlnet conditioning. Default value: `0.75`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_start" type="float" default="0">
      The start of the controlnet conditioning.

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_end" type="float" default="0.8">
      The end of the controlnet conditioning. Default value: `0.8`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="mask_image_url" type="string" required>
      URL of Mask for Inpaint generation.
    </ParamField>

    <ParamField body="strength" type="float" default="1">
      The strength of the inpaint conditioning. Default value: `1`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
      "image_size": "auto",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
      "control_scale": 0.75,
      "control_start": 0,
      "control_end": 0.8,
      "mask_image_url": "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg",
      "strength": 1
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 888,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-inpaint-output.png",
          "width": 512
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Lora">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/inpaint/lora`
    **Endpoint ID:** `fal-ai/z-image/turbo/inpaint/lora`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/inpaint/lora/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/inpaint/lora",
          arguments={
              "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
              "mask_image_url": "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/inpaint/lora", {
        input: {
            prompt: "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
            mask_image_url: "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/inpaint/lora \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
        "mask_image_url": "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="auto">
      The size of the generated image. Default value: `auto`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of Image for Inpaint generation.
    </ParamField>

    <ParamField body="control_scale" type="float" default="0.75">
      The scale of the controlnet conditioning. Default value: `0.75`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_start" type="float" default="0">
      The start of the controlnet conditioning.

      Range: `0` to `1`
    </ParamField>

    <ParamField body="control_end" type="float" default="0.8">
      The end of the controlnet conditioning. Default value: `0.8`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="mask_image_url" type="string" required>
      URL of Mask for Inpaint generation.
    </ParamField>

    <ParamField body="strength" type="float" default="1">
      The strength of the inpaint conditioning. Default value: `1`
    </ParamField>

    <ParamField body="loras" type="list<LoRAInput>" default="">
      List of LoRA weights to apply (maximum 3).
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A young Asian woman with long, vibrant purple hair stands on a sunlit sandy beach, posing confidently with her left hand resting on her hip. She gazes directly at the camera with a neutral expression. A sleek black ribbon bow is tied neatly on the right side of her head, just above her ear. She wears a flowing white cotton dress with a fitted bodice and a flared skirt that reaches mid-calf, slightly lifted by a gentle sea breeze. The beach behind her features fine, pale golden sand with subtle footprints, leading to calm turquoise waves under a clear blue sky with soft, wispy clouds. The lighting is natural daylight, casting soft shadows to her left, indicating late afternoon sun. The horizon line is visible in the background, with a faint silhouette of distant dunes. Her skin tone is fair with a natural glow, and her facial features are delicately defined. The composition is centered on her figure, framed from mid-thigh up, with shallow depth of field blurring the distant waves slightly.",
      "image_size": "auto",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/inpaint-input.jpg",
      "control_scale": 0.75,
      "control_start": 0,
      "control_end": 0.8,
      "mask_image_url": "https://storage.googleapis.com/falserverless/whls/z-image-inpaint-mask.jpg",
      "strength": 1,
      "loras": []
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 888,
          "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-inpaint-output.png",
          "width": 512
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [Z-Image Turbo](/model-api-reference/image-generation-api/z-image-turbo) — Image Generation
* [Z Image Base](/model-api-reference/image-generation-api/z-image-base) — Image Generation
* [Z Image Base (LoRA)](/model-api-reference/image-generation-api/z-image-base-lora) — Image Generation
* [Z-Image Turbo Seamless Tiling](/model-api-reference/image-generation-api/z-image-turbo-seamless-tiling) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
* `num_inference_steps` range: 1 to 8
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `acceleration` restricted to: `none`, `regular`, `high`
* `control_scale` range: 0 to 1
* `control_start` range: 0 to 1
* `control_end` range: 0 to 1
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/z-image-turbo-lora.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Z Image Turbo Lora API

> API reference for Z Image Turbo Lora. Text-to-Image endpoint with LoRA support for Z-Image Turbo, a super fast text-to-image model of 6B parameters developed by Tongyi-MAI.

**Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/lora`
**Endpoint ID:** `fal-ai/z-image/turbo/lora`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/lora/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/z-image/turbo/lora",
      arguments={
          "prompt": "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject's dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/z-image/turbo/lora", {
    input: {
        prompt: "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject's dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/z-image/turbo/lora \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject'\''s dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic."
  }'
  ```
</CodeGroup>

Tongyi-MAI's Z-Image Turbo with LoRA support delivers 6B-parameter text-to-image generation at \$0.0085 per megapixel with 8-step inference. Apply up to 3 custom LoRA weights at inference time without retraining, enabling style consistency and brand adaptation at approximately 118 generations per dollar on fal.

**Built for:** Custom style application | Brand-consistent generation | Character consistency workflows | Rapid design iteration

***

## LoRA Flexibility Without Training Overhead

Z-Image Turbo LoRA adds inference-time style customization to the base model's speed advantages. Apply pre-trained LoRA adapters directly through the API, combining multiple style influences in a single generation call without touching the underlying model weights.

**What this means for you:**

* **Apply up to 3 LoRA weights simultaneously:** Combine custom styles, character adapters, and brand guidelines in a single generation request through the `loras` parameter
* **Batch generation at scale:** Generate up to 4 images per request with configurable inference steps (1-8 range), optimizing the speed-quality tradeoff for your use case
* **Acceleration options:** Choose between "none", "regular", or "high" acceleration modes to balance generation speed against output fidelity
* **Production-ready safety:** Built-in safety checker (enabled by default) filters NSFW content automatically, with optional prompt expansion for enhanced detail at +\$0.0025 per request
* **Flexible output formats:** Generate images in JPEG, PNG, or WebP with landscape (4:3), portrait (3:4), or square (1:1) aspect ratios

***

## Performance That Scales

Z-Image Turbo LoRA adds minimal overhead to base model pricing while enabling custom style application at inference time.

| Metric                 | Result                     | Context                                           |
| :--------------------- | :------------------------- | :------------------------------------------------ |
| **Cost per Megapixel** | \$0.0085                   | \~118 generations per \$1.00 on fal               |
| **Inference Steps**    | 1-8 configurable           | Default 8 steps balances speed and quality        |
| **Batch Capability**   | Up to 4 images             | Single API call generates multiple variants       |
| **LoRA Support**       | Up to 3 concurrent weights | Apply custom styles without base model retraining |
| **Base Model Cost**    | \$0.005/MP                 | LoRA adds \$0.0035/MP for style flexibility       |

***

## Technical Specifications

| Spec                   | Details                                                                                  |
| :--------------------- | :--------------------------------------------------------------------------------------- |
| **Architecture**       | Z-Image Turbo (6B parameters) with LoRA inference                                        |
| **Input Formats**      | Text prompts, optional LoRA weights (up to 3)                                            |
| **Output Formats**     | JPEG, PNG, WebP                                                                          |
| **Image Sizes**        | Landscape 4:3, Portrait 3:4, Square 1:1                                                  |
| **Acceleration Modes** | None, Regular, High                                                                      |
| **Training**           | [Z-Image Trainer](https://fal.ai/models/fal-ai/z-image-trainer) for custom LoRA creation |
| **License**            | Commercial use permitted                                                                 |

[API Documentation](https://fal.ai/models/fal-ai/z-image/turbo/lora/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart)

***

## How It Stacks Up

**[Z-Image Turbo](https://fal.ai/models/fal-ai/z-image/turbo)** – The base Z-Image Turbo endpoint runs at $0.005/MP for maximum cost efficiency when style customization isn't required. The LoRA variant adds $0.0035/MP overhead to enable custom style application, character consistency, and brand adaptation at inference time.

**[AuraFlow](https://fal.ai/models/fal-ai/aura-flow)** – Z-Image Turbo LoRA prioritizes cost efficiency at \$0.0085/MP with 8-step inference and runtime style customization. [AuraFlow](https://fal.ai/models/fal-ai/aura-flow) emphasizes open-source flexibility and longer inference paths for applications requiring maximum creative control and community-driven development.

**[FLUX.2 \[dev\] LoRA](https://fal.ai/models/fal-ai/flux-2/lora)** – Z-Image Turbo LoRA delivers comparable style customization at $0.0085/MP versus FLUX.2 [dev] LoRA's $0.021/MP, making it 2.5x more cost-efficient for high-volume workflows. [FLUX.2 \[dev\] LoRA](https://fal.ai/models/fal-ai/flux-2/lora) offers higher resolution outputs and more sophisticated prompt interpretation for applications where output quality justifies the premium.

## Related

* [Z-Image Turbo](/model-api-reference/image-generation-api/z-image-turbo) — Image Generation
* [Z Image Base](/model-api-reference/image-generation-api/z-image-base) — Image Generation
* [Z Image Base (LoRA)](/model-api-reference/image-generation-api/z-image-base-lora) — Image Generation
* [Z-Image Turbo Seamless Tiling](/model-api-reference/image-generation-api/z-image-turbo-seamless-tiling) — Image Generation

## Capabilities

* Text prompt input
* Configurable resolution
* Adjustable inference steps
* Reproducible generation (seed)
* Synchronous mode
* Batch generation
* Safety checker
* LoRA support

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The prompt to generate an image from.
</ParamField>

<ParamField body="image_size" type="ImageSize | Enum" default="landscape_4_3">
  The size of the generated image. Default value: `landscape_4_3`

  Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
</ParamField>

<ParamField body="num_inference_steps" type="integer" default="8">
  The number of inference steps to perform. Default value: `8`

  Range: `1` to `8`
</ParamField>

<ParamField body="seed" type="integer">
  The same seed and the same prompt given to the same version of the model
  will output the same image every time.
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="num_images" type="integer" default="1">
  The number of images to generate. Default value: `1`

  Range: `1` to `4`
</ParamField>

<ParamField body="enable_safety_checker" type="boolean" default="true">
  If set to true, the safety checker will be enabled. Default value: `true`
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="png">
  The format of the generated image. Default value: `"png"`

  Possible values: `jpeg`, `png`, `webp`
</ParamField>

<ParamField body="acceleration" type="AccelerationEnum" default="regular">
  The acceleration level to use. Default value: `"regular"`

  Possible values: `none`, `regular`, `high`
</ParamField>

<ParamField body="enable_prompt_expansion" type="boolean" default="false">
  Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
</ParamField>

<ParamField body="loras" type="list<LoRAInput>" default="">
  List of LoRA weights to apply (maximum 3).
</ParamField>

### Output Schema

<ParamField body="images" type="list<ImageFile>" required>
  The generated image files info.
</ParamField>

<ParamField body="timings" type="Timings" required>
  The timings of the generation process.
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
</ParamField>

<ParamField body="has_nsfw_concepts" type="list<boolean>" required>
  Whether the generated images contain NSFW concepts.
</ParamField>

<ParamField body="prompt" type="string" required>
  The prompt used for generating the image.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A hyper-realistic, close-up portrait of a tribal elder from the Omo Valley, painted with intricate white chalk patterns and adorned with a headdress made of dried flowers, seed pods, and rusted bottle caps. The focus is razor-sharp on the texture of the skin, showing every pore, wrinkle, and scar that tells a story of survival. The background is a blurred, smoky hut interior, with the warm glow of a cooking fire reflecting in the subject's dark, soulful eyes. Shot on a Leica M6 with Kodak Portra 400 film grain aesthetic.",
  "image_size": "landscape_4_3",
  "num_inference_steps": 8,
  "sync_mode": false,
  "num_images": 1,
  "enable_safety_checker": true,
  "output_format": "png",
  "acceleration": "regular",
  "enable_prompt_expansion": false,
  "loras": []
}
```

## Output Example

```json theme={null}
{
  "images": [
    {
      "content_type": "image/png",
      "height": 768,
      "url": "https://storage.googleapis.com/falserverless/example_outputs/z-image-turbo-output.png",
      "width": 1024
    }
  ],
  "prompt": ""
}
```

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`
* `num_inference_steps` range: 1 to 8
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `acceleration` restricted to: `none`, `regular`, `high`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/image-generation-api/z-image-turbo-tiling.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Z Image Turbo Tiling API

> API reference for Z Image Turbo Tiling. Generate seamlessly tiling photorealistic images from text using Z-Image Turbo

<Tabs>
  <Tab title="Tiling">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/tiling`
    **Endpoint ID:** `fal-ai/z-image/turbo/tiling`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/tiling/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/tiling",
          arguments={
              "prompt": "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/tiling", {
        input: {
            prompt: "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/tiling \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="square_hd">
      The size of the generated image. Use 'auto' to match the input image size (or 1024x1024 if no image). Default value: `square_hd`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string">
      URL of an image for image-to-image or inpainting. When provided without mask\_image\_url, performs image-to-image; with mask\_image\_url, performs inpainting.
    </ParamField>

    <ParamField body="mask_image_url" type="string">
      URL of a mask image for inpainting. White regions are regenerated, black regions are preserved. Requires image\_url.
    </ParamField>

    <ParamField body="strength" type="float" default="0.6">
      How much to transform the input image. Only used when image\_url is provided. Default value: `0.6`
    </ParamField>

    <ParamField body="tile_size" type="integer" default="128">
      Tile size in latent space (64 = 512px, 128 = 1024px, 256 = 2048px). Default value: `128`

      Range: `32` to `256`
    </ParamField>

    <ParamField body="tile_stride" type="integer" default="64">
      Tile stride in latent space. (32 = 256px, 64 = 512px, 128 = 1024px). Default value: `64`

      Range: `16` to `128`
    </ParamField>

    <ParamField body="tiling_mode" type="TilingModeEnum" default="both">
      Tiling direction: 'both' (omnidirectional), 'horizontal' (left-right only), 'vertical' (top-bottom only). Default value: `"both"`

      Possible values: `both`, `horizontal`, `vertical`
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit.",
      "image_size": "square_hd",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "strength": 0.6,
      "tile_size": 128,
      "tile_stride": 64,
      "tiling_mode": "both"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 2048,
          "url": "https://v3b.fal.media/files/b/0a9276c3/6KxxMb0bPmfNLH3DqcuSf_qRUe8cIL.png",
          "width": 2048
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>

  <Tab title="Lora">
    **Endpoint:** `POST https://fal.run/fal-ai/z-image/turbo/tiling/lora`
    **Endpoint ID:** `fal-ai/z-image/turbo/tiling/lora`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/z-image/turbo/tiling/lora/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/z-image/turbo/tiling/lora",
          arguments={
              "prompt": "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/z-image/turbo/tiling/lora", {
        input: {
            prompt: "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/z-image/turbo/tiling/lora \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt to generate an image from.
    </ParamField>

    <ParamField body="image_size" type="ImageSize | Enum" default="square_hd">
      The size of the generated image. Use 'auto' to match the input image size (or 1024x1024 if no image). Default value: `square_hd`

      Possible values: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
    </ParamField>

    <ParamField body="num_inference_steps" type="integer" default="8">
      The number of inference steps to perform. Default value: `8`

      Range: `1` to `8`
    </ParamField>

    <ParamField body="seed" type="integer">
      The same seed and the same prompt given to the same version of the model
      will output the same image every time.
    </ParamField>

    <ParamField body="sync_mode" type="boolean" default="false">
      If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
    </ParamField>

    <ParamField body="num_images" type="integer" default="1">
      The number of images to generate. Default value: `1`

      Range: `1` to `4`
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="output_format" type="OutputFormatEnum" default="png">
      The format of the generated image. Default value: `"png"`

      Possible values: `jpeg`, `png`, `webp`
    </ParamField>

    <ParamField body="acceleration" type="AccelerationEnum" default="regular">
      The acceleration level to use. Default value: `"regular"`

      Possible values: `none`, `regular`, `high`
    </ParamField>

    <ParamField body="enable_prompt_expansion" type="boolean" default="false">
      Whether to enable prompt expansion. Note: this will increase the price by 0.0025 credits per request.
    </ParamField>

    <ParamField body="image_url" type="string">
      URL of an image for image-to-image or inpainting. When provided without mask\_image\_url, performs image-to-image; with mask\_image\_url, performs inpainting.
    </ParamField>

    <ParamField body="mask_image_url" type="string">
      URL of a mask image for inpainting. White regions are regenerated, black regions are preserved. Requires image\_url.
    </ParamField>

    <ParamField body="strength" type="float" default="0.6">
      How much to transform the input image. Only used when image\_url is provided. Default value: `0.6`
    </ParamField>

    <ParamField body="tile_size" type="integer" default="128">
      Tile size in latent space (64 = 512px, 128 = 1024px, 256 = 2048px). Default value: `128`

      Range: `32` to `256`
    </ParamField>

    <ParamField body="tile_stride" type="integer" default="64">
      Tile stride in latent space. (32 = 256px, 64 = 512px, 128 = 1024px). Default value: `64`

      Range: `16` to `128`
    </ParamField>

    <ParamField body="tiling_mode" type="TilingModeEnum" default="both">
      Tiling direction: 'both' (omnidirectional), 'horizontal' (left-right only), 'vertical' (top-bottom only). Default value: `"both"`

      Possible values: `both`, `horizontal`, `vertical`
    </ParamField>

    <ParamField body="loras" type="list<LoRAInput>" default="">
      List of LoRA weights to apply (maximum 3).
    </ParamField>

    ### Output Schema

    <ParamField body="images" type="list<ImageFile>" required>
      The generated image files info.
    </ParamField>

    <ParamField body="timings" type="Timings" required>
      The timings of the generation process.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed of the generated Image. It will be the same value of the one passed in the input or the randomly generated that was used in case none was passed.
    </ParamField>

    <ParamField body="has_nsfw_concepts" type="list<boolean>" required>
      Whether the generated images contain NSFW concepts.
    </ParamField>

    <ParamField body="prompt" type="string" required>
      The prompt used for generating the image.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A hyper-realistic, high-resolution 4k texture of an ancient weathered brick wall heavily overgrown with lush green moss and soft lichens. The bricks are aged, featuring deep earthy tones, natural cracks, and gritty textures. Vibrant emerald moss fills the mortar lines and spills over the rough surfaces of the stones. Uniform, flat cinematic lighting ensures no harsh shadows, highlighting the intricate organic details and damp stone surfaces. The composition is a perfectly balanced overhead view, showcasing a rich tapestry of botanical growth and masonry craftsmanship with professional clarity and hyper-detailed grit.",
      "image_size": "square_hd",
      "num_inference_steps": 8,
      "sync_mode": false,
      "num_images": 1,
      "enable_safety_checker": true,
      "output_format": "png",
      "acceleration": "regular",
      "enable_prompt_expansion": false,
      "strength": 0.6,
      "tile_size": 128,
      "tile_stride": 64,
      "tiling_mode": "both",
      "loras": []
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "images": [
        {
          "content_type": "image/png",
          "height": 2048,
          "url": "https://v3b.fal.media/files/b/0a9276c3/6KxxMb0bPmfNLH3DqcuSf_qRUe8cIL.png",
          "width": 2048
        }
      ],
      "prompt": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [Z-Image Turbo](/model-api-reference/image-generation-api/z-image-turbo) — Image Generation
* [Z Image Base](/model-api-reference/image-generation-api/z-image-base) — Image Generation
* [Z Image Base (LoRA)](/model-api-reference/image-generation-api/z-image-base-lora) — Image Generation
* [Z-Image Turbo Seamless Tiling](/model-api-reference/image-generation-api/z-image-turbo-seamless-tiling) — Image Generation

## Limitations

* `image_size` restricted to: `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9`, `auto`
* `num_inference_steps` range: 1 to 8
* `num_images` range: 1 to 4
* `output_format` restricted to: `jpeg`, `png`, `webp`
* `acceleration` restricted to: `none`, `regular`, `high`
* `tile_size` range: 32 to 256
* `tile_stride` range: 16 to 128
* `tiling_mode` restricted to: `both`, `horizontal`, `vertical`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/index.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Model API Reference

> Complete API reference for fal.ai's image, video, audio, vision, and 3D generation models on fal.ai.

API reference for top models on fal.ai — complete input/output schemas, code examples in Python, JavaScript, and cURL, plus real prompt-and-output examples.

Whether you're generating images with FLUX or Nano Banana, creating videos with Seedance or Kling, synthesizing audio with ElevenLabs, or building 3D assets — find the full API documentation for each endpoint below.

<Card title="Explore All Models" icon="grid" href="https://fal.ai/models">
  Browse and try all models interactively on fal.ai
</Card>

## Models by Category

<CardGroup cols={2}>
  <Card title="Video Generation API" href="/model-api-reference/video-generation-api/overview">
    Generate videos from text prompts or images using cutting-edge video generation models. 59 models documented.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a9460e7/626QXDcTbiOI5I3LPidrR_1ae86d7b0fbb47b3b6d1a41e7fc00956.jpg" alt="Video Generation example" noZoom />
    </Frame>
  </Card>

  <Card title="Image Generation API" href="/model-api-reference/image-generation-api/overview">
    Generate and edit images using state-of-the-art diffusion and transformer models. 59 models documented.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a900b9e/ptbZcVWIQ_fXGGHfv8Zez_0ea5ca41bdf143a29e21e30a53120672.jpg" alt="Image Generation example" noZoom />
    </Frame>
  </Card>

  <Card title="Audio API" href="/model-api-reference/audio-api/overview">
    Models for audio processing including text-to-speech, speech-to-text, voice cloning, and music generation.. 5 models documented.

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/whisper.jpg" alt="Audio example" noZoom />
    </Frame>
  </Card>

  <Card title="Vision API" href="/model-api-reference/vision-api/overview">
    Models for understanding and analyzing images, including captioning, visual question answering, and object detection.. 3 models documented.

    <Frame>
      <img src="https://v3b.fal.media/files/b/penguin/v-wl5CGbHxNVatcGXntIY_e14c7922d88348769a90469d1c206501.jpg" alt="Vision example" noZoom />
    </Frame>
  </Card>

  <Card title="3D API" href="/model-api-reference/3d-api/overview">
    Generate 3D assets from text or images using AI models. 6 models documented.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a87573c/DwQCx7YBl36dnFSHaU8OT_bfc26b64d210462489530b5d5d5d98e1.jpg" alt="3D example" noZoom />
    </Frame>
  </Card>
</CardGroup>

## Getting Started

New to fal.ai? Check out these resources:

* [Model APIs Overview](/documentation/model-apis/overview) — How to call model APIs
* [Authentication](/documentation/authentication) — Set up your API key
* [Explore Models](https://fal.ai/models) — Browse and try models interactively
* [fal.ai Pricing](https://fal.ai/pricing) — Pricing details for all models


# https://fal.ai/docs/model-api-reference/video-generation-api/birefnet-v2.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Birefnet V2 API

> API reference for Birefnet V2. Video background removal version of bilateral reference framework (BiRefNet) for high-resolution dichotomous image segmentation (DIS)

**Endpoint:** `POST https://fal.run/fal-ai/birefnet/v2/video`
**Endpoint ID:** `fal-ai/birefnet/v2/video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/birefnet/v2/video/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/birefnet/v2/video",
      arguments={
          "video_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-video-input.mp4"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/birefnet/v2/video", {
    input: {
        video_url: "https://storage.googleapis.com/falserverless/example_inputs/birefnet-video-input.mp4"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/birefnet/v2/video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "video_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-video-input.mp4"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="model" type="ModelEnum" default="General Use (Light)">
  Model to use for background removal.
  The 'General Use (Light)' model is the original model used in the BiRefNet repository.
  The 'General Use (Light 2K)' model is the original model used in the BiRefNet repository but trained with 2K images.
  The 'General Use (Heavy)' model is a slower but more accurate model.
  The 'Matting' model is a model trained specifically for matting images.
  The 'Portrait' model is a model trained specifically for portrait images.
  The 'General Use (Dynamic)' model supports dynamic resolutions from 256x256 to 2304x2304.
  The 'General Use (Light)' model is recommended for most use cases.

  The corresponding models are as follows:

  * 'General Use (Light)': BiRefNet
  * 'General Use (Light 2K)': BiRefNet\_lite-2K
  * 'General Use (Heavy)': BiRefNet\_lite
  * 'Matting': BiRefNet-matting
  * 'Portrait': BiRefNet-portrait
  * 'General Use (Dynamic)': BiRefNet\_dynamic Default value: `"General Use (Light)"`

  Possible values: `General Use (Light)`, `General Use (Light 2K)`, `General Use (Heavy)`, `Matting`, `Portrait`, `General Use (Dynamic)`
</ParamField>

<ParamField body="operating_resolution" type="OperatingResolutionEnum" default="1024x1024">
  The resolution to operate on. The higher the resolution, the more accurate the output will be for high res input images. The '2304x2304' option is only available for the 'General Use (Dynamic)' model. Default value: `"1024x1024"`

  Possible values: `1024x1024`, `2048x2048`, `2304x2304`
</ParamField>

<ParamField body="output_mask" type="boolean" default="false">
  Whether to output the mask used to remove the background
</ParamField>

<ParamField body="refine_foreground" type="boolean" default="true">
  Whether to refine the foreground using the estimated mask Default value: `true`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

<ParamField body="video_url" type="string" required>
  URL of the video to remove background from
</ParamField>

<ParamField body="video_output_type" type="VideoOutputTypeEnum" default="X264 (.mp4)">
  The output type of the generated video. Default value: `"X264 (.mp4)"`

  Possible values: `X264 (.mp4)`, `VP9 (.webm)`, `PRORES4444 (.mov)`, `GIF (.gif)`
</ParamField>

<ParamField body="video_quality" type="VideoQualityEnum" default="high">
  The quality of the generated video. Default value: `"high"`

  Possible values: `low`, `medium`, `high`, `maximum`
</ParamField>

<ParamField body="video_write_mode" type="VideoWriteModeEnum" default="balanced">
  The write mode of the generated video. Default value: `"balanced"`

  Possible values: `fast`, `balanced`, `small`
</ParamField>

### Output Schema

<ParamField body="video" type="VideoFile" required>
  Video with background removed
</ParamField>

<ParamField body="mask_video" type="VideoFile">
  Mask used to remove the background
</ParamField>

### Input Example

```json theme={null}
{
  "model": "General Use (Light)",
  "operating_resolution": "1024x1024",
  "output_mask": false,
  "refine_foreground": true,
  "sync_mode": false,
  "video_url": "https://storage.googleapis.com/falserverless/example_inputs/birefnet-video-input.mp4",
  "video_output_type": "X264 (.mp4)",
  "video_quality": "high",
  "video_write_mode": "balanced"
}
```

### Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/webm",
    "duration": 8,
    "file_name": "birefnet-video-output.webm",
    "fps": 24,
    "height": 1080,
    "num_frames": 192,
    "url": "https://storage.googleapis.com/falserverless/example_outputs/birefnet-video-output.webm",
    "width": 1920
  }
}
```

## Limitations

* `model` restricted to: `General Use (Light)`, `General Use (Light 2K)`, `General Use (Heavy)`, `Matting`, `Portrait`, `General Use (Dynamic)`
* `operating_resolution` restricted to: `1024x1024`, `2048x2048`, `2304x2304`
* `video_output_type` restricted to: `X264 (.mp4)`, `VP9 (.webm)`, `PRORES4444 (.mov)`, `GIF (.gif)`
* `video_quality` restricted to: `low`, `medium`, `high`, `maximum`
* `video_write_mode` restricted to: `fast`, `balanced`, `small`


# https://fal.ai/docs/model-api-reference/video-generation-api/bria-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bria Video API

> API reference for Bria Video. Automatically remove backgrounds from videos -perfect for creating clean, professional content without a green screen.

<Tabs>
  <Tab title="Background Removal">
    **Endpoint:** `POST https://fal.run/bria/video/background-removal`
    **Endpoint ID:** `bria/video/background-removal`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/video/background-removal/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/video/background-removal",
          arguments={
              "video_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/rmbg_tests/videos/5586521-uhd_3840_2160_25fps_original.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/video/background-removal", {
        input: {
            video_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/rmbg_tests/videos/5586521-uhd_3840_2160_25fps_original.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/video/background-removal \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "video_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/rmbg_tests/videos/5586521-uhd_3840_2160_25fps_original.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="video_url" type="string" required>
      Input video to remove background from. Size should be less than 4000x4000 and duration less than 30s.
    </ParamField>

    <ParamField body="background_color" type="BackgroundColorEnum" default="Black">
      Background color. Options: Transparent, Black, White, Gray, Red, Green, Blue, Yellow, Cyan, Magenta, Orange. Default value: `"Black"`

      Possible values: `Transparent`, `Black`, `White`, `Gray`, `Red`, `Green`, `Blue`, `Yellow`, `Cyan`, `Magenta`, `Orange`
    </ParamField>

    <ParamField body="output_container_and_codec" type="OutputContainerAndCodecEnum" default="webm_vp9">
      Output container and codec. Options: mp4\_h265, mp4\_h264, webm\_vp9, mov\_h265, mov\_proresks, mkv\_h265, mkv\_h264, mkv\_vp9, gif. Default value: `"webm_vp9"`

      Possible values: `mp4_h265`, `mp4_h264`, `webm_vp9`, `mov_h265`, `mov_proresks`, `mkv_h265`, `mkv_h264`, `mkv_vp9`, `gif`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="Video | File" required>
      Video with removed background and audio.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "video_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/rmbg_tests/videos/5586521-uhd_3840_2160_25fps_original.mp4",
      "background_color": "Black",
      "output_container_and_codec": "webm_vp9"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019
      }
    }
    ```
  </Tab>

  <Tab title="Increase Resolution">
    **Endpoint:** `POST https://fal.run/bria/video/increase-resolution`
    **Endpoint ID:** `bria/video/increase-resolution`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bria/video/increase-resolution/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bria/video/increase-resolution",
          arguments={
              "video_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/video_increase_res/3446608-sd_426_240_25fps.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bria/video/increase-resolution", {
        input: {
            video_url: "https://bria-datasets.s3.us-east-1.amazonaws.com/video_increase_res/3446608-sd_426_240_25fps.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bria/video/increase-resolution \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "video_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/video_increase_res/3446608-sd_426_240_25fps.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="video_url" type="string" required>
      Input video to increase resolution. Size should be less than 7680,4320 and duration less than 30s.
    </ParamField>

    <ParamField body="desired_increase" type="DesiredIncreaseEnum" default="2">
      desired\_increase factor. Options: 2x, 4x. Default value: `"2"`

      Possible values: `2`, `4`
    </ParamField>

    <ParamField body="output_container_and_codec" type="OutputContainerAndCodecEnum" default="webm_vp9">
      Output container and codec. Options: mp4\_h265, mp4\_h264, webm\_vp9, mov\_h265, mov\_proresks, mkv\_h265, mkv\_h264, mkv\_vp9, gif. Default value: `"webm_vp9"`

      Possible values: `mp4_h265`, `mp4_h264`, `webm_vp9`, `mov_h265`, `mov_proresks`, `mkv_h265`, `mkv_h264`, `mkv_vp9`, `gif`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="Video | File" required>
      Video with removed background and audio.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "video_url": "https://bria-datasets.s3.us-east-1.amazonaws.com/video_increase_res/3446608-sd_426_240_25fps.mp4",
      "desired_increase": "2",
      "output_container_and_codec": "webm_vp9"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Bria RMBG 2.0](/model-api-reference/image-generation-api/bria-rmbg-2.0) — Image Generation
* [Bria Expand Image](/model-api-reference/image-generation-api/bria-expand-image) — Image Generation
* [Bria Eraser](/model-api-reference/image-generation-api/bria-eraser) — Image Generation
* [Bria Product Shot](/model-api-reference/image-generation-api/bria-product-shot) — Image Generation
* [Bria Background Replace](/model-api-reference/image-generation-api/bria-background-replace) — Image Generation
* [Bria GenFill](/model-api-reference/image-generation-api/bria-genfill) — Image Generation
* [Replace Background](/model-api-reference/image-generation-api/replace-background) — Image Generation
* [Video](/model-api-reference/video-generation-api/video) — Video Generation
* [Bria Text-to-Image HD](/model-api-reference/image-generation-api/bria-text-to-image-hd) — Image Generation
* [Bria Text-to-Image Base](/model-api-reference/image-generation-api/bria-text-to-image-base) — Image Generation
* [Embed Product](/model-api-reference/image-generation-api/embed-product) — Image Generation
* [Bria Text-to-Image Fast](/model-api-reference/image-generation-api/bria-text-to-image-fast) — Image Generation

## Limitations

* `desired_increase` restricted to: `2`, `4`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-dreamactor.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Dreamactor API

> API reference for Bytedance Dreamactor. Transfer motion from a video to characters in an image using Dreamactor v2. Great performance for non-human and multiple characters

**Endpoint:** `POST https://fal.run/fal-ai/bytedance/dreamactor/v2`
**Endpoint ID:** `fal-ai/bytedance/dreamactor/v2`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/dreamactor/v2/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bytedance/dreamactor/v2",
      arguments={
          "image_url": "https://v3b.fal.media/files/b/0a8d6292/E9WNRJh8K8DF9lSV0bkXs_image.png",
          "video_url": "https://v3b.fal.media/files/b/0a8d633f/u5Ye7jXL0Cfo0ijz5M6YY_input_example_dreamactor.mp4"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bytedance/dreamactor/v2", {
    input: {
        image_url: "https://v3b.fal.media/files/b/0a8d6292/E9WNRJh8K8DF9lSV0bkXs_image.png",
        video_url: "https://v3b.fal.media/files/b/0a8d633f/u5Ye7jXL0Cfo0ijz5M6YY_input_example_dreamactor.mp4"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bytedance/dreamactor/v2 \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://v3b.fal.media/files/b/0a8d6292/E9WNRJh8K8DF9lSV0bkXs_image.png",
    "video_url": "https://v3b.fal.media/files/b/0a8d633f/u5Ye7jXL0Cfo0ijz5M6YY_input_example_dreamactor.mp4"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="image_url" type="string" required>
  The URL of the reference image to animate. Supports real people, animation, pets, etc. Format: jpeg, jpg or png. Max size: 4.7 MB. Resolution: between 480x480 and 1920x1080 (larger images will be proportionally reduced).
</ParamField>

<ParamField body="video_url" type="string" required>
  The URL of the driving template video providing motion, facial expressions, and lip movement reference. Max duration: 30 seconds. Format: mp4, mov or webm. Resolution: between 200x200 and 2048x1440. Supports full face and body driving.
</ParamField>

<ParamField body="trim_first_second" type="boolean" default="true">
  Whether to crop the first second of the output video. The output has a 1-second transition at the beginning; enable this to remove it. Default value: `true`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  Generated video file.
</ParamField>

### Input Example

```json theme={null}
{
  "image_url": "https://v3b.fal.media/files/b/0a8d6292/E9WNRJh8K8DF9lSV0bkXs_image.png",
  "video_url": "https://v3b.fal.media/files/b/0a8d633f/u5Ye7jXL0Cfo0ijz5M6YY_input_example_dreamactor.mp4",
  "trim_first_second": true
}
```

### Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3b.fal.media/files/b/0a8d6313/ONsZwYeJrFqi1W1jbnfYF_9HU7tPvX1hUlMMxXCepTz_video%20(1)%20(1).mp4"
  }
}
```


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-omnihuman.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Omnihuman API

> API reference for Bytedance Omnihuman. OmniHuman generates video using an image of a human figure paired with an audio file. It produces vivid, high-quality videos where the character’s emotions and m

<Tabs>
  <Tab title="Omnihuman">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/omnihuman`
    **Endpoint ID:** `fal-ai/bytedance/omnihuman`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/omnihuman/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/omnihuman",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman.png",
              "audio_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_audio.mp3"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/omnihuman", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/omnihuman.png",
            audio_url: "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_audio.mp3"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/omnihuman \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman.png",
        "audio_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_audio.mp3"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image used to generate the video
    </ParamField>

    <ParamField body="audio_url" type="string" required>
      The URL of the audio file to generate the video. Audio must be under 30s long.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="duration" type="float" required>
      Duration of audio input/video output as used for billing.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman.png",
      "audio_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_audio.mp3"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_outputs/omnihuman_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="V1.5">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/omnihuman/v1.5`
    **Endpoint ID:** `fal-ai/bytedance/omnihuman/v1.5`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/omnihuman/v1.5/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/omnihuman/v1.5",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_image.png",
              "audio_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_audio.mp3"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/omnihuman/v1.5", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_image.png",
            audio_url: "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_audio.mp3"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/omnihuman/v1.5 \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_image.png",
        "audio_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_audio.mp3"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string">
      The text prompt used to guide the video generation.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The URL of the image used to generate the video
    </ParamField>

    <ParamField body="audio_url" type="string" required>
      The URL of the audio file to generate the video. Audio must be under 30s long for 1080p generation and under 60s long for 720p generation.
    </ParamField>

    <ParamField body="turbo_mode" type="boolean" default="false">
      Generate a video at a faster rate with a slight quality trade-off.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1080p">
      The resolution of the generated video. Defaults to 1080p. 720p generation is faster and higher in quality. 1080p generation is limited to 30s audio and 720p generation is limited to 60s audio. Default value: `"1080p"`

      Possible values: `720p`, `1080p`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="duration" type="float" required>
      Duration of audio input/video output as used for billing.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_image.png",
      "audio_url": "https://storage.googleapis.com/falserverless/example_inputs/omnihuman_v15_input_audio.mp3",
      "turbo_mode": false,
      "resolution": "1080p"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_outputs/omnihuman_v15_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

ByteDance's OmniHuman model generates **audio-synchronized videos** from a single reference image at \$0.14 per second of output. With specialized lip-sync precision, the model trained on 18,700 hours of human motion data to maintain tight correlation between audio input and character movement. Built for content creators who need realistic talking head videos without motion capture equipment.

**Use Cases:** Social Media Content | Product Demos with Presenters | Educational Video Production

***

## Performance

At \$0.14 per second, OmniHuman sits in the mid-range for image-to-video generation on fal, trading cost for specialized **audio-sync capabilities** that generic models don't prioritize.

| Metric                 | Result                                                                                                                                                                                                                                                  | Context                                                        |
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------- |
| **Audio Sync Quality** | Tight emotion/movement correlation                                                                                                                                                                                                                      | Trained on 18,700 hours of human motion data                   |
| **Max Audio Duration** | 30 seconds                                                                                                                                                                                                                                              | Hard limit enforced at API level                               |
| **Cost per Second**    | \$0.14                                                                                                                                                                                                                                                  | Billed on actual audio/video duration                          |
| **Output Quality**     | High-fidelity video                                                                                                                                                                                                                                     | Specialized for human figure animation                         |
| **Related Endpoints**  | [OmniHuman v1.5](https://fal.ai/models/fal-ai/bytedance/omnihuman/v1.5), [Seedance Pro](https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/image-to-video), [Seedance Lite](https://fal.ai/models/fal-ai/bytedance/seedance/v1/lite/image-to-video) | ByteDance family variants for different quality/cost tradeoffs |

***

## Audio-First Video Generation

OmniHuman flips the standard image-to-video workflow by making audio the **primary control signal** rather than text prompts or motion parameters. Where most models animate based on text descriptions or keyframes, this architecture analyzes audio waveforms to drive facial expressions, lip movements, and body language simultaneously.

**What this means for you:**

* **Natural speech synchronization:** Upload any audio file under 30 seconds and get matching lip movements without manual keyframe adjustment or phoneme mapping

* **Emotion-driven animation:** The model interprets audio tone and pacing to generate corresponding facial expressions and body gestures, not just mouth shapes

* **Single-image input:** Start with one reference photo rather than building character rigs or providing multiple angles

* **Production-ready output:** High-fidelity video maintains visual consistency across the full duration without drift or quality degradation

***

## Technical Specifications

| Spec                   | Details                                                                          |
| :--------------------- | :------------------------------------------------------------------------------- |
| **Architecture**       | OmniHuman                                                                        |
| **Input Formats**      | Single image (JPEG, PNG, WebP, GIF, AVIF) + audio file (MP3, OGG, WAV, M4A, AAC) |
| **Output Formats**     | MP4 video                                                                        |
| **Max Audio Duration** | 30 seconds                                                                       |
| **License**            | Commercial use allowed via fal partnership                                       |

[API Documentation](https://fal.ai/models/fal-ai/bytedance/omnihuman/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

**Bytedance OmniHuman v1.5** ($0.14/sec) – [OmniHuman v1.5](https://fal.ai/models/fal-ai/bytedance/omnihuman/v1.5) offers enhanced audio processing and **improved motion quality** at the same $0.14 per second price point. The original OmniHuman remains viable for projects where the current quality threshold meets requirements without needing v1.5's refinements.

**Seedance 1.0 Pro** (\$0.14/sec) – OmniHuman prioritizes **audio-driven human animation** with specialized lip-sync capabilities. [Seedance Pro](https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/image-to-video) trades audio control for broader creative motion generation across any subject type, ideal for product animations or scene transitions where audio sync isn't critical.

**Seedance 1.0 Lite** ($0.08/sec) – [Seedance Lite](https://fal.ai/models/fal-ai/bytedance/seedance/v1/lite/image-to-video) delivers 43% cost savings ($0.08 vs \$0.14 per second) by simplifying motion generation **without audio processing**. Best for budget-conscious projects that can handle reduced quality or don't require speech synchronization.

## Limitations

* `resolution` restricted to: `720p`, `1080p`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-2.0-fast.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance 2.0 Fast API

> API reference for Bytedance Seedance 2.0 Fast. ByteDance's most advanced text-to-video model, fast tier. Lower latency and cost with cinematic output, native audio, multi-shot editing, and director-le

<Tabs>
  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/bytedance/seedance-2.0/fast/text-to-video`
    **Endpoint ID:** `bytedance/seedance-2.0/fast/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bytedance/seedance-2.0/fast/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bytedance/seedance-2.0/fast/text-to-video",
          arguments={
              "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bytedance/seedance-2.0/fast/text-to-video", {
        input: {
            prompt: "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bytedance/seedance-2.0/fast/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      }'
      ```
    </CodeGroup>

    ## Examples

    > A hyper-realistic medium shot of two women in their late 20s to early 30s sitting cross-legged on opposite ends of a deep charcoal sectional sofa in a cozy, lived-in apartment during a lazy Sunday afternoon, captured with a handheld camera feel as if a third friend is casually filming them; the firs...

    <video src="https://v3b.fal.media/files/b/0a959a2a/EaIW2xdGlq41Ab1codNXE_video.mp4" controls width="100%" />

    > Ultra high-end commercial product shot, photorealistic, 8K, cinematic lighting, macro detail, shallow depth of field, premium advertising aesthetic, dark chocolate bar snapping in half in slow motion, side macro, cocoa powder dust drifting, warm key light, deep brown backdrop, studio-grade color gra...

    <video src="https://v3b.fal.media/files/b/0a959996/WHdnS_NXRnLTPEOmjZ6ro_video.mp4" controls width="100%" />

    > A breathtaking cinematic aerial sequence following an original majestic parrot flying freely above an immense tropical jungle at golden hour. The camera stays locked in a fast, fluid, graceful follow shot behind and around the bird, gliding effortlessly through the air with a sense of wonder, speed,...

    <video src="https://v3b.fal.media/files/b/0a9499d5/xRH9GuSLwaWggKgkeSb_Q_video.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for balance. Default value: `"720p"`

      Possible values: `480p`, `720p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="auto">
      Duration of the video in seconds. Supports 4 to 15 seconds, or auto to let the model decide based on the prompt. Default value: `"auto"`

      Possible values: `auto`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Use 16:9 for landscape, 9:16 for portrait/vertical, 1:1 for square, 21:9 for ultrawide cinematic, or auto to let the model decide. Default value: `"auto"`

      Possible values: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate synchronized audio for the video, including sound effects, ambient sounds, and lip-synced speech. The cost of video generation is the same regardless of whether audio is generated or not. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed for reproducibility. Note that results may still vary slightly even with the same seed.
    </ParamField>

    <ParamField body="end_user_id" type="string">
      The unique user ID of the end user.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video file.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      The seed used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
      "resolution": "720p",
      "duration": "auto",
      "aspect_ratio": "auto",
      "generate_audio": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_outputs/bytedance/seedance_2/output.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>

  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/bytedance/seedance-2.0/fast/image-to-video`
    **Endpoint ID:** `bytedance/seedance-2.0/fast/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bytedance/seedance-2.0/fast/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bytedance/seedance-2.0/fast/image-to-video",
          arguments={
              "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
              "image_url": "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bytedance/seedance-2.0/fast/image-to-video", {
        input: {
            prompt: "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
            image_url: "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bytedance/seedance-2.0/fast/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
        "image_url": "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
      }'
      ```
    </CodeGroup>

    ## Examples

    > Ultra high-end commercial product shot, photorealistic, 8K, cinematic lighting, macro detail, shallow depth of field, premium advertising aesthetic, crystal-cut perfume bottle catching prismatic light beams, slow orbit, hard sunlight through venetian blinds, warm sandstone wall background, studio-gr...

    <video src="https://v3b.fal.media/files/b/0a959949/4YjMSjuKAeIIOLFiGktEi_video.mp4" controls width="100%" />

    > A shimmering underwater stage is set as eight octopi glide into view, ready to perform graceful formations. Tentacles intertwine in perfect harmony, showcasing the elegance of synchronized movement. Delight and wonder fill the space as these intelligent sea creatures dance, revealing a captivating w\...

    <video src="https://v3b.fal.media/files/b/0a948ad6/F3LUFaihRZ3nClRH-DjM__video.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the desired motion and action for the video.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The URL of the starting frame image to animate. Supported formats: JPEG, PNG, WebP. Max 30 MB.
    </ParamField>

    <ParamField body="end_image_url" type="string">
      The URL of the image to use as the last frame of the video. When provided, the generated video will transition from the starting image to this ending image. Supported formats: JPEG, PNG, WebP. Max 30 MB.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for balance. Default value: `"720p"`

      Possible values: `480p`, `720p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="auto">
      Duration of the video in seconds. Supports 4 to 15 seconds, or auto to let the model decide based on the prompt. Default value: `"auto"`

      Possible values: `auto`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Use 16:9 for landscape, 9:16 for portrait/vertical, 1:1 for square, 21:9 for ultrawide cinematic, or auto to infer from the input image. Default value: `"auto"`

      Possible values: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate synchronized audio for the video, including sound effects, ambient sounds, and lip-synced speech. The cost of video generation is the same regardless of whether audio is generated or not. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed for reproducibility. Note that results may still vary slightly even with the same seed.
    </ParamField>

    <ParamField body="end_user_id" type="string">
      The unique user ID of the end user.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video file.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      The seed used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
      "image_url": "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg",
      "resolution": "720p",
      "duration": "auto",
      "aspect_ratio": "auto",
      "generate_audio": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_outputs/bytedance/seedance_2/output.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>

  <Tab title="Reference To Video">
    **Endpoint:** `POST https://fal.run/bytedance/seedance-2.0/fast/reference-to-video`
    **Endpoint ID:** `bytedance/seedance-2.0/fast/reference-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bytedance/seedance-2.0/fast/reference-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "bytedance/seedance-2.0/fast/reference-to-video",
          arguments={
              "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("bytedance/seedance-2.0/fast/reference-to-video", {
        input: {
            prompt: "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/bytedance/seedance-2.0/fast/reference-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      }'
      ```
    </CodeGroup>

    ## Examples

    > A hyper-realistic UGC-style medium close-up of a woman in her late 20s standing in her sunlit bedroom in front of a slightly messy bed with white linen sheets, filmed vertically as if she's holding her phone at arm's length for a TikTok or Instagram Reel; she has shoulder-length honey blonde waves, ...

    <video src="https://v3b.fal.media/files/b/0a959ac1/vVRE687-Tmi0f1mqmbpSz_video.mp4" controls width="100%" />

    > Beautiful fusion of these two scenes. Mills stand against a rugged coastline, their large wooden wheels turned by the relentless surge of tidal waves combined with a field of wildflowers bathed in soft sunlight transitions into where monarch butterflies take flight.

    <video src="https://v3b.fal.media/files/b/0a948b29/dWoaqkPO7UA6hlEQXjgyI_video.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images to guide video generation. Refer to them in the prompt as @Image1, @Image2, etc. Supported formats: JPEG, PNG, WebP. Max 30 MB per image. Up to 9 images. Total files across all modalities must not exceed 12.
    </ParamField>

    <ParamField body="video_urls" type="list<string>">
      Reference videos to guide video generation. Refer to them in the prompt as @Video1, @Video2, etc. Supported formats: MP4, MOV. Up to 3 videos, combined duration must be between 2 and 15 seconds, total size under 50 MB. Each video must be between \~480p (640x640) and \~720p (834x1112) in resolution.
    </ParamField>

    <ParamField body="audio_urls" type="list<string>">
      Reference audio to guide video generation. Refer to them in the prompt as @Audio1, @Audio2, etc. Supported formats: MP3, WAV. Up to 3 files, combined duration must not exceed 15 seconds. Max 15 MB per file.If audio is provided, at least one reference image or video is required.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for balance. Default value: `"720p"`

      Possible values: `480p`, `720p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="auto">
      Duration of the video in seconds. Supports 4 to 15 seconds, or auto to let the model decide based on the prompt. Default value: `"auto"`

      Possible values: `auto`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Use 16:9 for landscape, 9:16 for portrait/vertical, 1:1 for square, 21:9 for ultrawide cinematic, or auto to let the model decide. Default value: `"auto"`

      Possible values: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate synchronized audio for the video, including sound effects, ambient sounds, and lip-synced speech. The cost of video generation is the same regardless of whether audio is generated or not. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed for reproducibility. Note that results may still vary slightly even with the same seed.
    </ParamField>

    <ParamField body="end_user_id" type="string">
      The unique user ID of the end user.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video file.
    </ParamField>

    <ParamField body="seed" type="integer" required>
      The seed used for generation.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
      "image_urls": [
        "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
      ],
      "resolution": "720p",
      "duration": "auto",
      "aspect_ratio": "auto",
      "generate_audio": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_outputs/bytedance/seedance_2/output.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>
</Tabs>

## Related

* [Seedance 2.0 Text to Video API](/model-api-reference/video-generation-api/seedance-2.0-text-to-video-api) — Video Generation
* [Seedance 2 Image to Video](/model-api-reference/video-generation-api/seedance-2-image-to-video) — Video Generation
* [Seedance 2 Reference to Video](/model-api-reference/video-generation-api/seedance-2-reference-to-video) — Video Generation
* [Seedance 2.0 Fast Image to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-image-to-video) — Video Generation
* [Seedance 2.0 Fast Reference to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-reference-to-video) — Video Generation
* [Seedance 2.0 Fast Text to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-text-to-video) — Video Generation

## Limitations

* `resolution` restricted to: `480p`, `720p`
* `aspect_ratio` restricted to: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-2.0-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance 2.0 Image To Video API

> API reference for Bytedance Seedance 2.0 Image To Video. ByteDance's most advanced image-to-video model. Animate still images into cinematic video with synchronized audio, start and end frame control,

**Endpoint:** `POST https://fal.run/bytedance/seedance-2.0/image-to-video`
**Endpoint ID:** `bytedance/seedance-2.0/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bytedance/seedance-2.0/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bytedance/seedance-2.0/image-to-video",
      arguments={
          "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
          "image_url": "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bytedance/seedance-2.0/image-to-video", {
    input: {
        prompt: "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
        image_url: "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/bytedance/seedance-2.0/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
    "image_url": "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
  }'
  ```
</CodeGroup>

## Examples

> Ultra high-end commercial product shot, photorealistic, 8K, cinematic lighting, macro detail, shallow depth of field, premium advertising aesthetic, VR headset suspended by invisible wires against a deep navy backdrop, slow vertical tilt down across the visor, magenta and cyan accent lighting, studi...

<video src="https://v3b.fal.media/files/b/0a95998b/Y2JKGGVWMyjhMKf_FoqS5_video.mp4" controls width="100%" />

> Glimpses of light illuminate Jupiter's polar regions, showcasing the auroras. The visuals simply present the glowing displays, revealing their location and radiant nature. It is a direct view of space phenomena on Jupiter's poles.

<video src="https://v3b.fal.media/files/b/0a948ae5/wUeGPTJd_2zh_5MAPeSDh_video.mp4" controls width="100%" />

## Related

* [Seedance 2.0 Text to Video API](/model-api-reference/video-generation-api/seedance-2.0-text-to-video-api) — Video Generation
* [Seedance 2 Reference to Video](/model-api-reference/video-generation-api/seedance-2-reference-to-video) — Video Generation
* [Seedance 2.0 Fast Text to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-text-to-video) — Video Generation
* [Seedance 2.0 Fast Image to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-image-to-video) — Video Generation
* [Seedance 2.0 Fast Reference to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-reference-to-video) — Video Generation

## Capabilities

* Text prompt input
* Image input
* Duration control
* Aspect ratio control
* Reproducible generation (seed)

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt describing the desired motion and action for the video.
</ParamField>

<ParamField body="image_url" type="string" required>
  The URL of the starting frame image to animate. Supported formats: JPEG, PNG, WebP. Max 30 MB.
</ParamField>

<ParamField body="end_image_url" type="string">
  The URL of the image to use as the last frame of the video. When provided, the generated video will transition from the starting image to this ending image. Supported formats: JPEG, PNG, WebP. Max 30 MB.
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="720p">
  Video resolution - 480p for faster generation, 720p for balance. Default value: `"720p"`

  Possible values: `480p`, `720p`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="auto">
  Duration of the video in seconds. Supports 4 to 15 seconds, or auto to let the model decide based on the prompt. Default value: `"auto"`

  Possible values: `auto`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
  The aspect ratio of the generated video. Use 16:9 for landscape, 9:16 for portrait/vertical, 1:1 for square, 21:9 for ultrawide cinematic, or auto to infer from the input image. Default value: `"auto"`

  Possible values: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate synchronized audio for the video, including sound effects, ambient sounds, and lip-synced speech. The cost of video generation is the same regardless of whether audio is generated or not. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  Random seed for reproducibility. Note that results may still vary slightly even with the same seed.
</ParamField>

<ParamField body="end_user_id" type="string">
  The unique user ID of the end user.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video file.
</ParamField>

<ParamField body="seed" type="integer" required>
  The seed used for generation.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
  "image_url": "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg",
  "resolution": "720p",
  "duration": "auto",
  "aspect_ratio": "auto",
  "generate_audio": true
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_outputs/bytedance/seedance_2/output.mp4"
  },
  "seed": 42
}
```

## Limitations

* `resolution` restricted to: `480p`, `720p`
* `aspect_ratio` restricted to: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-2.0-reference-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance 2.0 Reference To Video API

> API reference for Bytedance Seedance 2.0 Reference To Video. ByteDance's most advanced reference-to-video model. Generate video from up to 9 images, 3 videos, and 3 audio clips with native audio and c

**Endpoint:** `POST https://fal.run/bytedance/seedance-2.0/reference-to-video`
**Endpoint ID:** `bytedance/seedance-2.0/reference-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bytedance/seedance-2.0/reference-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bytedance/seedance-2.0/reference-to-video",
      arguments={
          "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bytedance/seedance-2.0/reference-to-video", {
    input: {
        prompt: "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/bytedance/seedance-2.0/reference-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
  }'
  ```
</CodeGroup>

## Examples

> Room is slowly getting filled from empty state to fully organized with furnitures. Camera is fixed timelapse.

<video src="https://v3b.fal.media/files/b/0a959a18/ojveMSkwmwthBKa4b-lIF_video.mp4" controls width="100%" />

> Sunlight filters into a crystalline cave, illuminating formations that hum softly. Air currents brush through the formations, their gentle vibrations creating ethereal melodies throughout the cavern. The serene simplicity of the cave reveals nature's delicate, musical architecture where tiny cleaner...

<video src="https://v3b.fal.media/files/b/0a948aed/kLlLreInOcDz2BkoGxtxb_video.mp4" controls width="100%" />

## Related

* [Seedance 2.0 Text to Video API](/model-api-reference/video-generation-api/seedance-2.0-text-to-video-api) — Video Generation
* [Seedance 2 Image to Video](/model-api-reference/video-generation-api/seedance-2-image-to-video) — Video Generation
* [Seedance 2.0 Fast Text to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-text-to-video) — Video Generation
* [Seedance 2.0 Fast Image to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-image-to-video) — Video Generation
* [Seedance 2.0 Fast Reference to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-reference-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control
* Reproducible generation (seed)

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt used to generate the video.
</ParamField>

<ParamField body="image_urls" type="list<string>">
  Reference images to guide video generation. Refer to them in the prompt as @Image1, @Image2, etc. Supported formats: JPEG, PNG, WebP. Max 30 MB per image. Up to 9 images. Total files across all modalities must not exceed 12.
</ParamField>

<ParamField body="video_urls" type="list<string>">
  Reference videos to guide video generation. Refer to them in the prompt as @Video1, @Video2, etc. Supported formats: MP4, MOV. Up to 3 videos, combined duration must be between 2 and 15 seconds, total size under 50 MB. Each video must be between \~480p (640x640) and \~720p (834x1112) in resolution.
</ParamField>

<ParamField body="audio_urls" type="list<string>">
  Reference audio to guide video generation. Refer to them in the prompt as @Audio1, @Audio2, etc. Supported formats: MP3, WAV. Up to 3 files, combined duration must not exceed 15 seconds. Max 15 MB per file.If audio is provided, at least one reference image or video is required.
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="720p">
  Video resolution - 480p for faster generation, 720p for balance. Default value: `"720p"`

  Possible values: `480p`, `720p`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="auto">
  Duration of the video in seconds. Supports 4 to 15 seconds, or auto to let the model decide based on the prompt. Default value: `"auto"`

  Possible values: `auto`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
  The aspect ratio of the generated video. Use 16:9 for landscape, 9:16 for portrait/vertical, 1:1 for square, 21:9 for ultrawide cinematic, or auto to let the model decide. Default value: `"auto"`

  Possible values: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate synchronized audio for the video, including sound effects, ambient sounds, and lip-synced speech. The cost of video generation is the same regardless of whether audio is generated or not. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  Random seed for reproducibility. Note that results may still vary slightly even with the same seed.
</ParamField>

<ParamField body="end_user_id" type="string">
  The unique user ID of the end user.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video file.
</ParamField>

<ParamField body="seed" type="integer" required>
  The seed used for generation.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
  "image_urls": [
    "https://v3b.fal.media/files/b/0a8eba37/Cqg-4Uwzyz4DELfceT1CF_a17e588773ec45b1a9e6f100a787b80b.jpg"
  ],
  "resolution": "720p",
  "duration": "auto",
  "aspect_ratio": "auto",
  "generate_audio": true
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_outputs/bytedance/seedance_2/output.mp4"
  },
  "seed": 42
}
```

## Limitations

* `resolution` restricted to: `480p`, `720p`
* `aspect_ratio` restricted to: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-2.0-text-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance 2.0 Text To Video API

> API reference for Bytedance Seedance 2.0 Text To Video. ByteDance's most advanced text-to-video model. Cinematic output with native audio, multi-shot editing, real-world physics, and director-level ca

**Endpoint:** `POST https://fal.run/bytedance/seedance-2.0/text-to-video`
**Endpoint ID:** `bytedance/seedance-2.0/text-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/bytedance/seedance-2.0/text-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bytedance/seedance-2.0/text-to-video",
      arguments={
          "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bytedance/seedance-2.0/text-to-video", {
    input: {
        prompt: "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/bytedance/seedance-2.0/text-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
  }'
  ```
</CodeGroup>

## Examples

> ltra high-end editorial photography, photorealistic, 8K, razor-sharp detail, perfect skin texture with natural pores and subsurface scattering, cinematic lighting, shot on medium format, Portrait: 31-year-old Black British architect in a cream blazer, standing in a brutalist concrete stairwell, soft...

<video src="https://v3b.fal.media/files/b/0a959980/O8bR1l3Z8tvZiNDNVUBDM_video.mp4" controls width="100%" />

> A shimmering soap film stretches across a circular frame, catching the light. The secrets to achieving a perfectly spherical bubble are unveiled as the surface tension and air pressure work in harmony. This exploration reveals the simple yet elegant physics at play, creating fleeting moments of irid...

<video src="https://v3b.fal.media/files/b/0a948b06/f_MwnfesPZNuFJnIKra1i_video.mp4" controls width="100%" />

ByteDance's most advanced video generation model. Generate cinematic video with native audio, real-world physics, and director-level camera control, all in a single pass.

`bytedance/seedance-2.0`

***

## Overview

Seedance 2.0 is built on a unified multimodal architecture that accepts text, images, video clips, and audio as inputs and produces coherent, audio-synchronized video output. Audio and video are generated together natively, no post-production layering.

***

## API Endpoints

| Endpoint                  | Model ID                                         |
| ------------------------- | ------------------------------------------------ |
| Text to Video             | `bytedance/seedance-2.0/text-to-video`           |
| Text to Video (Fast)      | `bytedance/seedance-2.0/fast/text-to-video`      |
| Image to Video            | `bytedance/seedance-2.0/image-to-video`          |
| Image to Video (Fast)     | `bytedance/seedance-2.0/fast/image-to-video`     |
| Reference to Video        | `bytedance/seedance-2.0/reference-to-video`      |
| Reference to Video (Fast) | `bytedance/seedance-2.0/fast/reference-to-video` |

Standard endpoints prioritize maximum quality. Fast endpoints offer lower latency and cost for production workloads.

***

## Pricing

| Endpoint             | Price             |
| -------------------- | ----------------- |
| 720p with audio      | \$0.3034 / second |
| 720p fast with audio | \$0.2419 / second |

***

## What's new in 2.0

**Multimodal reference inputs.** Combine up to 9 images, 3 video clips, and 3 audio files in a single generation via the reference-to-video endpoint. Reference them in your prompt using `[Image1]`, `[Video1]`, `[Audio1]`, etc.

**Better motion and physics.** More realistic rendering of complex interactions — sports, dancing, fighting, object collisions, and more.

**Video editing and extension.** Provide a reference video and describe what to change, or describe what should happen next to extend it.

**Intelligent duration.** Set `duration` to `"auto"` and the model picks the optimal length for the content.

**Adaptive aspect ratio.** Set `aspect_ratio` to `"auto"` and the model chooses the best fit based on your inputs.

***

## Usage

Install the client:

```bash theme={null}
npm install --save @fal-ai/client
```

> **Note:** `@fal-ai/serverless-client` is deprecated. Use `@fal-ai/client` instead.

### Python

```python theme={null}
import fal_client

result = fal_client.subscribe(
    "bytedance/seedance-2.0/text-to-video",
    arguments={
        "prompt": "A spear-wielding warrior clashes with a dual-blade fighter in a maple leaf forest. Autumn leaves scatter on each impact.",
        "duration": "5",
        "resolution": "720p",
        "aspect_ratio": "16:9",
    }
)

print(result["video"]["url"])
```

### JavaScript

```javascript theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("bytedance/seedance-2.0/text-to-video", {
  input: {
    prompt: "A spear-wielding warrior clashes with a dual-blade fighter in a maple leaf forest. Autumn leaves scatter on each impact.",
    duration: "5",
    resolution: "720p",
    aspect_ratio: "16:9",
  },
  logs: true,
  onQueueUpdate: (update) => {
    if (update.status === "IN_PROGRESS") {
      update.logs.map((log) => log.message).forEach(console.log);
    }
  },
});

console.log(result.data);
```

### REST

```bash theme={null}
curl -X POST https://fal.run/bytedance/seedance-2.0/text-to-video \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A spear-wielding warrior clashes with a dual-blade fighter in a maple leaf forest.",
    "duration": "5",
    "resolution": "720p",
    "aspect_ratio": "16:9"
  }'
```

***

## Input schema

### Text to Video (`bytedance/seedance-2.0/text-to-video`)

| Parameter        | Type    | Default  | Description                                                                                 |
| ---------------- | ------- | -------- | ------------------------------------------------------------------------------------------- |
| `prompt`         | string  | —        | **Required.** Scene description. Put spoken dialogue in double quotes for lip-synced audio. |
| `resolution`     | string  | `"720p"` | `"480p"` or `"720p"`                                                                        |
| `duration`       | string  | `"auto"` | `"auto"`, or `"4"` through `"15"`                                                           |
| `aspect_ratio`   | string  | `"auto"` | `"auto"`, `"21:9"`, `"16:9"`, `"4:3"`, `"1:1"`, `"3:4"`, `"9:16"`                           |
| `generate_audio` | boolean | `true`   | Generate synchronized audio alongside video.                                                |
| `seed`           | integer | —        | Optional seed for reproducibility.                                                          |
| `end_user_id`    | string  | —        | Required for B2B access. Unique identifier for your end customer.                           |

### Image to Video (`bytedance/seedance-2.0/image-to-video`)

All text-to-video parameters, plus:

| Parameter       | Type   | Description                                                                     |
| --------------- | ------ | ------------------------------------------------------------------------------- |
| `image_url`     | string | **Required.** Start frame image URL. Accepted: jpg, jpeg, png, webp, gif, avif. |
| `end_image_url` | string | Optional end frame image to control where the video concludes.                  |

### Reference to Video (`bytedance/seedance-2.0/reference-to-video`)

Accepts text prompts combined with up to 9 images, 3 video clips, and 3 audio files. Reference inputs in your prompt as `[Image1]`, `[Video1]`, `[Audio1]`, etc.

***

## Output schema

```json theme={null}
{
  "video": {
    "url": "https://v3b.fal.media/files/...",
    "content_type": "video/mp4",
    "file_name": "video.mp4",
    "file_size": 4352150
  },
  "seed": 1094575694
}
```

Access the video URL at `result["video"]["url"]` (Python) or `result.data.video.url` (JavaScript).

***

## Supported resolutions

|          | 21:9     | 16:9     | 4:3      | 1:1     | 3:4      | 9:16     |
| -------- | -------- | -------- | -------- | ------- | -------- | -------- |
| **480p** | 992×432  | 864×496  | 752×560  | 640×640 | 560×752  | 496×864  |
| **720p** | 1470×630 | 1280×720 | 1112×834 | 960×960 | 834×1112 | 720×1280 |

***

## Capabilities

**Text to video.** Describe a scene and get video with matching audio. The model handles multi-subject interactions, camera movements, and emotional tone. For dialogue, put speech in double quotes — the model generates matching lip movements and voice.

**Image to video.** Animate a still image using it as the first frame. Optionally provide an end frame to control where the video concludes. The model preserves the look and style of your input image while adding natural motion.

**Multimodal reference.** Combine images, videos, and audio as references in a single generation via the reference-to-video endpoint. Provide a reference video for motion style, reference images for character appearance, and reference audio for rhythm — then describe how to combine them. Powerful for outfit-change videos, product showcases, and music-synced content.

**Video editing.** Provide a reference video and describe changes — replace an object, change a background, alter the style. The model preserves original motion and camera work while applying your edits.

**Video extension.** Provide a reference video and describe what should happen next. The model continues the scene with consistent characters, environment, and style.

***

## Tips

* **Be specific.** Describe camera movements, lighting, mood, and specific actions for best results.
* **Dialogue.** Wrap spoken lines in double quotes: `The man stopped and said: "Remember this moment."`
* **Referencing inputs.** Label them explicitly in your prompt: `"The character from [Image1] performs the dance from [Video1]."`
* **Video editing.** Describe what to change and what to preserve: `"Replace the perfume in [Video1] with the face cream from [Image1], keeping all original motion."`
* **Iterate fast.** Start with 5-second generations to nail the style, then increase duration.

## Related

* [Seedance 2 Image to Video](/model-api-reference/video-generation-api/seedance-2-image-to-video) — Video Generation
* [Seedance 2 Reference to Video](/model-api-reference/video-generation-api/seedance-2-reference-to-video) — Video Generation
* [Seedance 2.0 Fast Text to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-text-to-video) — Video Generation
* [Seedance 2.0 Fast Image to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-image-to-video) — Video Generation
* [Seedance 2.0 Fast Reference to Video](/model-api-reference/video-generation-api/seedance-2.0-fast-reference-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control
* Reproducible generation (seed)

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt used to generate the video
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="720p">
  Video resolution - 480p for faster generation, 720p for balance. Default value: `"720p"`

  Possible values: `480p`, `720p`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="auto">
  Duration of the video in seconds. Supports 4 to 15 seconds, or auto to let the model decide based on the prompt. Default value: `"auto"`

  Possible values: `auto`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
  The aspect ratio of the generated video. Use 16:9 for landscape, 9:16 for portrait/vertical, 1:1 for square, 21:9 for ultrawide cinematic, or auto to let the model decide. Default value: `"auto"`

  Possible values: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate synchronized audio for the video, including sound effects, ambient sounds, and lip-synced speech. The cost of video generation is the same regardless of whether audio is generated or not. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  Random seed for reproducibility. Note that results may still vary slightly even with the same seed.
</ParamField>

<ParamField body="end_user_id" type="string">
  The unique user ID of the end user.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video file.
</ParamField>

<ParamField body="seed" type="integer" required>
  The seed used for generation.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea.",
  "resolution": "720p",
  "duration": "auto",
  "aspect_ratio": "auto",
  "generate_audio": true
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_outputs/bytedance/seedance_2/output.mp4"
  },
  "seed": 42
}
```

## Limitations

* `resolution` restricted to: `480p`, `720p`
* `aspect_ratio` restricted to: `auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-v1-lite.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance V1 Lite API

> API reference for Bytedance Seedance V1 Lite. Seedance 1.0 Lite

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1/lite/image-to-video`
    **Endpoint ID:** `fal-ai/bytedance/seedance/v1/lite/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1/lite/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedance/v1/lite/image-to-video",
          arguments={
              "prompt": "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden.",
              "image_url": "https://fal.media/files/koala/f_xmiodPjhiKjdBkFmTu1.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/lite/image-to-video", {
        input: {
            prompt: "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden.",
            image_url: "https://fal.media/files/koala/f_xmiodPjhiKjdBkFmTu1.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedance/v1/lite/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden.",
        "image_url": "https://fal.media/files/koala/f_xmiodPjhiKjdBkFmTu1.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video Default value: `"auto"`

      Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for higher quality Default value: `"720p"`

      Possible values: `480p`, `720p`, `1080p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Duration of the video in seconds Default value: `"5"`

      Possible values: `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
    </ParamField>

    <ParamField body="camera_fixed" type="boolean" default="false">
      Whether to fix the camera position
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control video generation. Use -1 for random.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="num_frames" type="integer">
      The number of frames to generate. If provided, will override duration.

      Range: `29` to `289`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The URL of the image used to generate video
    </ParamField>

    <ParamField body="end_image_url" type="string">
      The URL of the image the video ends with. Defaults to None.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden.",
      "aspect_ratio": "auto",
      "resolution": "720p",
      "duration": "5",
      "camera_fixed": false,
      "enable_safety_checker": true,
      "image_url": "https://fal.media/files/koala/f_xmiodPjhiKjdBkFmTu1.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/penguin/qmLZSvOIzTKs6bDFXiEtH_video.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1/lite/text-to-video`
    **Endpoint ID:** `fal-ai/bytedance/seedance/v1/lite/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1/lite/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedance/v1/lite/text-to-video",
          arguments={
              "prompt": "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/lite/text-to-video", {
        input: {
            prompt: "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedance/v1/lite/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `9:21`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for higher quality Default value: `"720p"`

      Possible values: `480p`, `720p`, `1080p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Duration of the video in seconds Default value: `"5"`

      Possible values: `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
    </ParamField>

    <ParamField body="camera_fixed" type="boolean" default="false">
      Whether to fix the camera position
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control video generation. Use -1 for random.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="num_frames" type="integer">
      The number of frames to generate. If provided, will override duration.

      Range: `29` to `289`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden.",
      "aspect_ratio": "16:9",
      "resolution": "720p",
      "duration": "5",
      "camera_fixed": false,
      "enable_safety_checker": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/penguin/qmLZSvOIzTKs6bDFXiEtH_video.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>

  <Tab title="Reference To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1/lite/reference-to-video`
    **Endpoint ID:** `fal-ai/bytedance/seedance/v1/lite/reference-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1/lite/reference-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedance/v1/lite/reference-to-video",
          arguments={
              "prompt": "The girl catches the puppy and hugs it.",
              "reference_image_urls": [
                  "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference.jpeg",
                  "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference_2.jpeg"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/lite/reference-to-video", {
        input: {
            prompt: "The girl catches the puppy and hugs it.",
            reference_image_urls: [
              "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference.jpeg",
              "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference_2.jpeg"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedance/v1/lite/reference-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "The girl catches the puppy and hugs it.",
        "reference_image_urls": [
          "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference.jpeg",
          "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference_2.jpeg"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video Default value: `"auto"`

      Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for higher quality Default value: `"720p"`

      Possible values: `480p`, `720p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Duration of the video in seconds Default value: `"5"`

      Possible values: `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
    </ParamField>

    <ParamField body="camera_fixed" type="boolean" default="false">
      Whether to fix the camera position
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control video generation. Use -1 for random.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="num_frames" type="integer">
      The number of frames to generate. If provided, will override duration.

      Range: `29` to `289`
    </ParamField>

    <ParamField body="reference_image_urls" type="list<string>" required>
      Reference images to generate the video with.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "The girl catches the puppy and hugs it.",
      "aspect_ratio": "auto",
      "resolution": "720p",
      "duration": "5",
      "camera_fixed": false,
      "enable_safety_checker": true,
      "reference_image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference.jpeg",
        "https://storage.googleapis.com/falserverless/example_inputs/seedance_reference_2.jpeg"
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_outputs/seedance_reference_output.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>
</Tabs>

## Seedance 1.0 - High-Quality AI Video Generation by ByteDance

Transform your creative vision into professional videos with Seedance, ByteDance's advanced video generation model. Available in both Pro and Lite versions, Seedance delivers exceptional text-to-video and image-to-video generation capabilities for content creators, marketers, and developers.

### Overview

Seedance 1.0 is a fast and efficient video generation model that creates high-quality videos from text prompts or images. The model supports multiple aspect ratios, resolutions, and durations for versatile video generation.

#### Available Endpoints

**Seedance Lite (Fast & Cost-Effective)**

* Text-to-Video: `fal-ai/bytedance/seedance/v1/lite/text-to-video`
* Image-to-Video: `fal-ai/bytedance/seedance/v1/lite/image-to-video`
* Resolution: Up to 720p
* Duration: 5 or 10 seconds

**Seedance Pro (Premium Quality)**

* Text-to-Video: `fal-ai/bytedance/seedance/v1/pro/text-to-video`
* Image-to-Video: `fal-ai/bytedance/seedance/v1/pro/image-to-video`
* Resolution: Up to 1080p
* Duration: 5 or 10 seconds

### Getting Started

Setting up Seedance is straightforward. First, install your preferred client:

For JavaScript/TypeScript:

```bash theme={null}
npm install --save @fal-ai/client
```

For Python:

```bash theme={null}
pip install fal-client
```

Configure your authentication:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY_HERE"
});
```

### Creating Your First Video

#### Text-to-Video Generation

Generate videos directly from text descriptions:

```typescript theme={null}
const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/lite/text-to-video", {
  input: {
    prompt: "A little dog is running in the sunshine. The camera follows the dog as it plays in a garden.",
    aspect_ratio: "16:9",
    resolution: "720p",
    duration: "5"
  }
});

console.log(result.video.url);
```

#### Image-to-Video Generation

Animate still images with descriptive prompts:

```typescript theme={null}
const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/lite/image-to-video", {
  input: {
    image_url: "https://example.com/your-image.jpg",
    prompt: "A skier glides over fresh snow, joyously smiling while kicking up large clouds of snow",
    resolution: "720p",
    duration: "5"
  }
});
```

### API Parameters

#### Common Parameters

* `prompt` (required): Descriptive text for video generation
* `aspect_ratio`: "16:9", "9:16", or "1:1"
* `resolution`: "480p", "720p", or "1080p" (Pro only)
* `duration`: "5" or "10" (seconds)
* `seed`: Random seed for reproducible results (use -1 for random)

#### Image-to-Video Specific

* `image_url` (required): URL of the input image
* Supported formats: jpg, jpeg, png, webp, gif, avif

### Advanced Features

#### Camera Movement Instructions (Pro)

Seedance Pro supports camera movement instructions using square brackets:

```typescript theme={null}
const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/pro/text-to-video", {
  input: {
    prompt: "A bright blue race car speeds along a snowy racetrack. [Low-angle shot] Captures several cars speeding along the racetrack through a harsh snowstorm. [Overhead shot] The camera gradually pulls upward, revealing the full race scene",
    resolution: "1080p",
    duration: "10"
  }
});
```

Supported movements include:

* Truck left/right, Pan left/right
* Push in/Pull out, Pedestal up/down
* Tilt up/down, Zoom in/out
* Shake, Tracking shot, Static shot

#### File Upload Support

Upload local files for image-to-video generation:

```typescript theme={null}
import { fal } from "@fal-ai/client";

const file = new File([imageData], "image.jpg", { type: "image/jpeg" });
const url = await fal.storage.upload(file);

const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/lite/image-to-video", {
  input: {
    image_url: url,
    prompt: "Animate this scene with gentle movement",
    resolution: "720p",
    duration: "5"
  }
});
```

### Pricing

**Seedance Lite**

* \$0.18 per 720p 5-second video
* \$1.80 per million video tokens
* Formula: `tokens = (height × width × FPS × duration) / 1024`

**Seedance Pro**

* \~\$0.62 per 1080p 5-second video
* \$2.50 per million video tokens
* Premium quality with advanced features

### Best Practices

#### For Optimal Results

1. **Write Clear, Detailed Prompts**
   * Begin with the main subject
   * Include important visual details
   * Specify desired movement or camera actions
   * Use camera movement instructions in Pro for cinematic effects

2. **Optimize Performance**
   * Start with shorter durations (5 seconds) during testing
   * Use Lite for rapid prototyping and social media content
   * Choose Pro for professional productions requiring highest quality

3. **Image-to-Video Tips**
   * Use high-quality input images
   * Ensure images have clear subjects
   * Match prompt descriptions to image content
   * Consider aspect ratio compatibility

### Use Cases

**Seedance Lite - Perfect for:**

* Social media content (TikTok, Instagram Reels)
* Quick creative concepts and prototypes
* Educational content and demonstrations
* Marketing previews and teasers

**Seedance Pro - Ideal for:**

* Professional marketing campaigns
* High-quality brand content
* Cinematic storytelling with multi-shot sequences
* Premium product demonstrations

### Error Handling

Implement robust error handling for production use:

```typescript theme={null}
try {
  const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/lite/text-to-video", {
    input: {
      prompt: "Your creative prompt",
      resolution: "720p",
      duration: "5"
    }
  });
  console.log(result.video.url);
} catch (error) {
  console.error("Video generation failed:", error.message);
  // Implement fallback logic
}
```

### Queue Management

For long-running requests, use the queue API:

```typescript theme={null}
// Submit request
const { request_id } = await fal.queue.submit("fal-ai/bytedance/seedance/v1/pro/text-to-video", {
  input: {
    prompt: "Complex multi-shot video prompt",
    resolution: "1080p",
    duration: "10"
  },
  webhookUrl: "https://your-webhook.url/results"
});

// Check status
const status = await fal.queue.status("fal-ai/bytedance/seedance/v1/pro/text-to-video", {
  requestId: request_id
});

// Get result
const result = await fal.queue.result("fal-ai/bytedance/seedance/v1/pro/text-to-video", {
  requestId: request_id
});
```

### Technical Details

* **Inference Speed**: \~41 seconds for 5-second 1080p video on L20 GPU
* **Concurrency**: Up to 10 simultaneous renders
* **API Authentication**: Key-based authentication via FAL\_KEY
* **Output Format**: MP4 video files
* **Partner Model**: Available through fal.ai's inference infrastructure

### Support

For implementation assistance and additional resources:

* **Documentation**: [fal.ai Documentation](https://docs.fal.ai/)
* **API Reference**: View model-specific endpoints and parameters
* **Model Gallery**: Explore all Seedance variants at [fal.ai/models](https://fal.ai/models)
* **Dashboard**: Manage API keys at [fal.ai/dashboard](https://fal.ai/dashboard)

### Getting Started Today

Ready to transform your ideas into compelling videos? Sign up at [fal.ai](https://fal.ai/) to get your API key and start creating with Seedance. Both Pro and Lite versions offer unique advantages for different use cases, ensuring you have the right tool for your creative needs.

## Related

* [Seedance 1.0 Pro](/model-api-reference/video-generation-api/seedance-1.0-pro) — Video Generation
* [Bytedance](/model-api-reference/video-generation-api/bytedance) — Video Generation
* [Seedance 1.0 Lite](/model-api-reference/video-generation-api/seedance-1.0-lite) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
* `resolution` restricted to: `480p`, `720p`, `1080p`
* `num_frames` range: 29 to 289
* Content moderation via safety checker
* `aspect_ratio` restricted to: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `9:21`
* `resolution` restricted to: `480p`, `720p`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-v1-pro-fast.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance V1 Pro Fast API

> API reference for Bytedance Seedance V1 Pro Fast. Image to Video endpoint for Seedance 1.0 Pro Fast, a next-generation video model designed to deliver maximum performance at minimal cost

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1/pro/fast/image-to-video`
    **Endpoint ID:** `fal-ai/bytedance/seedance/v1/pro/fast/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/fast/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedance/v1/pro/fast/image-to-video",
          arguments={
              "prompt": "Bathed in a stark spotlight, a lone ballet dancer takes center stage. Her movements, precise and graceful, tell a story of passion and dedication against the velvet darkness. The scene evokes a sense of intimacy, highlighting the raw emotion and artistry of her performance.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_fast_i2v_input.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/pro/fast/image-to-video", {
        input: {
            prompt: "Bathed in a stark spotlight, a lone ballet dancer takes center stage. Her movements, precise and graceful, tell a story of passion and dedication against the velvet darkness. The scene evokes a sense of intimacy, highlighting the raw emotion and artistry of her performance.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/seedance_fast_i2v_input.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedance/v1/pro/fast/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Bathed in a stark spotlight, a lone ballet dancer takes center stage. Her movements, precise and graceful, tell a story of passion and dedication against the velvet darkness. The scene evokes a sense of intimacy, highlighting the raw emotion and artistry of her performance.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_fast_i2v_input.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video Default value: `"auto"`

      Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1080p">
      Video resolution - 480p for faster generation, 720p for balance, 1080p for higher quality Default value: `"1080p"`

      Possible values: `480p`, `720p`, `1080p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Duration of the video in seconds Default value: `"5"`

      Possible values: `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
    </ParamField>

    <ParamField body="camera_fixed" type="boolean" default="false">
      Whether to fix the camera position
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control video generation. Use -1 for random.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="num_frames" type="integer">
      The number of frames to generate. If provided, will override duration.

      Range: `29` to `289`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The URL of the image used to generate video
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Bathed in a stark spotlight, a lone ballet dancer takes center stage. Her movements, precise and graceful, tell a story of passion and dedication against the velvet darkness. The scene evokes a sense of intimacy, highlighting the raw emotion and artistry of her performance.",
      "aspect_ratio": "auto",
      "resolution": "1080p",
      "duration": "5",
      "camera_fixed": false,
      "enable_safety_checker": true,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_fast_i2v_input.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_fast_i2v_output.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1/pro/fast/text-to-video`
    **Endpoint ID:** `fal-ai/bytedance/seedance/v1/pro/fast/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/fast/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedance/v1/pro/fast/text-to-video",
          arguments={
              "prompt": "Inside a quiet dojo, a martial artist moves with precision and grace. The performance highlights the beauty and discipline inherent in the ancient practice. Each form unfolds clearly, a testament to dedication and skill."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/pro/fast/text-to-video", {
        input: {
            prompt: "Inside a quiet dojo, a martial artist moves with precision and grace. The performance highlights the beauty and discipline inherent in the ancient practice. Each form unfolds clearly, a testament to dedication and skill."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedance/v1/pro/fast/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Inside a quiet dojo, a martial artist moves with precision and grace. The performance highlights the beauty and discipline inherent in the ancient practice. Each form unfolds clearly, a testament to dedication and skill."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1080p">
      Video resolution - 480p for faster generation, 720p for balance, 1080p for higher quality Default value: `"1080p"`

      Possible values: `480p`, `720p`, `1080p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Duration of the video in seconds Default value: `"5"`

      Possible values: `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
    </ParamField>

    <ParamField body="camera_fixed" type="boolean" default="false">
      Whether to fix the camera position
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control video generation. Use -1 for random.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="num_frames" type="integer">
      The number of frames to generate. If provided, will override duration.

      Range: `29` to `289`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Inside a quiet dojo, a martial artist moves with precision and grace. The performance highlights the beauty and discipline inherent in the ancient practice. Each form unfolds clearly, a testament to dedication and skill.",
      "aspect_ratio": "16:9",
      "resolution": "1080p",
      "duration": "5",
      "camera_fixed": false,
      "enable_safety_checker": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_fast_t2v_output.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>
</Tabs>

## Seedance 1.0 Pro Fast \[Text-to-Video]

Transform text prompts into professional-grade videos with ByteDance's next-generation video model engineered for maximum performance at minimal cost.

## Overview

Seedance 1.0 Pro Fast delivers high-quality video generation from text prompts with exceptional speed and efficiency. Built to support versatile production workflows, this model excels at creating videos with realistic motion and physical stability—making it ideal for everything from social media content to commercial productions. Generate compelling visual narratives without requiring complex video editing skills or production infrastructure.

## Key Capabilities

* **Text-to-video transformation**: Convert detailed text descriptions directly into coherent, high-quality video sequences
* **Fast inference times**: Deliver quick turnarounds for time-sensitive content creation workflows
* **Wide dynamic range**: Generate smooth large-scale movements from subtle expressions to active scenes with high stability
* **Production-ready output**: Create commercially viable videos suitable for marketing, social media, and professional applications

## Popular Use Cases

**Social Media Content Creation**\
Generate engaging video content for Instagram Reels, TikTok, and YouTube Shorts directly from text descriptions. Transform product descriptions, promotional copy, or creative concepts into thumb-stopping videos that capture attention across multiple platforms without hiring production crews or investing in expensive equipment.

**Marketing and Advertising**\
Create compelling commercial video content for campaigns, product launches, and brand storytelling. Generate multiple variations of marketing videos to test different messaging approaches, visual styles, and creative directions—enabling rapid iteration and A/B testing at a fraction of traditional production costs.

**Educational and Training Content**\
Develop instructional videos, demonstrations, and training materials by describing the scenes you need. Produce consistent, professional-quality educational content that illustrates complex concepts, procedures, or workflows without coordinating filming schedules or managing production logistics.

## Getting Started

Getting up and running with Seedance 1.0 Pro Fast takes just a few minutes. Here's how to begin:

**1. Get your API key**\
Sign up at [https://fal.ai/login](https://fal.ai/login) to obtain your credentials and access the platform.

**2. Install the client library**\
Add the fal.ai client to your project:

```bash theme={null}
npm install --save @fal-ai/client
```

**3. Make your first API call**\
Submit a video generation request with your text prompt:

```javascript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY"
});

const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/pro/fast/text-to-video", {
  input: {
    prompt: "Inside a quiet dojo, a martial artist moves with precision and grace. The performance highlights the beauty and discipline inherent in the ancient practice. Each form unfolds clearly, a testament to dedication and skill."
  },
  logs: true,
  onQueueUpdate: (update) => {
    if (update.status === "IN_PROGRESS") {
      update.logs.map((log) => log.message).forEach(console.log);
    }
  }
});

// Access the generated video
console.log(result.data.video.url);
console.log(result.requestId);
```

For Python developers:

```python theme={null}
from fal_client import FalClient

client = FalClient("YOUR_FAL_KEY")
result = client.subscribe("fal-ai/bytedance/seedance/v1/pro/fast/text-to-video", {
    "prompt": "Inside a quiet dojo, a martial artist moves with precision and grace. The performance highlights the beauty and discipline inherent in the ancient practice. Each form unfolds clearly, a testament to dedication and skill."
})

# Access the generated video
print(result["video"]["url"])
```

## Technical Specifications

**Model Architecture**

* Next-generation text-to-video model optimized for speed and quality balance
* Designed for commercial-scale deployment with reliable performance
* Features wide dynamic range enabling smooth generation of large-scale movements, from subtle expressions to active scenes with high stability and physical realism

**Input Capabilities**

* Text prompt-based video generation
* Default output: 1080p resolution at standard frame rates

**Performance**

* Fast inference optimized for production workflows
* Queue-based processing with status tracking and webhooks
* Scalable infrastructure for handling multiple concurrent requests
* No charges for cold starts or server errors (5xx)

## Best Practices

Achieve optimal results with these proven approaches:

**Craft Detailed, Specific Prompts**\
The quality of your generated video directly correlates with prompt specificity. Instead of generic descriptions like "a person walking," provide rich contextual details: "A young woman in a red coat walks confidently down a rain-slicked city street at dusk, her reflection shimmering in puddles as neon signs illuminate the background." Include information about movement, lighting, atmosphere, and visual style to guide the model toward your creative vision. ByteDance's Seedance technology excels at translating nuanced descriptions into visually coherent sequences.

**Leverage the Queue System for Production Workflows**\
For applications requiring multiple video generations or integration into larger content pipelines, utilize the queue system with webhooks rather than blocking operations. This approach enables you to submit requests asynchronously, track progress through status updates, and retrieve results when ready—essential for building responsive applications that maintain performance under load. Consider implementing webhook endpoints to automatically process completed videos without polling.

**Combine with Other AI Tools for Complete Workflows**\
Maximize creative potential by integrating Seedance into broader AI-powered production pipelines. Start with [AI image generators like Flux](https://fal.ai/models/fal-ai/flux-general/inpainting) to create reference frames, then extend them into video sequences. Add AI-generated music through [CassetteAI](https://fal.ai/models/cassetteai/music-generator) or create talking head videos with [lipsync capabilities](https://fal.ai/models/veed/lipsync) to build complete multimedia experiences that would traditionally require entire production teams.

## Advanced Features

**Webhook Integration for Asynchronous Processing**\
Configure webhook URLs to receive automatic notifications when video generation completes, enabling event-driven architectures and seamless integration with existing systems:

```javascript theme={null}
const { request_id } = await fal.queue.submit("fal-ai/bytedance/seedance/v1/pro/fast/text-to-video", {
  input: {
    prompt: "A serene mountain landscape at sunrise, with mist rolling through valleys"
  },
  webhookUrl: "https://your-domain.com/webhooks/video-complete"
});
```

**Queue Management and Status Tracking**\
Monitor generation progress in real-time and implement sophisticated retry logic for production applications:

```javascript theme={null}
const status = await fal.queue.status("fal-ai/bytedance/seedance/v1/pro/fast/text-to-video", {
  requestId: request_id,
  logs: true
});

// Retrieve result when ready
const result = await fal.queue.result("fal-ai/bytedance/seedance/v1/pro/fast/text-to-video", {
  requestId: request_id
});
```

## API Reference

```typescript theme={null}
interface SeedanceInput {
  prompt: string; // Detailed text description of the video to generate (required)
  webhookUrl?: string; // Optional webhook URL for completion notifications
}

interface SeedanceOutput {
  video: {
    url: string; // URL to the generated video file
    content_type: string; // MIME type of the video (e.g., "video/mp4")
    file_name: string; // Generated filename
    file_size: number; // Size of the video file in bytes
  };
  seed: number; // Random seed used for generation
}
```

## Pricing and Usage

Seedance 1.0 Pro Fast uses token-based pricing calculated by video dimensions and duration. Each 1080p 5-second video costs approximately **$0.245**. For other resolutions, pricing is **$1 per million video tokens**, where:

```
tokens(video) = (height × width × FPS × duration) / 1024
```

**Billing Notes:**

* Server errors (5xx) are not charged
* Client errors (422) are charged
* Cold starts incur no additional costs
* Purchased credits expire in 365 days; free credits expire in 90 days

For enterprise solutions requiring custom volume arrangements, private deployments, or dedicated infrastructure, contact sales for tailored pricing options. Volume discounts are available for high-usage customers.

## Support and Resources

We're here to help you succeed with Seedance 1.0 Pro Fast:

* **Documentation**: Explore comprehensive guides and API references at [https://docs.fal.ai/](https://docs.fal.ai/)
* **Interactive Playground**: Test the model and experiment with different prompts at the [Seedance playground](https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/fast/text-to-video)
* **Alternative Versions**: Explore the Seedance 1.0 Lite version for different performance characteristics
* **Developer Support**: Access technical assistance and integration guidance through our community channels

Ready to transform text into compelling video content? Sign up now at [https://fal.ai](https://fal.ai) and start creating with Seedance 1.0 Pro Fast.

[Get Started](https://fal.ai/login)

## Related

* [Seedance 1.0 Pro](/model-api-reference/video-generation-api/seedance-1.0-pro) — Video Generation
* [Seedance 1.0 Lite](/model-api-reference/video-generation-api/seedance-1.0-lite) — Video Generation
* [Bytedance](/model-api-reference/video-generation-api/bytedance) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
* `resolution` restricted to: `480p`, `720p`, `1080p`
* `num_frames` range: 29 to 289
* Content moderation via safety checker
* `aspect_ratio` restricted to: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-v1-pro-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance V1 Pro Image To Video API

> API reference for Bytedance Seedance V1 Pro Image To Video. Seedance 1.0 Pro, a high quality video generation model developed by Bytedance.

**Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1/pro/image-to-video`
**Endpoint ID:** `fal-ai/bytedance/seedance/v1/pro/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bytedance/seedance/v1/pro/image-to-video",
      arguments={
          "prompt": "A skier glides over fresh snow, joyously smiling while kicking up large clouds of snow as he turns. Accelerating gradually down the slope, the camera moves smoothly alongside.",
          "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_pro_i2v_img.jpg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/pro/image-to-video", {
    input: {
        prompt: "A skier glides over fresh snow, joyously smiling while kicking up large clouds of snow as he turns. Accelerating gradually down the slope, the camera moves smoothly alongside.",
        image_url: "https://storage.googleapis.com/falserverless/example_inputs/seedance_pro_i2v_img.jpg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bytedance/seedance/v1/pro/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A skier glides over fresh snow, joyously smiling while kicking up large clouds of snow as he turns. Accelerating gradually down the slope, the camera moves smoothly alongside.",
    "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_pro_i2v_img.jpg"
  }'
  ```
</CodeGroup>

## Seedance: Professional Image-to-Video Generation

Transform static images into fluid, natural-looking videos with Seedance, ByteDance's advanced AI motion generation model. Whether you're creating engaging social media content, dynamic marketing materials, or creative visual projects, Seedance helps you bring your images to life with sophisticated motion synthesis.

### Key Capabilities

Seedance excels at creating natural motion from single images while preserving visual quality and temporal consistency. The model understands complex scenes and generates realistic movement patterns that respect physical constraints and object relationships.

Create compelling video content from:

* Portrait photos with natural facial expressions and movements
* Landscape scenes with flowing water, swaying trees, and dynamic skies
* Product shots with smooth rotations and transitions
* Abstract art with creative motion effects

### Getting Started

Setting up Seedance is straightforward. First, install the fal client library:

```bash theme={null}
# For Node.js
npm install --save @fal-ai/client

# For Python
pip install fal-client
```

Configure your API credentials:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY_HERE"
});
```

### Making Your First API Call

Generate your first video with this simple example:

```typescript theme={null}
const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/pro/image-to-video", {
  input: {
    image_url: "YOUR_IMAGE_URL"
  }
});
```

### Advanced Usage

Seedance offers fine-grained control over video generation through various parameters:

#### Motion Control

Control the intensity and nature of movement with configurable parameters. The model features a wide dynamic range, enabling smooth generation of large-scale movements while maintaining stability and physical realism.

#### Duration and Quality

Adjust video length and quality settings to match your needs. The Pro model supports 1080p output, while the Lite model provides 720p resolution. Both models typically generate 5-second videos.

### Best Practices

For optimal results:

* Use high-quality source images with good lighting and clear subjects
* Accepted file types include: jpg, jpeg, png, webp, gif, avif
* Consider the intended motion when composing your input image
* Start with default parameters and adjust gradually
* Test different configurations to find the right balance for your content

### Technical Specifications

Processing Capabilities:

* Input Resolution: Supports various input formats and sizes
* Output Formats: MP4 video
* Output Resolution: Up to 1080p (Pro), 720p (Lite)
* Frame Rate: Standard video frame rates
* Processing Time: Varies based on complexity and queue

### Pricing and Usage

Each 1080p 5 second video costs roughly $0.74 (Pro version). For other resolutions, 1 million video tokens costs $3.0. The Lite version costs $0.18 per 720p 5 second video, with 1 million video tokens costing $1.8.

Pricing calculation: `tokens(video) = (height x width x FPS x duration) / 1024`

Our transparent, usage-based pricing scales with your needs:

* Pay-per-use model with no subscription required
* Pro version for high-quality 1080p output
* Lite version for cost-effective 720p generation
* No hidden fees or minimum commitments

### Implementation Support

Our comprehensive support resources help you integrate Seedance successfully:

#### Documentation

Access detailed API references, code examples, and integration guides in our documentation portal at docs.fal.ai

#### Client Libraries

We have support via official client libraries for JavaScript, Python, Swift, Java, Kotlin, and Dart (Flutter)

#### Sample Applications

Explore reference implementations and example projects demonstrating common use cases and implementation patterns

For detailed pricing information, visit [fal.ai/pricing](https://fal.ai/pricing) or contact [support@fal.ai](mailto:support@fal.ai) for enterprise solutions.

## Related

* [Seedance 1.0 Lite](/model-api-reference/video-generation-api/seedance-1.0-lite) — Video Generation
* [Bytedance](/model-api-reference/video-generation-api/bytedance) — Video Generation
* [Seedance 1.0 Pro](/model-api-reference/video-generation-api/seedance-1.0-pro) — Video Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Duration control
* Reproducible generation (seed)
* Safety checker
* Frame count control
* Image input

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt used to generate the video
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
  The aspect ratio of the generated video Default value: `"auto"`

  Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="1080p">
  Video resolution - 480p for faster generation, 720p for balance, 1080p for higher quality Default value: `"1080p"`

  Possible values: `480p`, `720p`, `1080p`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Duration of the video in seconds Default value: `"5"`

  Possible values: `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
</ParamField>

<ParamField body="camera_fixed" type="boolean" default="false">
  Whether to fix the camera position
</ParamField>

<ParamField body="seed" type="integer">
  Random seed to control video generation. Use -1 for random.
</ParamField>

<ParamField body="enable_safety_checker" type="boolean" default="true">
  If set to true, the safety checker will be enabled. Default value: `true`
</ParamField>

<ParamField body="num_frames" type="integer">
  The number of frames to generate. If provided, will override duration.

  Range: `29` to `289`
</ParamField>

<ParamField body="image_url" type="string" required>
  The URL of the image used to generate video
</ParamField>

<ParamField body="end_image_url" type="string">
  The URL of the image the video ends with. Defaults to None.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  Generated video file
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed used for generation
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A skier glides over fresh snow, joyously smiling while kicking up large clouds of snow as he turns. Accelerating gradually down the slope, the camera moves smoothly alongside.",
  "aspect_ratio": "auto",
  "resolution": "1080p",
  "duration": "5",
  "camera_fixed": false,
  "enable_safety_checker": true,
  "image_url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_pro_i2v_img.jpg"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_pro_i2v.mp4"
  },
  "seed": 42
}
```

## Limitations

* `aspect_ratio` restricted to: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
* `resolution` restricted to: `480p`, `720p`, `1080p`
* `num_frames` range: 29 to 289
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-v1-pro-text-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance V1 Pro Text To Video API

> API reference for Bytedance Seedance V1 Pro Text To Video. Seedance 1.0 Pro, a high quality video generation model developed by Bytedance.

**Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1/pro/text-to-video`
**Endpoint ID:** `fal-ai/bytedance/seedance/v1/pro/text-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1/pro/text-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bytedance/seedance/v1/pro/text-to-video",
      arguments={
          "prompt": "A bright blue race car speeds along a snowy racetrack. [Low-angle shot] Captures several cars speeding along the racetrack through a harsh snowstorm. [Overhead shot] The camera gradually pulls upward, revealing the full race scene illuminated by storm lights"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bytedance/seedance/v1/pro/text-to-video", {
    input: {
        prompt: "A bright blue race car speeds along a snowy racetrack. [Low-angle shot] Captures several cars speeding along the racetrack through a harsh snowstorm. [Overhead shot] The camera gradually pulls upward, revealing the full race scene illuminated by storm lights"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bytedance/seedance/v1/pro/text-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A bright blue race car speeds along a snowy racetrack. [Low-angle shot] Captures several cars speeding along the racetrack through a harsh snowstorm. [Overhead shot] The camera gradually pulls upward, revealing the full race scene illuminated by storm lights"
  }'
  ```
</CodeGroup>

## Related

* [Seedance 1.0 Pro](/model-api-reference/video-generation-api/seedance-1.0-pro) — Video Generation
* [Seedance 1.0 Lite](/model-api-reference/video-generation-api/seedance-1.0-lite) — Video Generation
* [Bytedance](/model-api-reference/video-generation-api/bytedance) — Video Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Duration control
* Reproducible generation (seed)
* Safety checker
* Frame count control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt used to generate the video
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  The aspect ratio of the generated video Default value: `"16:9"`

  Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="1080p">
  Video resolution - 480p for faster generation, 720p for balance, 1080p for higher quality Default value: `"1080p"`

  Possible values: `480p`, `720p`, `1080p`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Duration of the video in seconds Default value: `"5"`

  Possible values: `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
</ParamField>

<ParamField body="camera_fixed" type="boolean" default="false">
  Whether to fix the camera position
</ParamField>

<ParamField body="seed" type="integer">
  Random seed to control video generation. Use -1 for random.
</ParamField>

<ParamField body="enable_safety_checker" type="boolean" default="true">
  If set to true, the safety checker will be enabled. Default value: `true`
</ParamField>

<ParamField body="num_frames" type="integer">
  The number of frames to generate. If provided, will override duration.

  Range: `29` to `289`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  Generated video file
</ParamField>

<ParamField body="seed" type="integer" required>
  Seed used for generation
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A bright blue race car speeds along a snowy racetrack. [Low-angle shot] Captures several cars speeding along the racetrack through a harsh snowstorm. [Overhead shot] The camera gradually pulls upward, revealing the full race scene illuminated by storm lights",
  "aspect_ratio": "16:9",
  "resolution": "1080p",
  "duration": "5",
  "camera_fixed": false,
  "enable_safety_checker": true
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_inputs/seedance_pro_t2v.mp4"
  },
  "seed": 42
}
```

## Limitations

* `aspect_ratio` restricted to: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
* `resolution` restricted to: `480p`, `720p`, `1080p`
* `num_frames` range: 29 to 289
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-seedance-v1.5-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Seedance V1.5 Pro API

> API reference for Bytedance Seedance V1.5 Pro. Generate videos with audio with Seedance 1.5 (supports start & end frame)

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1.5/pro/image-to-video`
    **Endpoint ID:** `fal-ai/bytedance/seedance/v1.5/pro/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1.5/pro/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedance/v1.5/pro/image-to-video",
          arguments={
              "prompt": "A man is crying and he says \"I shouldn't have done it. I regret everything\"",
              "image_url": "https://v3b.fal.media/files/b/0a8773cd/REzCWn1BKUVuMFTxR-R3W_image_317.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedance/v1.5/pro/image-to-video", {
        input: {
            prompt: "A man is crying and he says \"I shouldn't have done it. I regret everything\"",
            image_url: "https://v3b.fal.media/files/b/0a8773cd/REzCWn1BKUVuMFTxR-R3W_image_317.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedance/v1.5/pro/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A man is crying and he says \"I shouldn'\''t have done it. I regret everything\"",
        "image_url": "https://v3b.fal.media/files/b/0a8773cd/REzCWn1BKUVuMFTxR-R3W_image_317.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for balance, 1080p for higher quality Default value: `"720p"`

      Possible values: `480p`, `720p`, `1080p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Duration of the video in seconds Default value: `"5"`

      Possible values: `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
    </ParamField>

    <ParamField body="camera_fixed" type="boolean" default="false">
      Whether to fix the camera position
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control video generation. Use -1 for random.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video Default value: `true`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The URL of the image used to generate video
    </ParamField>

    <ParamField body="end_image_url" type="string">
      The URL of the image the video ends with. Defaults to None.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A man is crying and he says \"I shouldn't have done it. I regret everything\"",
      "aspect_ratio": "16:9",
      "resolution": "720p",
      "duration": "5",
      "camera_fixed": false,
      "enable_safety_checker": true,
      "generate_audio": true,
      "image_url": "https://v3b.fal.media/files/b/0a8773cd/REzCWn1BKUVuMFTxR-R3W_image_317.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3b.fal.media/files/b/0a8773d3/l2fk-fIO_PQFPzbvHkQX1_video.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/bytedance/seedance/v1.5/pro/text-to-video`
    **Endpoint ID:** `fal-ai/bytedance/seedance/v1.5/pro/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/seedance/v1.5/pro/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/bytedance/seedance/v1.5/pro/text-to-video",
          arguments={
              "prompt": "Defense attorney declaring \"Ladies and gentlemen, reasonable doubt isn't just a phrase, it's the foundation of justice itself\", footsteps on marble, jury shifting, courtroom drama, closing argument power."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/bytedance/seedance/v1.5/pro/text-to-video", {
        input: {
            prompt: "Defense attorney declaring \"Ladies and gentlemen, reasonable doubt isn't just a phrase, it's the foundation of justice itself\", footsteps on marble, jury shifting, courtroom drama, closing argument power."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/bytedance/seedance/v1.5/pro/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Defense attorney declaring \"Ladies and gentlemen, reasonable doubt isn'\''t just a phrase, it'\''s the foundation of justice itself\", footsteps on marble, jury shifting, courtroom drama, closing argument power."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt used to generate the video
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Video resolution - 480p for faster generation, 720p for balance, 1080p for higher quality Default value: `"720p"`

      Possible values: `480p`, `720p`, `1080p`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Duration of the video in seconds Default value: `"5"`

      Possible values: `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`
    </ParamField>

    <ParamField body="camera_fixed" type="boolean" default="false">
      Whether to fix the camera position
    </ParamField>

    <ParamField body="seed" type="integer">
      Random seed to control video generation. Use -1 for random.
    </ParamField>

    <ParamField body="enable_safety_checker" type="boolean" default="true">
      If set to true, the safety checker will be enabled. Default value: `true`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video Default value: `true`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      Generated video file
    </ParamField>

    <ParamField body="seed" type="integer" required>
      Seed used for generation
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Defense attorney declaring \"Ladies and gentlemen, reasonable doubt isn't just a phrase, it's the foundation of justice itself\", footsteps on marble, jury shifting, courtroom drama, closing argument power.",
      "aspect_ratio": "16:9",
      "resolution": "720p",
      "duration": "5",
      "camera_fixed": false,
      "enable_safety_checker": true,
      "generate_audio": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3b.fal.media/files/b/0a87743e/0K5lW0v-iC_BbKo64o0cA_video.mp4"
      },
      "seed": 42
    }
    ```
  </Tab>
</Tabs>

Animate any image into a cinematic video with synchronized audio. Upload a start frame and optionally an end frame and Seedance 1.5 Pro generates the motion, camera movement, dialogue, and sound design in between.

***

## Use Cases

| Use Case                | Why Seedance 1.5 Pro fits                                                                               |
| :---------------------- | :------------------------------------------------------------------------------------------------------ |
| **Photo animation**     | Breathe life into a still portrait or product shot with realistic motion and ambient sound.             |
| **Character animation** | Turn concept art or a single character frame into a speaking, emoting performance with lip-sync.        |
| **Product reveals**     | Start on a hero shot, end on packaging — the model animates the transition with cinematic flair.        |
| **Scene transitions**   | Define start and end compositions for precise A-to-B shots — useful for ads, trailers, or music videos. |
| **Storyboard-to-video** | Convert illustrated storyboard frames into rough-cut motion tests with matching audio.                  |
| **Social content**      | Animate memes, portraits, or fan art into shareable clips with sound.                                   |
| **Virtual avatars**     | Animate a single headshot into a talking-head video with natural speech and lip-sync.                   |

***

## Key Features

| Feature                      | Description                                                                                                         |
| :--------------------------- | :------------------------------------------------------------------------------------------------------------------ |
| **Start frame conditioning** | Upload an image to set the opening composition, lighting, subject, and style.                                       |
| **End frame conditioning**   | Optionally upload a second image to define where the shot lands — the model generates the motion path between them. |
| **Native audio generation**  | Dialogue, sound effects, and ambient audio rendered alongside the video. Lip movements stay locked to speech.       |
| **Cinematic camera work**    | Pan, tilt, zoom, dolly, orbit, tracking shots — describe the move in your prompt.                                   |
| **Character consistency**    | The subject from your start frame stays stable throughout — face, clothing, and expression.                         |
| **High resolution**          | Output up to 1080p with smooth temporal consistency.                                                                |

***

## Controls

| Parameter        | Options                                          | Notes                                                |
| :--------------- | :----------------------------------------------- | :--------------------------------------------------- |
| `prompt`         | Text (required)                                  | Describe action, dialogue, camera, and sound         |
| `image_url`      | URL (required)                                   | Start frame — sets the opening composition           |
| `end_image_url`  | URL (optional)                                   | End frame — defines the closing composition          |
| `aspect_ratio`   | `21:9` · `16:9` · `4:3` · `1:1` · `3:4` · `9:16` | Default: `16:9`                                      |
| `resolution`     | `480p` · `720p`                                  | `480p` for faster iteration; `720p` for final output |
| `duration`       | `4`–`12` seconds                                 | Default: `5`                                         |
| `generate_audio` | `true` / `false`                                 | Default: `true` — set `false` for silent video       |
| `camera_fixed`   | `true` / `false`                                 | Lock the camera in place (tripod shot)               |
| `seed`           | Integer                                          | Set a value for reproducibility; use `-1` for random |

***

## Start Frame / End Frame

This is the core differentiator from text-to-video. You control the opening and closing compositions directly.

| Frame                           | What it does                                                                                                            |
| :------------------------------ | :---------------------------------------------------------------------------------------------------------------------- |
| **Start frame** (`image_url`)   | Required. Sets the initial subject, pose, lighting, color grade, and environment. The model animates forward from here. |
| **End frame** (`end_image_url`) | Optional. Defines the final composition. The model generates a motion path that lands precisely on this frame.          |

**Tips:**

* Use the same subject in both frames for smooth transitions.
* Match aspect ratio and style between start and end frames.
* Motion is generated in latent space — not interpolated — so physics and camera movement feel natural.

***

## Prompting Tips

Your prompt guides what happens *between* the frames:

| Element         | Example                                             |
| :-------------- | :-------------------------------------------------- |
| **Action**      | "She turns to face the camera and smiles"           |
| **Dialogue**    | `"I've been waiting for this moment."` (use quotes) |
| **Camera**      | "Slow push-in ending on a close-up"                 |
| **Audio/Foley** | "Soft piano, room reverb, fabric rustling"          |

**More tips:**

* The start frame already defines the scene — focus your prompt on *motion* and *sound*.
* For talking heads, put the dialogue in quotes and describe the emotion: `"I can't believe it," voice breaking with emotion`.
* Use `camera_fixed: true` if you want the subject to move but the frame to stay locked.

***

## Specs

| Spec           | Value                                      |
| :------------- | :----------------------------------------- |
| Max duration   | 12 seconds                                 |
| Max resolution | 1080p                                      |
| Audio          | Mixed dialogue + foley + score, 48 kHz AAC |
| Output format  | MP4 (H.264)                                |

***

## API

[fal.ai → Seedance 1.5 Pro image-to-video](https://fal.ai/models/fal-ai/bytedance/seedance/v1.5/pro/image-to-video/api)

## Related

* [Bytedance](/model-api-reference/video-generation-api/bytedance) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`, `auto`
* `resolution` restricted to: `480p`, `720p`, `1080p`
* Content moderation via safety checker


# https://fal.ai/docs/model-api-reference/video-generation-api/bytedance-video-stylize.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bytedance Video Stylize API

> API reference for Bytedance Video Stylize. Transform your images into stylized videos using this workflow.

**Endpoint:** `POST https://fal.run/fal-ai/bytedance/video-stylize`
**Endpoint ID:** `fal-ai/bytedance/video-stylize`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/bytedance/video-stylize/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/bytedance/video-stylize",
      arguments={
          "style": "Manga style",
          "image_url": "https://v3.fal.media/files/kangaroo/-KmSPIcXeGA3Z_iiH4C75_tmph2ry_0_8.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/bytedance/video-stylize", {
    input: {
        style: "Manga style",
        image_url: "https://v3.fal.media/files/kangaroo/-KmSPIcXeGA3Z_iiH4C75_tmph2ry_0_8.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/bytedance/video-stylize \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "style": "Manga style",
    "image_url": "https://v3.fal.media/files/kangaroo/-KmSPIcXeGA3Z_iiH4C75_tmph2ry_0_8.png"
  }'
  ```
</CodeGroup>

## Capabilities

* Image input

## API Reference

### Input Schema

<ParamField body="style" type="string" required>
  The style for your character in the video. Please use a short description.
</ParamField>

<ParamField body="image_url" type="string" required>
  URL of the image to make the stylized video from.
</ParamField>

## Input Example

```json theme={null}
{
  "style": "Manga style",
  "image_url": "https://v3.fal.media/files/kangaroo/-KmSPIcXeGA3Z_iiH4C75_tmph2ry_0_8.png"
}
```


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-ai-avatar-v2.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video Ai Avatar V2 API

> API reference for Kling Video Ai Avatar V2. Kling AI Avatar v2 Pro: The premium endpoint for creating avatar videos with realistic humans, animals, cartoons, or stylized characters

<Tabs>
  <Tab title="Pro">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/ai-avatar/v2/pro`
    **Endpoint ID:** `fal-ai/kling-video/ai-avatar/v2/pro`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/ai-avatar/v2/pro/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/ai-avatar/v2/pro",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
              "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/ai-avatar/v2/pro", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
            audio_url: "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/ai-avatar/v2/pro \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
        "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to use as your avatar
    </ParamField>

    <ParamField body="audio_url" type="string" required>
      The URL of the audio file.
    </ParamField>

    <ParamField body="prompt" type="string" default=".">
      The prompt to use for the video generation. Default value: `"."`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    <ParamField body="duration" type="float" required>
      Duration of the output video in seconds.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
      "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3",
      "prompt": "."
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/penguin/ln3x7H1p1jL0Pwo7675NI_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Standard">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/ai-avatar/v2/standard`
    **Endpoint ID:** `fal-ai/kling-video/ai-avatar/v2/standard`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/ai-avatar/v2/standard/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/ai-avatar/v2/standard",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
              "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/ai-avatar/v2/standard", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
            audio_url: "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/ai-avatar/v2/standard \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
        "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to use as your avatar
    </ParamField>

    <ParamField body="audio_url" type="string" required>
      The URL of the audio file.
    </ParamField>

    <ParamField body="prompt" type="string" default=".">
      The prompt to use for the video generation. Default value: `"."`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    <ParamField body="duration" type="float" required>
      Duration of the output video in seconds.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
      "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3",
      "prompt": "."
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/penguin/ln3x7H1p1jL0Pwo7675NI_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

Kuaishou's Kling AI Avatar v2 Pro transforms static images into synchronized talking avatar videos at \$0.115 per second of output. Trading simplicity for production-grade lip sync and motion quality, this premium endpoint handles realistic humans, animals, cartoons, and stylized characters without manual rigging. Built for content creators who need broadcast-quality avatar videos without the technical overhead of traditional animation pipelines.

**Built for:** Marketing video production | Social media content | Character animation | Educational content | Podcast visualization

***

## Audio-Driven Animation Without the Complexity

Kling AI Avatar v2 Pro uses audio-synchronized motion generation to animate any portrait or character image. Unlike traditional animation workflows that require rigging, keyframing, and manual lip sync adjustment, this model maps audio waveforms directly to facial movements and expressions.

**What this means for you:**

* **Simple dual-input API:** Upload one portrait photo (JPG, PNG, WebP, GIF, AVIF) plus one audio file (MP3, OGG, WAV, M4A, AAC) to generate synchronized avatar videos
* **Natural lip synchronization:** Audio-driven facial animation matches speech patterns without manual keyframe adjustment
* **Multi-character support:** Works across realistic humans, animals, cartoon styles, and stylized characters from the same endpoint
* **Production-ready output:** Generate avatar videos suitable for commercial use at broadcast quality standards
* **Optional prompt refinement:** Include text prompts to guide subtle aspects of the animation beyond audio synchronization

***

## Performance That Scales

Pricing scales linearly with output duration, making cost predictable for batch production workflows.

| Metric                 | Result               | Context                                                                                                        |
| :--------------------- | :------------------- | :------------------------------------------------------------------------------------------------------------- |
| **Cost per Second**    | \$0.115              | Approximately 8.7 seconds of video per \$1.00 on fal                                                           |
| **Cost per Minute**    | \$6.90               | Predictable scaling for longer content                                                                         |
| **Standard Tier Cost** | \$0.0562/second      | [Kling AI Avatar v2 Standard](https://fal.ai/models/fal-ai/kling-video/ai-avatar/v2/standard) at \~49% savings |
| **Output Duration**    | Matches audio length | Video automatically scaled to audio file duration                                                              |

***

## Technical Specifications

| Spec                | Details                                   |
| :------------------ | :---------------------------------------- |
| **Architecture**    | Kling AI Avatar v2 Pro                    |
| **Image Formats**   | JPG, JPEG, PNG, WebP, GIF, AVIF           |
| **Audio Formats**   | MP3, OGG, WAV, M4A, AAC                   |
| **Output Format**   | MP4 video with synchronized audio         |
| **Generation Type** | Image-to-video with audio synchronization |
| **License**         | Commercial use permitted (Partner)        |

[API Documentation](https://fal.ai/models/fal-ai/kling-video/ai-avatar/v2/pro/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart)

***

## How It Stacks Up

**[Kling AI Avatar v2 Standard](https://fal.ai/models/fal-ai/kling-video/ai-avatar/v2/standard)** – Kling AI Avatar v2 Pro delivers enhanced facial detail and smoother lip-sync precision at $0.115/second versus Standard's $0.0562/second. Choose Pro for professional productions where output quality justifies the 2x cost premium, Standard for high-volume workflows where cost efficiency matters more.

**[Kling 2.5 Turbo Pro Image-to-Video](https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/image-to-video)** – Kling AI Avatar v2 Pro specializes in audio-synchronized avatar animation with automatic lip sync and facial motion for talking head content. Kling 2.5 Turbo Pro handles general image-to-video animation at $0.35 for 5 seconds ($0.07/additional second) without audio synchronization, for broader motion graphics and scene animation workflows.

**[Kling 2.1 Master Image-to-Video](https://fal.ai/models/fal-ai/kling-video/v2.1/master/image-to-video)** – Kling AI Avatar v2 Pro constrains generation around audio input for consistent character performance at $0.115/second. Kling 2.1 Master emphasizes maximum quality and cinematic motion at $1.40 for 5 seconds (\$0.28/additional second) for high-fidelity general video generation without audio synchronization.

**[Argil Avatars Audio-to-Video](https://fal.ai/models/argil/avatars/audio-to-video)** – Kling AI Avatar v2 Pro supports custom image input for any character style at $0.115/second with premium lip-sync quality. Argil Avatars uses pre-trained avatar templates at $0.02/second for 5.75x cost savings when custom character appearance isn't required.

## Related

* [Kling AI Avatar v2 Standard](/model-api-reference/video-generation-api/kling-ai-avatar-v2-standard) — Video Generation
* [Kling AI Avatar](/model-api-reference/video-generation-api/kling-ai-avatar) — Video Generation
* [Kling TTS](/model-api-reference/audio-api/kling-tts) — Audio
* [Kling AI Avatar Pro](/model-api-reference/video-generation-api/kling-ai-avatar-pro) — Video Generation
* [Kling AI Avatar v2 Pro](/model-api-reference/video-generation-api/kling-ai-avatar-v2-pro) — Video Generation


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-lipsync.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video Lipsync API

> API reference for Kling Video Lipsync. Kling LipSync is an audio-to-video model that generates realistic lip movements from audio input.

<Tabs>
  <Tab title="Audio To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/lipsync/audio-to-video`
    **Endpoint ID:** `fal-ai/kling-video/lipsync/audio-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/lipsync/audio-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/lipsync/audio-to-video",
          arguments={
              "video_url": "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
              "audio_url": "https://storage.googleapis.com/falserverless/kling/kling-audio.mp3"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/lipsync/audio-to-video", {
        input: {
            video_url: "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
            audio_url: "https://storage.googleapis.com/falserverless/kling/kling-audio.mp3"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/lipsync/audio-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "video_url": "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
        "audio_url": "https://storage.googleapis.com/falserverless/kling/kling-audio.mp3"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="video_url" type="string" required>
      The URL of the video to generate the lip sync for. Supports .mp4/.mov, ≤100MB, 2–10s, 720p/1080p only, width/height 720–1920px.
    </ParamField>

    <ParamField body="audio_url" type="string" required>
      The URL of the audio to generate the lip sync for. Minimum duration is 2s and maximum duration is 60s. Maximum file size is 5MB.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "video_url": "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
      "audio_url": "https://storage.googleapis.com/falserverless/kling/kling-audio.mp3"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/kling/kling_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/lipsync/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/lipsync/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/lipsync/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/lipsync/text-to-video",
          arguments={
              "video_url": "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
              "text": "Mental health is as important as physical health, shaping our emotions, thoughts, and daily interactions.",
              "voice_id": "genshin_klee2"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/lipsync/text-to-video", {
        input: {
            video_url: "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
            text: "Mental health is as important as physical health, shaping our emotions, thoughts, and daily interactions.",
            voice_id: "genshin_klee2"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/lipsync/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "video_url": "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
        "text": "Mental health is as important as physical health, shaping our emotions, thoughts, and daily interactions.",
        "voice_id": "genshin_klee2"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="video_url" type="string" required>
      The URL of the video to generate the lip sync for. Supports .mp4/.mov, ≤100MB, 2-60s, 720p/1080p only, width/height 720–1920px. If validation fails, an error is returned.
    </ParamField>

    <ParamField body="text" type="string" required>
      Text content for lip-sync video generation. Max 120 characters.
    </ParamField>

    <ParamField body="voice_id" type="VoiceIdEnum" required>
      Voice ID to use for speech synthesis

      Possible values: `genshin_vindi2`, `zhinen_xuesheng`, `AOT`, `ai_shatang`, `genshin_klee2`, `genshin_kirara`, `ai_kaiya`, `oversea_male1`, `ai_chenjiahao_712`, `girlfriend_4_speech02`, `chat1_female_new-3`, `chat_0407_5-1`, `cartoon-boy-07`, `uk_boy1`, `cartoon-girl-01`, `PeppaPig_platform`, `ai_huangzhong_712`, `ai_huangyaoshi_712`, `ai_laoguowang_712`, `chengshu_jiejie`, `you_pingjing`, `calm_story1`, `uk_man2`, `laopopo_speech02`, `heainainai_speech02`, `reader_en_m-v1`, `commercial_lady_en_f-v1`, `tiyuxi_xuedi`, `tiexin_nanyou`, `girlfriend_1_speech02`, `girlfriend_2_speech02`, `zhuxi_speech02`, `uk_oldman3`, `dongbeilaotie_speech02`, `chongqingxiaohuo_speech02`, `chuanmeizi_speech02`, `chaoshandashu_speech02`, `ai_taiwan_man2_speech02`, `xianzhanggui_speech02`, `tianjinjiejie_speech02`, `diyinnansang_DB_CN_M_04-v2`, `yizhipiannan-v1`, `guanxiaofang-v2`, `tianmeixuemei-v1`, `daopianyansang-v1`, `mengwa-v1`
    </ParamField>

    <ParamField body="voice_language" type="VoiceLanguageEnum" default="en">
      The voice language corresponding to the Voice ID Default value: `"en"`

      Possible values: `zh`, `en`
    </ParamField>

    <ParamField body="voice_speed" type="float" default="1">
      Speech rate for Text to Video generation Default value: `1`

      Range: `0.8` to `2`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "video_url": "https://fal.media/files/koala/8teUPbRRMtAUTORDvqy0l.mp4",
      "text": "Mental health is as important as physical health, shaping our emotions, thoughts, and daily interactions.",
      "voice_id": "genshin_klee2",
      "voice_language": "en",
      "voice_speed": 1
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/kling/kling_text_lipsync.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

Kuaishou's Kling LipSync generates realistic lip-synchronized video from audio input in approximately 12 minutes at \$0.014 per 5-second increment. Trading speed for precision lip-sync accuracy, the model handles 2-10 second source videos with audio up to 60 seconds. Purpose-built for dubbing, content localization, and audio-driven character animation where **mouth movement realism** matters more than generation time.

**Use Cases:** Video Dubbing & Translation | Audio-Driven Character Animation | Content Localization for Global Markets

***

## Performance

At \$0.014 per 5-second video increment (rounded up), Kling LipSync positions as a specialized audio-to-video tool trading inference speed for **lip-sync precision**. Processing takes approximately 12 minutes regardless of video duration within the 2-10 second input range.

| Metric                   | Result                   | Context                                              |
| :----------------------- | :----------------------- | :--------------------------------------------------- |
| **Inference Speed**      | \~12 minutes             | Fixed processing time for 2-10s input videos         |
| **Cost per Video**       | \$0.014 per 5s increment | Billed in 5-second increments (3s video = 5s charge) |
| **Input Video Duration** | 2-10 seconds             | 720p/1080p, ≤100MB, .mp4/.mov only                   |
| **Audio Duration**       | 2-60 seconds             | ≤5MB file size, .mp3/.wav/.ogg/.m4a/.aac formats     |
| **Resolution Support**   | 720p-1080p               | Width/height constrained to 720-1920px               |

***

## Precision Lip-Sync Without Training Data

Kling LipSync uses audio-driven facial animation architecture that generates mouth movements directly from audio waveforms without requiring speaker-specific training data, contrasting with traditional lip-sync approaches that need extensive footage of the target speaker.

**What this means for you:**

* **Zero-shot speaker adaptation:** Sync any audio to any face without pre-training on that specific person, enabling rapid dubbing workflows across multiple speakers and languages

* **Extended audio support:** Process up to 60 seconds of audio against 2-10 second video clips, useful for looping background characters or extending dialogue beyond source footage length

* **Format flexibility:** Accepts 5 audio formats (.mp3, .wav, .ogg, .m4a, .aac) and standard video containers (.mp4, .mov), integrating into existing [video generation workflows](https://fal.ai/models) without format conversion overhead

* **Increment-based pricing transparency:** 5-second billing increments mean predictable costs (a 3-second video costs the same as 5 seconds at $0.014, a 7-second video bills as 10 seconds at $0.028)

***

## Technical Specifications

| Spec                        | Details                                                                               |
| :-------------------------- | :------------------------------------------------------------------------------------ |
| **Architecture**            | Kling LipSync                                                                         |
| **Input Formats**           | Video: .mp4, .mov (2-10s, ≤100MB) / Audio: .mp3, .wav, .ogg, .m4a, .aac (2-60s, ≤5MB) |
| **Output Formats**          | .mp4 video with synchronized lip movements                                            |
| **Resolution Requirements** | 720p or 1080p input, width/height 720-1920px                                          |
| **License**                 | Commercial use via fal partnership                                                    |

[API Documentation](https://fal.ai/models/fal-ai/kling-video/lipsync/audio-to-video/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

## Related

* [Kling LipSync Text-to-Video](/model-api-reference/video-generation-api/kling-lipsync-text-to-video) — Video Generation
* [Kling LipSync Audio-to-Video](/model-api-reference/video-generation-api/kling-lipsync-audio-to-video) — Video Generation

## Limitations

* `voice_language` restricted to: `zh`, `en`
* `voice_speed` range: 0.8 to 2


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o1-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O1 Image To Video API

> API reference for Kling Video O1 Image To Video. Generate a video by taking a start frame and an end frame, animating the transition between them while following text-driven style and scene guidance.

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/image-to-video`
**Endpoint ID:** `fal-ai/kling-video/o1/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o1/image-to-video",
      arguments={
          "prompt": "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
          "start_image_url": "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o1/image-to-video", {
    input: {
        prompt: "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
        start_image_url: "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o1/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
    "start_image_url": "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png"
  }'
  ```
</CodeGroup>

Kuaishou's Kling O1 delivers first-frame-last-frame video generation at \$0.112 per second, animating precise transitions between two keyframes. Trading broad creative freedom for exact endpoint control, this specialized variant handles timelapse transformations, morphing sequences, and narrative scene transitions where both start and end states matter. Built for motion designers, creative studios, and developers who need deterministic video outputs rather than open-ended generation.

**Built for:** Timelapse animations | Product transformation sequences | Narrative scene transitions

***

## Dual-Keyframe Control Architecture

Kling O1's dual-keyframe approach inverts the standard image-to-video workflow by accepting both start and end images as constraints, then synthesizing the motion path between them. Where traditional image-to-video models extrapolate freely from a single frame, this variant interpolates along a defined trajectory while respecting prompt-driven style guidance.

**What this means for you:**

* **Deterministic endpoints:** Generate 5 or 10-second videos where both opening and closing frames match your exact specifications, critical for brand-consistent sequences or narrative continuity
* **Controlled transformation arcs:** Animate seasonal changes, product evolutions, or character state transitions with predictable motion paths rather than AI-improvised endings
* **Prompt-guided interpolation:** Reference start and end frames via `@Image1` and `@Image2` in prompts to direct style, camera movement, and scene dynamics during the transition
* **Flexible duration options:** Choose between 5-second ($0.56) or 10-second ($1.12) outputs to match pacing requirements for social media clips or longer editorial sequences

***

## Performance Scaling

Kling O1 operates within Kuaishou's broader Kling Video ecosystem, prioritizing frame-accurate transitions over generation speed.

| Metric                 | Result                            | Context                                                          |
| :--------------------- | :-------------------------------- | :--------------------------------------------------------------- |
| **Duration Options**   | 5s or 10s                         | Configurable via `duration` parameter                            |
| **Cost per Video**     | $0.56 (5s) or $1.12 (10s)         | Based on \$0.112 per second rate                                 |
| **Input Requirements** | Start + end frame (both required) | Min 300px dimensions, 0.40-2.50 aspect ratio, 10MB max per image |
| **Output Format**      | MP4 video                         | Single video file with synthesized motion path                   |

***

## Technical Specifications

| Spec                 | Details                                                                         |
| :------------------- | :------------------------------------------------------------------------------ |
| **Architecture**     | Kling O1                                                                        |
| **Input Formats**    | Start image (required), end image (required), text prompt with frame references |
| **Output Formats**   | MP4 video                                                                       |
| **Duration Options** | 5 seconds or 10 seconds                                                         |
| **Prompt Syntax**    | Use `@Image1` and `@Image2` to reference uploaded keyframes in prompts          |
| **License**          | Commercial use via fal partnership                                              |

[API Documentation](https://fal.ai/models/fal-ai/kling-video/o1/image-to-video/llms.txt)

***

## How It Stacks Up

**Kling Video Image to Video (v2.5-turbo)** - Kling O1 specializes in dual-keyframe interpolation for transformation sequences where endpoint precision matters, making it ideal for timelapse effects and morphing animations. [Kling Video v2.5-turbo](https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/image-to-video) emphasizes single-frame extrapolation with faster generation speeds for open-ended creative exploration.

**Kling 2.0 Master Image to Video** - Kling O1 trades generation flexibility for endpoint accuracy, constraining motion paths between two defined frames at a specialized price point. [Kling 2.0 Master](https://fal.ai/models/fal-ai/kling-video/v2/master/image-to-video) prioritizes maximum quality single-frame animation for premium production workflows requiring cinematic motion without endpoint constraints.

## Related

* [Kling O1 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-edit-video) — Video Generation
* [Kling O1 First Frame Last Frame to Video \[Standard\]](/model-api-reference/video-generation-api/kling-o1-first-frame-last-frame-to-video) — Video Generation
* [Kling O1 Reference Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-image-to-video) — Video Generation
* [Kling O1 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  Use @Image1 to reference the start frame, @Image2 to reference the end frame.
</ParamField>

<ParamField body="start_image_url" type="string" required>
  Image to use as the first frame of the video.

  Max file size: 10.0MB, Min width: 300px, Min height: 300px, Min aspect ratio: 0.40, Max aspect ratio: 2.50, Timeout: 20.0s
</ParamField>

<ParamField body="end_image_url" type="string">
  Image to use as the last frame of the video.
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds. Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
  "start_image_url": "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png",
  "end_image_url": "https://v3b.fal.media/files/b/tiger/BwHi22qoQnqaTNMMhe533.png",
  "duration": "5"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 27588984,
    "url": "https://v3b.fal.media/files/b/koala/knryyyGF3ZVyMMrGr77CL_output.mp4"
  }
}
```

## Limitations

* `duration` restricted to: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o1-reference-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O1 Reference To Video API

> API reference for Kling Video O1 Reference To Video. Transform images, elements, and text into consistent, high-quality video scenes, ensuring stable character identity, object details, and environmen

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/reference-to-video`
**Endpoint ID:** `fal-ai/kling-video/o1/reference-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/reference-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o1/reference-to-video",
      arguments={
          "prompt": "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o1/reference-to-video", {
    input: {
        prompt: "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o1/reference-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2."
  }'
  ```
</CodeGroup>

Kuaishou Technology's Kling O1 Reference transforms static images into consistent video sequences at \$0.112 per second, supporting up to 7 simultaneous reference inputs. Trading single-input simplicity for multi-element consistency, it maintains stable character and object identity across complex compositions through specialized reference conditioning. Built for narrative sequences requiring character continuity, product demonstrations with consistent styling, and complex scene transitions where object identity must persist frame-to-frame.

**Built for:** Multi-character storytelling | Brand-consistent product videos | Complex scene transitions with stable elements

***

## Multi-Reference Architecture for Consistent Generation

Kling O1 Reference uses a specialized reference-conditioning system that processes frontal images and multiple reference angles per element, then maintains their identity throughout generated video sequences. Unlike standard image-to-video models that treat input as a single keyframe, this architecture tracks multiple elements independently while preserving their visual characteristics across camera movements and scene changes.

**What this means for you:**

* **Up to 7 simultaneous inputs:** Combine tracked elements (characters/objects with frontal + reference angles), style reference images, and an optional start frame in a single generation. Reference them in prompts as @Element1, @Element2 for tracked objects or @Image1, @Image2 for style references and start frames.
* **Element-level consistency:** Each tracked element supports one frontal image plus multiple reference angles, ensuring characters and objects maintain identity through complex camera movements and transitions
* **Flexible duration control:** Generate 5-second ($0.56) or 10-second ($1.12) sequences at 16:9, 9:16, or 1:1 aspect ratios for platform-specific content optimization
* **Prompt-driven scene control:** Direct camera movements, lighting, and transitions through natural language while the model maintains element consistency. Specify "Take @Image1 as the start frame" to control the video's opening frame.

**Example input structure:** 2 tracked elements (character + object) + 2 style references + 1 start frame = 5 of 7 available inputs

***

## Performance Scaling

Kling O1 Reference prioritizes multi-element consistency over generation speed, with pricing scaled to video duration.

| Metric               | Result                    | Context                                                |
| :------------------- | :------------------------ | :----------------------------------------------------- |
| **Cost per Video**   | $0.56 (5s) or $1.12 (10s) | Based on \$0.112 per second rate                       |
| **Duration Options** | 5s or 10s                 | Fixed durations for consistent output quality          |
| **Maximum Inputs**   | 7 total                   | Combined: elements + reference images + start frame    |
| **Aspect Ratios**    | 16:9, 9:16, 1:1           | Platform-optimized formats for social, web, and mobile |

***

## Technical Specifications

| Spec               | Details                                                                                                                        |
| :----------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| **Architecture**   | Kling O1 Reference Image to Video                                                                                              |
| **Input Formats**  | Image URLs (JPG, JPEG, PNG, WebP, GIF, AVIF) + text prompts                                                                    |
| **Output Formats** | MP4 video                                                                                                                      |
| **Video Duration** | 5 or 10 seconds                                                                                                                |
| **Aspect Ratios**  | 16:9, 9:16, 1:1                                                                                                                |
| **Input Types**    | Elements (frontal + reference angles, tracked), Reference Images (style/appearance guides), Start Frame (optional first frame) |
| **Prompt Syntax**  | @Element1, @Element2 for tracked objects; @Image1, @Image2 for references/start frame                                          |
| **License**        | Commercial use (Partner)                                                                                                       |

[API Documentation](https://fal.ai/models/fal-ai/kling-video/o1/reference-to-video/api)

***

## How It Stacks Up

**Kling Video Image to Video (v2.5-turbo)** - Kling O1 Reference trades single-input simplicity for multi-element consistency, making it ideal for narratives requiring multiple characters or objects with stable identity across camera movements. [Kling Video v2.5-turbo](https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/image-to-video) prioritizes single-image animation for straightforward transformations where element tracking isn't required.

**Kling 1.6 Image to Video** - Kling O1 Reference offers advanced element-level control through its reference system for complex multi-character scenes. [Kling 1.6](https://fal.ai/models/fal-ai/kling-video/v1.6/pro/image-to-video) provides established performance for standard image-to-video workflows without multi-reference capabilities.

## Related

* [Kling O1 First Frame Last Frame to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-first-frame-last-frame-to-video) — Video Generation
* [Kling O1 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-edit-video) — Video Generation
* [Kling O1 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-video-to-video) — Video Generation
* [Kling O1 Reference Image to Video \[Standard\]](/model-api-reference/video-generation-api/kling-o1-reference-image-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  Take @Element1, @Element2 to reference elements and @Image1, @Image2 to reference images in order.
</ParamField>

<ParamField body="image_urls" type="list<string>">
  Additional reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 7 total (elements + reference images + start image).
</ParamField>

<ParamField body="elements" type="list<OmniVideoElementInput>">
  Elements (characters/objects) to include in the video. Reference in prompt as @Element1, @Element2, etc. Maximum 7 total (elements + reference images + start image).
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds. Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  The aspect ratio of the generated video frame. Default value: `"16:9"`

  Possible values: `16:9`, `9:16`, `1:1`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2.",
  "image_urls": [
    "https://v3b.fal.media/files/b/koala/v9COzzH23FGBYdGLgbK3u.png",
    "https://v3b.fal.media/files/b/elephant/5Is2huKQFSE7A7c5uUeUF.png"
  ],
  "elements": [
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/panda/MQp-ghIqshvMZROKh9lW3.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/kangaroo/YMpmQkYt9xugpOTQyZW0O.png",
        "https://v3b.fal.media/files/b/zebra/d6ywajNyJ6bnpa_xBue-K.png"
      ]
    },
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/koala/gSnsA7HJlgcaTyR5Ujj2H.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/kangaroo/EBF4nWihspyv4pp6hgj7D.png"
      ]
    }
  ],
  "duration": "5",
  "aspect_ratio": "16:9"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 47359974,
    "url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
  }
}
```

## Limitations

* `duration` restricted to: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o1-standard-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O1 Standard Image To Video API

> API reference for Kling Video O1 Standard Image To Video. Generate a video by taking a start frame and an end frame, animating the transition between them while following text-driven style and scene g

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/standard/image-to-video`
**Endpoint ID:** `fal-ai/kling-video/o1/standard/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/standard/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o1/standard/image-to-video",
      arguments={
          "prompt": "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
          "start_image_url": "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o1/standard/image-to-video", {
    input: {
        prompt: "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
        start_image_url: "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o1/standard/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
    "start_image_url": "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png"
  }'
  ```
</CodeGroup>

## Related

* [Kling O1 First Frame Last Frame to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-first-frame-last-frame-to-video) — Video Generation
* [Kling O1 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-edit-video) — Video Generation
* [Kling O1 Reference Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-image-to-video) — Video Generation
* [Kling O1 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  Use @Image1 to reference the start frame, @Image2 to reference the end frame.
</ParamField>

<ParamField body="start_image_url" type="string" required>
  Image to use as the first frame of the video.

  Max file size: 10.0MB, Min width: 300px, Min height: 300px, Min aspect ratio: 0.40, Max aspect ratio: 2.50, Timeout: 20.0s
</ParamField>

<ParamField body="end_image_url" type="string">
  Image to use as the last frame of the video.
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds. Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Create a magical timelapse transition. The snow melts rapidly to reveal green grass, and the tree branches burst into bloom with pink flowers in real-time. The lighting shifts from cold winter light to warm spring sunshine. The camera pushes in slowly towards the tree. Disney-style magical transformation, cinematic, 8k.",
  "start_image_url": "https://v3b.fal.media/files/b/rabbit/NaslJIC7F2WodS6DFZRRJ.png",
  "end_image_url": "https://v3b.fal.media/files/b/tiger/BwHi22qoQnqaTNMMhe533.png",
  "duration": "5"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 27588984,
    "url": "https://v3b.fal.media/files/b/koala/knryyyGF3ZVyMMrGr77CL_output.mp4"
  }
}
```

## Limitations

* `duration` restricted to: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o1-standard-reference-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O1 Standard Reference To Video API

> API reference for Kling Video O1 Standard Reference To Video. Transform images, elements, and text into consistent, high-quality video scenes, ensuring stable character identity, object details, and e

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/standard/reference-to-video`
**Endpoint ID:** `fal-ai/kling-video/o1/standard/reference-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/standard/reference-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o1/standard/reference-to-video",
      arguments={
          "prompt": "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o1/standard/reference-to-video", {
    input: {
        prompt: "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o1/standard/reference-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2."
  }'
  ```
</CodeGroup>

## Related

* [Kling O1 First Frame Last Frame to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-first-frame-last-frame-to-video) — Video Generation
* [Kling O1 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-edit-video) — Video Generation
* [Kling O1 Reference Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-image-to-video) — Video Generation
* [Kling O1 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  Take @Element1, @Element2 to reference elements and @Image1, @Image2 to reference images in order.
</ParamField>

<ParamField body="image_urls" type="list<string>">
  Additional reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 7 total (elements + reference images + start image).
</ParamField>

<ParamField body="elements" type="list<OmniVideoElementInput>">
  Elements (characters/objects) to include in the video. Reference in prompt as @Element1, @Element2, etc. Maximum 7 total (elements + reference images + start image).
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds. Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  The aspect ratio of the generated video frame. Default value: `"16:9"`

  Possible values: `16:9`, `9:16`, `1:1`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Take @Image1 as the start frame. Start with a high-angle satellite view of the ancient greenhouse ruin surrounded by nature. The camera swoops down and flies inside the building, revealing the character from @Element1 standing in the sun-drenched center. The camera then seamlessly transitions into a smooth 180-degree orbit around the character, moving to the back view. As the open backpack comes into focus, the camera continues to push forward, zooming deep inside the bag to reveal the glowing stone from @Element2 nestled inside. Cinematic lighting, hopeful atmosphere, 35mm lens. Make sure to keep it as the style of @Image2.",
  "image_urls": [
    "https://v3b.fal.media/files/b/koala/v9COzzH23FGBYdGLgbK3u.png",
    "https://v3b.fal.media/files/b/elephant/5Is2huKQFSE7A7c5uUeUF.png"
  ],
  "elements": [
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/panda/MQp-ghIqshvMZROKh9lW3.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/kangaroo/YMpmQkYt9xugpOTQyZW0O.png",
        "https://v3b.fal.media/files/b/zebra/d6ywajNyJ6bnpa_xBue-K.png"
      ]
    },
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/koala/gSnsA7HJlgcaTyR5Ujj2H.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/kangaroo/EBF4nWihspyv4pp6hgj7D.png"
      ]
    }
  ],
  "duration": "5",
  "aspect_ratio": "16:9"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 47359974,
    "url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
  }
}
```

## Limitations

* `duration` restricted to: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o1-standard-video-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O1 Standard Video To Video API

> API reference for Kling Video O1 Standard Video To Video. Edit an existing video using natural-language instructions, transforming subjects, settings, and style while retaining the original motion str

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/standard/video-to-video/edit`
    **Endpoint ID:** `fal-ai/kling-video/o1/standard/video-to-video/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/standard/video-to-video/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o1/standard/video-to-video/edit",
          arguments={
              "prompt": "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
              "video_url": "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o1/standard/video-to-video/edit", {
        input: {
            prompt: "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
            video_url: "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o1/standard/video-to-video/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
        "video_url": "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Use @Element1, @Element2 to reference elements and @Image1, @Image2 to reference images in order.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats supported, 3-10 seconds duration, 720-2160px resolution, max 200MB.

      Max file size: 200.0MB, Min width: 720px, Min height: 720px, Max width: 2160px, Max height: 2160px, Min duration: 3.0s, Max duration: 10.05s, Min FPS: 24.0, Max FPS: 60.0, Timeout: 30.0s
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="false">
      Whether to keep the original audio from the video.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="elements" type="list<OmniVideoElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
      "video_url": "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4",
      "keep_audio": false,
      "image_urls": [
        "https://v3b.fal.media/files/b/lion/MKvhFko5_wYnfORYacNII_AgPt8v25Wt4oyKhjnhVK5.png"
      ],
      "elements": [
        {
          "frontal_image_url": "https://v3b.fal.media/files/b/panda/MQp-ghIqshvMZROKh9lW3.png",
          "reference_image_urls": [
            "https://v3b.fal.media/files/b/kangaroo/YMpmQkYt9xugpOTQyZW0O.png",
            "https://v3b.fal.media/files/b/zebra/d6ywajNyJ6bnpa_xBue-K.png"
          ]
        }
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 7533071,
        "url": "https://v3b.fal.media/files/b/0a86603b/YAlbB2535l07BTy1wpDeI_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Reference">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/standard/video-to-video/reference`
    **Endpoint ID:** `fal-ai/kling-video/o1/standard/video-to-video/reference`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/standard/video-to-video/reference/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o1/standard/video-to-video/reference",
          arguments={
              "prompt": "Based on @Video1, generate the next shot. keep the style of the video",
              "video_url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o1/standard/video-to-video/reference", {
        input: {
            prompt: "Based on @Video1, generate the next shot. keep the style of the video",
            video_url: "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o1/standard/video-to-video/reference \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Based on @Video1, generate the next shot. keep the style of the video",
        "video_url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Use @Element1, @Element2 to reference elements and @Image1, @Image2 to reference images in order.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats supported, 3-10 seconds duration, 720-2160px resolution, max 200MB.

      Max file size: 200.0MB, Min width: 720px, Min height: 720px, Max width: 2160px, Max height: 2160px, Min duration: 3.0s, Max duration: 10.05s, Min FPS: 24.0, Max FPS: 60.0, Timeout: 30.0s
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="false">
      Whether to keep the original audio from the video.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="elements" type="list<OmniVideoElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video frame. If 'auto', the aspect ratio will be determined automatically based on the input video, and the closest aspect ratio to the input video will be used. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Video duration in seconds. Default value: `"5"`

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Based on @Video1, generate the next shot. keep the style of the video",
      "video_url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4",
      "keep_audio": false,
      "image_urls": [],
      "elements": [
        {
          "frontal_image_url": "https://v3b.fal.media/files/b/panda/MQp-ghIqshvMZROKh9lW3.png",
          "reference_image_urls": [
            "https://v3b.fal.media/files/b/kangaroo/YMpmQkYt9xugpOTQyZW0O.png",
            "https://v3b.fal.media/files/b/zebra/d6ywajNyJ6bnpa_xBue-K.png"
          ]
        }
      ],
      "aspect_ratio": "auto",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 28472159,
        "url": "https://v3b.fal.media/files/b/kangaroo/3n_Lpxm_SjK5NYyBobRdS_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling O1 First Frame Last Frame to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-first-frame-last-frame-to-video) — Video Generation
* [Kling O1 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-edit-video) — Video Generation
* [Kling O1 Reference Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-image-to-video) — Video Generation
* [Kling O1 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-video-to-video) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`, `1:1`
* `duration` restricted to: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o1-video-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O1 Video To Video API

> API reference for Kling Video O1 Video To Video. Edit an existing video using natural-language instructions, transforming subjects, settings, and style while retaining the original motion structure.

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/video-to-video/edit`
    **Endpoint ID:** `fal-ai/kling-video/o1/video-to-video/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/video-to-video/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o1/video-to-video/edit",
          arguments={
              "prompt": "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
              "video_url": "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o1/video-to-video/edit", {
        input: {
            prompt: "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
            video_url: "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o1/video-to-video/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
        "video_url": "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Use @Element1, @Element2 to reference elements and @Image1, @Image2 to reference images in order.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats supported, 3-10 seconds duration, 720-2160px resolution, max 200MB.

      Max file size: 200.0MB, Min width: 720px, Min height: 720px, Max width: 2160px, Max height: 2160px, Min duration: 3.0s, Max duration: 10.05s, Min FPS: 24.0, Max FPS: 60.0, Timeout: 30.0s
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="false">
      Whether to keep the original audio from the video.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="elements" type="list<OmniVideoElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Replace the character in the video with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1",
      "video_url": "https://v3b.fal.media/files/b/rabbit/ku8_Wdpf-oTbGRq4lB5DU_output.mp4",
      "keep_audio": false,
      "image_urls": [
        "https://v3b.fal.media/files/b/lion/MKvhFko5_wYnfORYacNII_AgPt8v25Wt4oyKhjnhVK5.png"
      ],
      "elements": [
        {
          "frontal_image_url": "https://v3b.fal.media/files/b/panda/MQp-ghIqshvMZROKh9lW3.png",
          "reference_image_urls": [
            "https://v3b.fal.media/files/b/kangaroo/YMpmQkYt9xugpOTQyZW0O.png",
            "https://v3b.fal.media/files/b/zebra/d6ywajNyJ6bnpa_xBue-K.png"
          ]
        }
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 7533071,
        "url": "https://v3b.fal.media/files/b/0a86603b/YAlbB2535l07BTy1wpDeI_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Reference">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o1/video-to-video/reference`
    **Endpoint ID:** `fal-ai/kling-video/o1/video-to-video/reference`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o1/video-to-video/reference/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o1/video-to-video/reference",
          arguments={
              "prompt": "Based on @Video1, generate the next shot. keep the style of the video",
              "video_url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o1/video-to-video/reference", {
        input: {
            prompt: "Based on @Video1, generate the next shot. keep the style of the video",
            video_url: "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o1/video-to-video/reference \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Based on @Video1, generate the next shot. keep the style of the video",
        "video_url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Use @Element1, @Element2 to reference elements and @Image1, @Image2 to reference images in order.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats supported, 3-10 seconds duration, 720-2160px resolution, max 200MB.

      Max file size: 200.0MB, Min width: 720px, Min height: 720px, Max width: 2160px, Max height: 2160px, Min duration: 3.0s, Max duration: 10.05s, Min FPS: 24.0, Max FPS: 60.0, Timeout: 30.0s
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="false">
      Whether to keep the original audio from the video.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="elements" type="list<OmniVideoElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video frame. If 'auto', the aspect ratio will be determined automatically based on the input video, and the closest aspect ratio to the input video will be used. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      Video duration in seconds. Default value: `"5"`

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Based on @Video1, generate the next shot. keep the style of the video",
      "video_url": "https://v3b.fal.media/files/b/panda/oVdiICFXY03Vbam-08Aj8_output.mp4",
      "keep_audio": false,
      "image_urls": [],
      "elements": [
        {
          "frontal_image_url": "https://v3b.fal.media/files/b/panda/MQp-ghIqshvMZROKh9lW3.png",
          "reference_image_urls": [
            "https://v3b.fal.media/files/b/kangaroo/YMpmQkYt9xugpOTQyZW0O.png",
            "https://v3b.fal.media/files/b/zebra/d6ywajNyJ6bnpa_xBue-K.png"
          ]
        }
      ],
      "aspect_ratio": "auto",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 28472159,
        "url": "https://v3b.fal.media/files/b/kangaroo/3n_Lpxm_SjK5NYyBobRdS_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

Kuaishou's Kling O1 Edit delivers natural language video transformation at \$0.168 per second, trading traditional masking workflows for prompt-based editing that preserves original motion structure. The model accepts up to 4 combined reference elements and images, enabling complex character swaps and environment transformations through simple text commands.

**Built for:** Character replacement in existing footage | Scene environment transformations | Style transfer while maintaining motion

***

## Context-Aware Video Transformation Without Masking

Kling O1 Edit operates on a fundamentally different approach than frame-by-frame editing tools: it understands the entire motion structure of your input video and applies transformations that respect camera angles, movement patterns, and spatial relationships. Where traditional video editing requires manual masking and frame-level adjustments, this model interprets natural language instructions and applies them across the full video duration.

**What this means for you:**

* **Multi-reference editing:** Combine up to 4 total elements and reference images in a single transformation, enabling complex character swaps with specific style references
* **Motion preservation:** Original camera movements and subject motion remain intact while subjects, settings, and visual style transform according to your prompt
* **Natural language control:** Direct the edit through conversational instructions rather than technical parameters. Example: "Replace the character with @Element1, maintaining the same movements and camera angles. Transform the landscape into @Image1"
* **Audio preservation:** Choose to keep original audio from your source video or generate silent output through the keep\_audio parameter
* **Element structure:** Each element accepts one frontal image plus multiple reference angles (frontal\_image\_url + reference\_image\_urls array), giving the model comprehensive visual context for accurate transformations

***

## Performance That Scales

Kling O1 Edit's per-second pricing model reflects the computational complexity of motion-preserving video transformation, with costs scaling directly to your input video duration.

| Metric                 | Result        | Context                                                |
| :--------------------- | :------------ | :----------------------------------------------------- |
| **Cost per Video**     | $0.50-$1.68   | Based on 3-10 second input duration at \$0.168/second  |
| **Input Duration**     | 3-10 seconds  | Supports .mp4, .mov, .webm, .m4v, .gif up to 200MB     |
| **Resolution Range**   | 720-2160px    | Accepts standard HD through 4K input resolutions       |
| **Reference Capacity** | Up to 4 total | Combined limit for elements and style reference images |

***

## Technical Specifications

| Spec               | Details                                                                                         |
| :----------------- | :---------------------------------------------------------------------------------------------- |
| **Architecture**   | Kling O1 Edit                                                                                   |
| **Input Formats**  | Video (.mp4, .mov, .webm, .m4v, .gif), reference images (.jpg, .jpeg, .png, .webp, .gif, .avif) |
| **Output Formats** | .mp4 video                                                                                      |
| **Video Duration** | 3-10 seconds (output matches input duration)                                                    |
| **Audio Handling** | Optional audio preservation via keep\_audio parameter (default: false)                          |
| **Prompt Syntax**  | @Element1, @Element2 for tracked elements; @Image1, @Image2 for style references                |
| **License**        | Commercial use via fal partnership                                                              |

[API Documentation](https://fal.ai/models/fal-ai/kling-video/o1/video-to-video/edit/api)

***

## How It Stacks Up

**Sora 2 Video to Video** - Kling O1 Edit prioritizes multi-reference element control with up to 4 combined inputs for complex character and environment transformations. [Sora 2's remix capabilities](https://fal.ai/models/fal-ai/sora-2/video-to-video/remix) emphasize broader creative reinterpretation and style transfer across longer video durations, ideal for narrative content that requires substantial visual reimagining.

**Wan Video to Video** - Kling O1 Edit's natural language interface eliminates technical parameter tuning, making it accessible for creators who want direct prompt-based control. [Wan's video-to-video endpoint](https://fal.ai/models/fal-ai/wan/v2.2-a14b/video-to-video) offers granular parameter control for users who need precise technical adjustments in their transformation workflows.

**AnimateDiff Video to Video** - Kling O1 Edit maintains original motion structure while transforming visual content, preserving the exact camera movements and subject actions from your source footage. [AnimateDiff](https://fal.ai/models/fal-ai/fast-animatediff/video-to-video) focuses on animation-style transformations and motion synthesis, serving creators building stylized or animated content from video references.

## Related

* [Kling O1 First Frame Last Frame to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-first-frame-last-frame-to-video) — Video Generation
* [Kling O1 Reference Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-image-to-video) — Video Generation
* [Kling O1 Edit Video \[Standard\]](/model-api-reference/video-generation-api/kling-o1-edit-video) — Video Generation
* [Kling O1 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o1-reference-video-to-video) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`, `1:1`
* `duration` restricted to: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-pro-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Pro Image To Video API

> API reference for Kling Video O3 Pro Image To Video. Generate a video by taking a start frame and an end frame, animating the transition between them while following text-driven style and scene guidan

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/pro/image-to-video`
**Endpoint ID:** `fal-ai/kling-video/o3/pro/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/pro/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o3/pro/image-to-video",
      arguments={
          "image_url": "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o3/pro/image-to-video", {
    input: {
        image_url: "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o3/pro/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png"
  }'
  ```
</CodeGroup>

## Examples

> The character walks forward slowly, with the camera following from behind.

<video src="https://v3b.fal.media/files/b/0a932ef6/Qxfmb0COHKJdwlePT_7Xb_output.mp4" controls width="100%" />

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Reference to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation
* [Kling O3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Image input
* Duration control

## API Reference

### Input Schema

<ParamField body="prompt" type="string">
  Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
</ParamField>

<ParamField body="image_url" type="string" required>
  URL of the start frame image.
</ParamField>

<ParamField body="end_image_url" type="string">
  URL of the end frame image (optional).
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds (3-15s). Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="false">
  Whether to generate native audio for the video.
</ParamField>

<ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
  List of prompts for multi-shot video generation.
</ParamField>

<ParamField body="shot_type" type="string" default="customize">
  The type of multi-shot video generation. Default value: `"customize"`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "The character walks forward slowly, with the camera following from behind.",
  "image_url": "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png",
  "end_image_url": "https://v3b.fal.media/files/b/0a8d0248/S415GcxackjjLKom6f3jq_VTImWrNO.png",
  "duration": "10",
  "generate_audio": false,
  "multi_prompt": null,
  "shot_type": "customize"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 12037975,
    "url": "https://v3b.fal.media/files/b/0a8d0278/pgIO9yOXTFCTetKBsqDwX_output.mp4"
  }
}
```


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-pro-reference-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Pro Reference To Video API

> API reference for Kling Video O3 Pro Reference To Video. Transform images, elements, and text into consistent, high-quality video scenes, ensuring stable character identity, object details, and enviro

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/pro/reference-to-video`
**Endpoint ID:** `fal-ai/kling-video/o3/pro/reference-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/pro/reference-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o3/pro/reference-to-video",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o3/pro/reference-to-video", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o3/pro/reference-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation
* [Kling O3 Reference to Video \[Standard\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string">
  Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
</ParamField>

<ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
  List of prompts for multi-shot video generation.
</ParamField>

<ParamField body="start_image_url" type="string">
  Image to use as the first frame of the video.
</ParamField>

<ParamField body="end_image_url" type="string">
  Image to use as the last frame of the video.
</ParamField>

<ParamField body="image_urls" type="list<string>">
  Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
</ParamField>

<ParamField body="elements" type="list<KlingV3ComboElementInput>">
  Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2.
</ParamField>

<ParamField body="generate_audio" type="boolean" default="false">
  Whether to generate native audio for the video.
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds (3-15s). Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="shot_type" type="string" default="customize">
  The type of multi-shot video generation. Default value: `"customize"`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  The aspect ratio of the generated video frame. Default value: `"16:9"`

  Possible values: `16:9`, `9:16`, `1:1`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "@Element1 and @Element2 enters the scene from two sides. Elephant starts to play with the ball",
  "multi_prompt": null,
  "start_image_url": "https://v3b.fal.media/files/b/0a8d1b38/myilPNN_WYdJCmpTy4Sjr_6XNBi9Mm.png",
  "elements": [
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/0a8d1b2e/yiHiZP1Now0V5JC5_OClE_PaKOtOGJ.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/0a8d1b1a/eZfSbcQ58EzD_l2SEbevg_F3U9GMLK.png"
      ]
    },
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/0a8d1b19/_eIj7GjmI5zgQkMN936YJ_2f3hZ7Xb.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/0a8d1b3c/_ZE2iIjkb-Eun3WXXGP4x_TSG1ELBo.png"
      ]
    }
  ],
  "generate_audio": false,
  "duration": "8",
  "shot_type": "customize",
  "aspect_ratio": "16:9"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 18468404,
    "url": "https://v3b.fal.media/files/b/0a8d1c8a/ZxdKrvPb3CQEmeuS-u_kU_output.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-pro-text-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Pro Text To Video API

> API reference for Kling Video O3 Pro Text To Video. Generate realistic videos using Kling O3 from Kling Team!

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/pro/text-to-video`
**Endpoint ID:** `fal-ai/kling-video/o3/pro/text-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/pro/text-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o3/pro/text-to-video",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o3/pro/text-to-video", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o3/pro/text-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Reference to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation
* [Kling O3 Text to Video \[Standard\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string">
  Text prompt for video generation. Required unless multi\_prompt is provided.
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds (3-15s). Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  Aspect ratio of the generated video. Default value: `"16:9"`

  Possible values: `16:9`, `9:16`, `1:1`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="false">
  Whether to generate native audio for the video.
</ParamField>

<ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
  List of prompts for multi-shot video generation.
</ParamField>

<ParamField body="shot_type" type="string" default="customize">
  The type of multi-shot video generation. Default value: `"customize"`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A mecha lands on the ground to save the city, and says \"I'm here\", in anime style",
  "duration": "5",
  "aspect_ratio": "16:9",
  "generate_audio": false,
  "multi_prompt": null,
  "shot_type": "customize"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 13096952,
    "url": "https://v3b.fal.media/files/b/0a8d04e2/idOb9V-Q9ujlggPSKqsfS_output.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-pro-video-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Pro Video To Video API

> API reference for Kling Video O3 Pro Video To Video. Edit videos using Kling O3 from Kling Team!

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/pro/video-to-video/edit`
    **Endpoint ID:** `fal-ai/kling-video/o3/pro/video-to-video/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/pro/video-to-video/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o3/pro/video-to-video/edit",
          arguments={
              "prompt": "Change environment to be fully snow as @Image1. Replace animal with @Element1",
              "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-edit/video_reference.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o3/pro/video-to-video/edit", {
        input: {
            prompt: "Change environment to be fully snow as @Image1. Replace animal with @Element1",
            video_url: "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-edit/video_reference.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o3/pro/video-to-video/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Change environment to be fully snow as @Image1. Replace animal with @Element1",
        "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-edit/video_reference.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text prompt for video generation. Reference video as @Video1.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats, 3-10s duration, 720-2160px resolution, max 200MB.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="true">
      Whether to keep the original audio from the reference video. Default value: `true`
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ImageElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2.
    </ParamField>

    <ParamField body="shot_type" type="string" default="customize">
      The type of multi-shot video generation. Default value: `"customize"`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Change environment to be fully snow as @Image1. Replace animal with @Element1",
      "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-edit/video_reference.mp4",
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-edit/image_url1.jpg"
      ],
      "keep_audio": true,
      "elements": [
        {
          "frontal_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-edit/element1_front.png",
          "reference_image_urls": [
            "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-edit/element1_reference1.png"
          ]
        }
      ],
      "shot_type": "customize"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 4322769,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-o3/pro-v2v-edit/output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Reference">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/pro/video-to-video/reference`
    **Endpoint ID:** `fal-ai/kling-video/o3/pro/video-to-video/reference`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/pro/video-to-video/reference/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o3/pro/video-to-video/reference",
          arguments={
              "prompt": "Integrate @Element1 in the scene. Style video should be following watercolor style of @Image1",
              "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/video_reference.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o3/pro/video-to-video/reference", {
        input: {
            prompt: "Integrate @Element1 in the scene. Style video should be following watercolor style of @Image1",
            video_url: "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/video_reference.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o3/pro/video-to-video/reference \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Integrate @Element1 in the scene. Style video should be following watercolor style of @Image1",
        "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/video_reference.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text prompt for video generation. Reference video as @Video1.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats, 3-10s duration, 720-2160px resolution, max 200MB.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="true">
      Whether to keep the original audio from the reference video. Default value: `true`
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ImageElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2.
    </ParamField>

    <ParamField body="shot_type" type="string" default="customize">
      The type of multi-shot video generation. Default value: `"customize"`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      Aspect ratio. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="duration" type="Enum">
      Video duration in seconds (3-15s for reference video).

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Integrate @Element1 in the scene. Style video should be following watercolor style of @Image1",
      "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/video_reference.mp4",
      "image_urls": [
        "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/image_url1.jpg",
        "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/image_url2.jpg"
      ],
      "keep_audio": false,
      "elements": [
        {
          "frontal_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/element1_front.png",
          "reference_image_urls": [
            "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/pro-v2v-reference/element1_reference1.png"
          ]
        }
      ],
      "shot_type": "customize",
      "aspect_ratio": "auto",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 15809901,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-o3/pro-v2v-reference/output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Reference to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation
* [Kling O3 Edit Video \[Standard\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-standard-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Standard Image To Video API

> API reference for Kling Video O3 Standard Image To Video. Generate a video by taking a start frame and an end frame, animating the transition between them while following text-driven style and scene g

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/standard/image-to-video`
**Endpoint ID:** `fal-ai/kling-video/o3/standard/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/standard/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o3/standard/image-to-video",
      arguments={
          "image_url": "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o3/standard/image-to-video", {
    input: {
        image_url: "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o3/standard/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png"
  }'
  ```
</CodeGroup>

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Reference to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation
* [Kling O3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Image input
* Duration control

## API Reference

### Input Schema

<ParamField body="prompt" type="string">
  Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
</ParamField>

<ParamField body="image_url" type="string" required>
  URL of the start frame image.
</ParamField>

<ParamField body="end_image_url" type="string">
  URL of the end frame image (optional).
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds (3-15s). Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="false">
  Whether to generate native audio for the video.
</ParamField>

<ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
  List of prompts for multi-shot video generation.
</ParamField>

<ParamField body="shot_type" type="string" default="customize">
  The type of multi-shot video generation. Default value: `"customize"`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "The character walks forward slowly, with the camera following from behind.",
  "image_url": "https://v3b.fal.media/files/b/0a8cfd5a/8ABMp4n9rh3kfD2Rq8fHd_start_frame.png",
  "end_image_url": "https://v3b.fal.media/files/b/0a8d0248/S415GcxackjjLKom6f3jq_VTImWrNO.png",
  "duration": "10",
  "generate_audio": false,
  "multi_prompt": null,
  "shot_type": "customize"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 12037975,
    "url": "https://v3b.fal.media/files/b/0a8d0278/pgIO9yOXTFCTetKBsqDwX_output.mp4"
  }
}
```


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-standard-reference-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Standard Reference To Video API

> API reference for Kling Video O3 Standard Reference To Video. Transform images, elements, and text into consistent, high-quality video scenes, ensuring stable character identity, object details, and e

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/standard/reference-to-video`
**Endpoint ID:** `fal-ai/kling-video/o3/standard/reference-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/standard/reference-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o3/standard/reference-to-video",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o3/standard/reference-to-video", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o3/standard/reference-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Reference to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation
* [Kling O3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string">
  Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
</ParamField>

<ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
  List of prompts for multi-shot video generation.
</ParamField>

<ParamField body="start_image_url" type="string">
  Image to use as the first frame of the video.
</ParamField>

<ParamField body="end_image_url" type="string">
  Image to use as the last frame of the video.
</ParamField>

<ParamField body="image_urls" type="list<string>">
  Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
</ParamField>

<ParamField body="elements" type="list<KlingV3ComboElementInput>">
  Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2.
</ParamField>

<ParamField body="generate_audio" type="boolean" default="false">
  Whether to generate native audio for the video.
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds (3-15s). Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="shot_type" type="string" default="customize">
  The type of multi-shot video generation. Default value: `"customize"`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  The aspect ratio of the generated video frame. Default value: `"16:9"`

  Possible values: `16:9`, `9:16`, `1:1`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "@Element1 and @Element2 is having dinner at this table on @Image1",
  "multi_prompt": null,
  "start_image_url": "https://v3b.fal.media/files/b/0a8d1b63/EcYdmuNB1LTFjtn3Ryjrf_6ROoQV4u.png",
  "image_urls": [
    "https://v3b.fal.media/files/b/0a8d1b63/EcYdmuNB1LTFjtn3Ryjrf_6ROoQV4u.png"
  ],
  "elements": [
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/0a8d1b64/-ddhNV-utVpHj_1uGfuY-_i6viYke3.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/0a8d1b5e/Gl1qUHJeTG63vAGtQmGM-_S3kPW32v.png"
      ]
    },
    {
      "frontal_image_url": "https://v3b.fal.media/files/b/0a8d1b66/cWe8LC84I_OF6ee9ZtnsO_nY9Hw5UB.png",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/0a8d1b60/Dt21s8LElZdSccIGDC7ec_Nuaraa9P.png"
      ]
    }
  ],
  "generate_audio": false,
  "duration": "8",
  "shot_type": "customize",
  "aspect_ratio": "16:9"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 3192162,
    "url": "https://v3b.fal.media/files/b/0a8d200d/ejCxI5DalzOPlP4yf6uP3_output.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-standard-text-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Standard Text To Video API

> API reference for Kling Video O3 Standard Text To Video. Generate realistic videos using Kling O3 from Kling Team!

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/standard/text-to-video`
**Endpoint ID:** `fal-ai/kling-video/o3/standard/text-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/standard/text-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/o3/standard/text-to-video",
      arguments={},
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/o3/standard/text-to-video", {
    input: {},
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/o3/standard/text-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{}'
  ```
</CodeGroup>

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Reference to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation
* [Kling O3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation

## Capabilities

* Text prompt input
* Duration control
* Aspect ratio control

## API Reference

### Input Schema

<ParamField body="prompt" type="string">
  Text prompt for video generation. Required unless multi\_prompt is provided.
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  Video duration in seconds (3-15s). Default value: `"5"`

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  Aspect ratio of the generated video. Default value: `"16:9"`

  Possible values: `16:9`, `9:16`, `1:1`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="false">
  Whether to generate native audio for the video.
</ParamField>

<ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
  List of prompts for multi-shot video generation.
</ParamField>

<ParamField body="shot_type" type="string" default="customize">
  The type of multi-shot video generation. Default value: `"customize"`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A mecha lands on the ground to save the city, and says \"I'm here\", in anime style",
  "duration": "5",
  "aspect_ratio": "16:9",
  "generate_audio": false,
  "multi_prompt": null,
  "shot_type": "customize"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 13096952,
    "url": "https://v3b.fal.media/files/b/0a8d04e2/idOb9V-Q9ujlggPSKqsfS_output.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-o3-standard-video-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video O3 Standard Video To Video API

> API reference for Kling Video O3 Standard Video To Video. Edit videos using Kling O3 from Kling Team!

<Tabs>
  <Tab title="Edit">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/standard/video-to-video/edit`
    **Endpoint ID:** `fal-ai/kling-video/o3/standard/video-to-video/edit`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/standard/video-to-video/edit/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o3/standard/video-to-video/edit",
          arguments={
              "prompt": "change the main character to be Popeye from @Element1, dark lighting and rain, 3d character. make him sad, with rain dropping on him, dark light on the character.",
              "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-edit/standard_video_reference.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o3/standard/video-to-video/edit", {
        input: {
            prompt: "change the main character to be Popeye from @Element1, dark lighting and rain, 3d character. make him sad, with rain dropping on him, dark light on the character.",
            video_url: "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-edit/standard_video_reference.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o3/standard/video-to-video/edit \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "change the main character to be Popeye from @Element1, dark lighting and rain, 3d character. make him sad, with rain dropping on him, dark light on the character.",
        "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-edit/standard_video_reference.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text prompt for video generation. Reference video as @Video1.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats, 3-10s duration, 720-2160px resolution, max 200MB.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="true">
      Whether to keep the original audio from the reference video. Default value: `true`
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ImageElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2.
    </ParamField>

    <ParamField body="shot_type" type="string" default="customize">
      The type of multi-shot video generation. Default value: `"customize"`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "change the main character to be Popeye from @Element1, dark lighting and rain, 3d character. make him sad, with rain dropping on him, dark light on the character.",
      "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-edit/standard_video_reference.mp4",
      "image_urls": null,
      "keep_audio": true,
      "elements": [
        {
          "frontal_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-edit/element1_front.jpg",
          "reference_image_urls": [
            "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-edit/standard_element1_reference1.jpg"
          ]
        }
      ],
      "shot_type": "customize"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 4322769,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-o3/standard-v2v-edit/output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Reference">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/o3/standard/video-to-video/reference`
    **Endpoint ID:** `fal-ai/kling-video/o3/standard/video-to-video/reference`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/o3/standard/video-to-video/reference/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/o3/standard/video-to-video/reference",
          arguments={
              "prompt": "Replace both character with @Element1 and @Element2",
              "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/video_reference.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/o3/standard/video-to-video/reference", {
        input: {
            prompt: "Replace both character with @Element1 and @Element2",
            video_url: "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/video_reference.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/o3/standard/video-to-video/reference \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Replace both character with @Element1 and @Element2",
        "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/video_reference.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text prompt for video generation. Reference video as @Video1.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. Only .mp4/.mov formats, 3-10s duration, 720-2160px resolution, max 200MB.
    </ParamField>

    <ParamField body="image_urls" type="list<string>">
      Reference images for style/appearance. Reference in prompt as @Image1, @Image2, etc. Maximum 4 total (elements + reference images) when using video.
    </ParamField>

    <ParamField body="keep_audio" type="boolean" default="true">
      Whether to keep the original audio from the reference video. Default value: `true`
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ImageElementInput>">
      Elements (characters/objects) to include. Reference in prompt as @Element1, @Element2.
    </ParamField>

    <ParamField body="shot_type" type="string" default="customize">
      The type of multi-shot video generation. Default value: `"customize"`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      Aspect ratio. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="duration" type="Enum">
      Video duration in seconds (3-15s for reference video).

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Replace both character with @Element1 and @Element2",
      "video_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/video_reference.mp4",
      "image_urls": null,
      "keep_audio": false,
      "elements": [
        {
          "frontal_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/element1_front.png",
          "reference_image_urls": [
            "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/element1_reference1.png"
          ]
        },
        {
          "frontal_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/element2_front.png",
          "reference_image_urls": [
            "https://storage.googleapis.com/falserverless/example_inputs/kling-o3/standard-v2v-reference/element2_reference1.png"
          ]
        }
      ],
      "shot_type": "customize",
      "aspect_ratio": "auto",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 7992288,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-o3/standard-v2v-reference/output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling O3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-image-to-video) — Video Generation
* [Kling O3 Reference to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-to-video) — Video Generation
* [Kling O3 Edit Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-edit-video) — Video Generation
* [Kling O3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-text-to-video) — Video Generation
* [Kling O3 Reference Video to Video \[Pro\]](/model-api-reference/video-generation-api/kling-o3-reference-video-to-video) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v1-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V1 Pro API

> API reference for Kling Video V1 Pro. Kling AI Avatar Pro: The premium endpoint for creating avatar videos with realistic humans, animals, cartoons, or stylized characters

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1/pro/ai-avatar`
**Endpoint ID:** `fal-ai/kling-video/v1/pro/ai-avatar`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1/pro/ai-avatar/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/v1/pro/ai-avatar",
      arguments={
          "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
          "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/v1/pro/ai-avatar", {
    input: {
        image_url: "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
        audio_url: "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/v1/pro/ai-avatar \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
    "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="image_url" type="string" required>
  The URL of the image to use as your avatar
</ParamField>

<ParamField body="audio_url" type="string" required>
  The URL of the audio file.
</ParamField>

<ParamField body="prompt" type="string" default=".">
  The prompt to use for the video generation. Default value: `"."`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video
</ParamField>

<ParamField body="duration" type="float" required>
  Duration of the output video in seconds.
</ParamField>

### Input Example

```json theme={null}
{
  "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
  "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3",
  "prompt": "."
}
```

### Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3.fal.media/files/penguin/ln3x7H1p1jL0Pwo7675NI_output.mp4"
  }
}
```

## Related

* [Kling AI Avatar v2 Pro](/model-api-reference/video-generation-api/kling-ai-avatar-v2-pro) — Video Generation
* [Kling AI Avatar v2 Standard](/model-api-reference/video-generation-api/kling-ai-avatar-v2-standard) — Video Generation
* [Kling AI Avatar](/model-api-reference/video-generation-api/kling-ai-avatar) — Video Generation
* [Kling TTS](/model-api-reference/audio-api/kling-tts) — Audio


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v1-standard.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V1 Standard API

> API reference for Kling Video V1 Standard. Generate video clips from your images using Kling 1.0

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1/standard/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1/standard/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1/standard/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1/standard/image-to-video",
          arguments={
              "prompt": "Snowflakes fall as a car moves forward along the road.",
              "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1/standard/image-to-video", {
        input: {
            prompt: "Snowflakes fall as a car moves forward along the road.",
            image_url: "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1/standard/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Snowflakes fall as a car moves forward along the road.",
        "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The prompt for the video
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of the image to be used for the video
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="tail_image_url" type="string">
      URL of the image to be used for the end of the video
    </ParamField>

    <ParamField body="static_mask_url" type="string">
      URL of the image for Static Brush Application Area (Mask image created by users using the motion brush)
    </ParamField>

    <ParamField body="dynamic_masks" type="list<DynamicMask>">
      List of dynamic masks
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Snowflakes fall as a car moves forward along the road.",
      "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg",
      "duration": "5",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5,
      "static_mask_url": "https://storage.googleapis.com/falserverless/kling/new_static_mask.png",
      "dynamic_masks": [
        {
          "mask_url": "https://storage.googleapis.com/falserverless/kling/new_dynamic_mask.png",
          "trajectories": [
            {
              "x": 279,
              "y": 219
            },
            {
              "x": 417,
              "y": 65
            }
          ]
        }
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/kling/kling_i2v_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1/standard/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1/standard/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1/standard/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1/standard/text-to-video",
          arguments={
              "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1/standard/text-to-video", {
        input: {
            prompt: "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1/standard/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="camera_control" type="Enum">
      Camera control parameters

      Possible values: `down_back`, `forward_up`, `right_turn_forward`, `left_turn_forward`
    </ParamField>

    <ParamField body="advanced_camera_control" type="CameraControl">
      Advanced Camera control parameters
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse.",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v2.fal.media/files/fb33a862b94d4d7195e610e4cbc5d392_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Ai Avatar">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1/standard/ai-avatar`
    **Endpoint ID:** `fal-ai/kling-video/v1/standard/ai-avatar`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1/standard/ai-avatar/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1/standard/ai-avatar",
          arguments={
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
              "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1/standard/ai-avatar", {
        input: {
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
            audio_url: "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1/standard/ai-avatar \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
        "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to use as your avatar
    </ParamField>

    <ParamField body="audio_url" type="string" required>
      The URL of the audio file.
    </ParamField>

    <ParamField body="prompt" type="string" default=".">
      The prompt to use for the video generation. Default value: `"."`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    <ParamField body="duration" type="float" required>
      Duration of the output video in seconds.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_ai_avatar_input.jpg",
      "audio_url": "https://v3.fal.media/files/rabbit/9_0ZG_geiWjZOmn9yscO6_output.mp3",
      "prompt": "."
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/penguin/ln3x7H1p1jL0Pwo7675NI_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Effects">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1/standard/effects`
    **Endpoint ID:** `fal-ai/kling-video/v1/standard/effects`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1/standard/effects/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1/standard/effects",
          arguments={
              "effect_scene": "hug"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1/standard/effects", {
        input: {
            effect_scene: "hug"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1/standard/effects \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "effect_scene": "hug"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="input_image_urls" type="list<string>">
      URL of images to be used for hug, kiss or heart\_gesture video.
    </ParamField>

    <ParamField body="effect_scene" type="EffectSceneEnum" required>
      The effect scene to use for the video generation

      Possible values: `hug`, `kiss`, `heart_gesture`, `squish`, `expansion`, `fuzzyfuzzy`, `bloombloom`, `dizzydizzy`, `jelly_press`, `jelly_slice`, `jelly_squish`, `jelly_jiggle`, `pixelpixel`, `yearbook`, `instant_film`, `anime_figure`, `rocketrocket`, `fly_fly`, `disappear`, `lightning_power`, `bullet_time`, `bullet_time_360`, `media_interview`, `day_to_night`, `let's_ride`, `jumpdrop`, `swish_swish`, `running_man`, `jazz_jazz`, `swing_swing`, `skateskate`, `building_sweater`, `pure_white_wings`, `black_wings`, `golden_wing`, `pink_pink_wings`, `rampage_ape`, `a_list_look`, `countdown_teleport`, `firework_2026`, `instant_christmas`, `birthday_star`, `firework`, `celebration`, `tiger_hug_pro`, `pet_lion_pro`, `guardian_spirit`, `squeeze_scream`, `inner_voice`, `memory_alive`, `guess_what`, `eagle_snatch`, `hug_from_past`, `instant_kid`, `dollar_rain`, `cry_cry`, `building_collapse`, `mushroom`, `jesus_hug`, `shark_alert`, `lie_flat`, `polar_bear_hug`, `brown_bear_hug`, `office_escape_plow`, `watermelon_bomb`, `boss_coming`, `wig_out`, `car_explosion`, `tiger_hug`, `siblings`, `construction_worker`, `snatched`, `felt_felt`, `plushcut`, `drunk_dance`, `drunk_dance_pet`, `daoma_dance`, `bouncy_dance`, `smooth_sailing_dance`, `new_year_greeting`, `lion_dance`, `prosperity`, `great_success`, `golden_horse_fortune`, `red_packet_box`, `lucky_horse_year`, `lucky_red_packet`, `lucky_money_come`, `lion_dance_pet`, `dumpling_making_pet`, `fish_making_pet`, `pet_red_packet`, `lantern_glow`, `expression_challenge`, `overdrive`, `heart_gesture_dance`, `poping`, `martial_arts`, `running`, `nezha`, `motorcycle_dance`, `subject_3_dance`, `ghost_step_dance`, `phantom_jewel`, `zoom_out`, `cheers_2026`, `kiss_pro`, `fight_pro`, `hug_pro`, `heart_gesture_pro`, `dollar_rain_pro`, `pet_bee_pro`, `santa_random_surprise`, `magic_match_tree`, `happy_birthday`, `thumbs_up_pro`, `surprise_bouquet`, `bouquet_drop`, `3d_cartoon_1_pro`, `glamour_photo_shoot`, `box_of_joy`, `first_toast_of_the_year`, `my_santa_pic`, `santa_gift`, `steampunk_christmas`, `snowglobe`, `christmas_photo_shoot`, `ornament_crash`, `santa_express`, `particle_santa_surround`, `coronation_of_frost`, `spark_in_the_snow`, `scarlet_and_snow`, `cozy_toon_wrap`, `bullet_time_lite`, `magic_cloak`, `balloon_parade`, `jumping_ginger_joy`, `c4d_cartoon_pro`, `venomous_spider`, `throne_of_king`, `luminous_elf`, `woodland_elf`, `japanese_anime_1`, `american_comics`, `snowboarding`, `witch_transform`, `vampire_transform`, `pumpkin_head_transform`, `demon_transform`, `mummy_transform`, `zombie_transform`, `cute_pumpkin_transform`, `cute_ghost_transform`, `knock_knock_halloween`, `halloween_escape`, `baseball`, `trampoline`, `trampoline_night`, `pucker_up`, `feed_mooncake`, `flyer`, `dishwasher`, `pet_chinese_opera`, `magic_fireball`, `gallery_ring`, `pet_moto_rider`, `muscle_pet`, `pet_delivery`, `mythic_style`, `steampunk`, `3d_cartoon_2`, `pet_chef`, `santa_gifts`, `santa_hug`, `girlfriend`, `boyfriend`, `heart_gesture_1`, `pet_wizard`, `smoke_smoke`, `gun_shot`, `double_gun`, `pet_warrior`, `long_hair`, `pet_dance`, `wool_curly`, `pet_bee`, `marry_me`, `piggy_morph`, `ski_ski`, `magic_broom`, `splashsplash`, `surfsurf`, `fairy_wing`, `angel_wing`, `dark_wing`, `emoji`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "input_image_urls": [
        "https://storage.googleapis.com/falserverless/juggernaut_examples/VHXMavzPyI27zi6JseyL4.png",
        "https://storage.googleapis.com/falserverless/juggernaut_examples/QEW5VrzccxGva7mPfEXjf.png"
      ],
      "effect_scene": "hug",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "url": "https://storage.googleapis.com/falserverless/kling/kling_ex.mp4.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling 1.0](/model-api-reference/video-generation-api/kling-1.0) — Video Generation
* [Kling AI Avatar v2 Pro](/model-api-reference/video-generation-api/kling-ai-avatar-v2-pro) — Video Generation
* [Kling AI Avatar v2 Standard](/model-api-reference/video-generation-api/kling-ai-avatar-v2-standard) — Video Generation
* [Kling TTS](/model-api-reference/audio-api/kling-tts) — Audio
* [Kling AI Avatar Pro](/model-api-reference/video-generation-api/kling-ai-avatar-pro) — Video Generation
* [Kling 1.6](/model-api-reference/video-generation-api/kling-1.6) — Video Generation
* [Kling 1.5](/model-api-reference/video-generation-api/kling-1.5) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`
* `camera_control` restricted to: `down_back`, `forward_up`, `right_turn_forward`, `left_turn_forward`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v1.5-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V1.5 Pro API

> API reference for Kling Video V1.5 Pro. Generate video clips from your images using Kling 1.5 (pro)

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.5/pro/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1.5/pro/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.5/pro/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.5/pro/image-to-video",
          arguments={
              "prompt": "Snowflakes fall as a car moves along the road.",
              "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.5/pro/image-to-video", {
        input: {
            prompt: "Snowflakes fall as a car moves along the road.",
            image_url: "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.5/pro/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Snowflakes fall as a car moves along the road.",
        "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="image_url" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="tail_image_url" type="string">
      URL of the image to be used for the end of the video
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="static_mask_url" type="string">
      URL of the image for Static Brush Application Area (Mask image created by users using the motion brush)
    </ParamField>

    <ParamField body="dynamic_masks" type="list<DynamicMask>">
      List of dynamic masks
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Snowflakes fall as a car moves along the road.",
      "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5,
      "static_mask_url": "https://storage.googleapis.com/falserverless/kling/new_static_mask.png",
      "dynamic_masks": [
        {
          "mask_url": "https://storage.googleapis.com/falserverless/kling/new_dynamic_mask.png",
          "trajectories": [
            {
              "x": 279,
              "y": 219
            },
            {
              "x": 417,
              "y": 65
            }
          ]
        }
      ]
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/kling/kling_i2v_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.5/pro/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1.5/pro/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.5/pro/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.5/pro/text-to-video",
          arguments={
              "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.5/pro/text-to-video", {
        input: {
            prompt: "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.5/pro/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse.",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v2.fal.media/files/fb33a862b94d4d7195e610e4cbc5d392_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Effects">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.5/pro/effects`
    **Endpoint ID:** `fal-ai/kling-video/v1.5/pro/effects`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.5/pro/effects/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.5/pro/effects",
          arguments={
              "effect_scene": "hug"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.5/pro/effects", {
        input: {
            effect_scene: "hug"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.5/pro/effects \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "effect_scene": "hug"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="input_image_urls" type="list<string>">
      URL of images to be used for hug, kiss or heart\_gesture video.
    </ParamField>

    <ParamField body="effect_scene" type="EffectSceneEnum" required>
      The effect scene to use for the video generation

      Possible values: `hug`, `kiss`, `heart_gesture`, `squish`, `expansion`, `fuzzyfuzzy`, `bloombloom`, `dizzydizzy`, `jelly_press`, `jelly_slice`, `jelly_squish`, `jelly_jiggle`, `pixelpixel`, `yearbook`, `instant_film`, `anime_figure`, `rocketrocket`, `fly_fly`, `disappear`, `lightning_power`, `bullet_time`, `bullet_time_360`, `media_interview`, `day_to_night`, `let's_ride`, `jumpdrop`, `swish_swish`, `running_man`, `jazz_jazz`, `swing_swing`, `skateskate`, `building_sweater`, `pure_white_wings`, `black_wings`, `golden_wing`, `pink_pink_wings`, `rampage_ape`, `a_list_look`, `countdown_teleport`, `firework_2026`, `instant_christmas`, `birthday_star`, `firework`, `celebration`, `tiger_hug_pro`, `pet_lion_pro`, `guardian_spirit`, `squeeze_scream`, `inner_voice`, `memory_alive`, `guess_what`, `eagle_snatch`, `hug_from_past`, `instant_kid`, `dollar_rain`, `cry_cry`, `building_collapse`, `mushroom`, `jesus_hug`, `shark_alert`, `lie_flat`, `polar_bear_hug`, `brown_bear_hug`, `office_escape_plow`, `watermelon_bomb`, `boss_coming`, `wig_out`, `car_explosion`, `tiger_hug`, `siblings`, `construction_worker`, `snatched`, `felt_felt`, `plushcut`, `drunk_dance`, `drunk_dance_pet`, `daoma_dance`, `bouncy_dance`, `smooth_sailing_dance`, `new_year_greeting`, `lion_dance`, `prosperity`, `great_success`, `golden_horse_fortune`, `red_packet_box`, `lucky_horse_year`, `lucky_red_packet`, `lucky_money_come`, `lion_dance_pet`, `dumpling_making_pet`, `fish_making_pet`, `pet_red_packet`, `lantern_glow`, `expression_challenge`, `overdrive`, `heart_gesture_dance`, `poping`, `martial_arts`, `running`, `nezha`, `motorcycle_dance`, `subject_3_dance`, `ghost_step_dance`, `phantom_jewel`, `zoom_out`, `cheers_2026`, `kiss_pro`, `fight_pro`, `hug_pro`, `heart_gesture_pro`, `dollar_rain_pro`, `pet_bee_pro`, `santa_random_surprise`, `magic_match_tree`, `happy_birthday`, `thumbs_up_pro`, `surprise_bouquet`, `bouquet_drop`, `3d_cartoon_1_pro`, `glamour_photo_shoot`, `box_of_joy`, `first_toast_of_the_year`, `my_santa_pic`, `santa_gift`, `steampunk_christmas`, `snowglobe`, `christmas_photo_shoot`, `ornament_crash`, `santa_express`, `particle_santa_surround`, `coronation_of_frost`, `spark_in_the_snow`, `scarlet_and_snow`, `cozy_toon_wrap`, `bullet_time_lite`, `magic_cloak`, `balloon_parade`, `jumping_ginger_joy`, `c4d_cartoon_pro`, `venomous_spider`, `throne_of_king`, `luminous_elf`, `woodland_elf`, `japanese_anime_1`, `american_comics`, `snowboarding`, `witch_transform`, `vampire_transform`, `pumpkin_head_transform`, `demon_transform`, `mummy_transform`, `zombie_transform`, `cute_pumpkin_transform`, `cute_ghost_transform`, `knock_knock_halloween`, `halloween_escape`, `baseball`, `trampoline`, `trampoline_night`, `pucker_up`, `feed_mooncake`, `flyer`, `dishwasher`, `pet_chinese_opera`, `magic_fireball`, `gallery_ring`, `pet_moto_rider`, `muscle_pet`, `pet_delivery`, `mythic_style`, `steampunk`, `3d_cartoon_2`, `pet_chef`, `santa_gifts`, `santa_hug`, `girlfriend`, `boyfriend`, `heart_gesture_1`, `pet_wizard`, `smoke_smoke`, `gun_shot`, `double_gun`, `pet_warrior`, `long_hair`, `pet_dance`, `wool_curly`, `pet_bee`, `marry_me`, `piggy_morph`, `ski_ski`, `magic_broom`, `splashsplash`, `surfsurf`, `fairy_wing`, `angel_wing`, `dark_wing`, `emoji`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "input_image_urls": [
        "https://storage.googleapis.com/falserverless/juggernaut_examples/VHXMavzPyI27zi6JseyL4.png",
        "https://storage.googleapis.com/falserverless/juggernaut_examples/QEW5VrzccxGva7mPfEXjf.png"
      ],
      "effect_scene": "hug",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "url": "https://storage.googleapis.com/falserverless/kling/kling_ex.mp4.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling 1.5](/model-api-reference/video-generation-api/kling-1.5) — Video Generation
* [Kling 1.6](/model-api-reference/video-generation-api/kling-1.6) — Video Generation
* [Kling 1.0](/model-api-reference/video-generation-api/kling-1.0) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`
* `cfg_scale` range: 0 to 1


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v1.6-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V1.6 Pro API

> API reference for Kling Video V1.6 Pro. Generate video clips from your images using Kling 1.6 (pro)

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/pro/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/pro/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/pro/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/pro/image-to-video",
          arguments={
              "prompt": "Snowflakes fall as a car moves along the road.",
              "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/pro/image-to-video", {
        input: {
            prompt: "Snowflakes fall as a car moves along the road.",
            image_url: "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/pro/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Snowflakes fall as a car moves along the road.",
        "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="image_url" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="tail_image_url" type="string">
      URL of the image to be used for the end of the video
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Snowflakes fall as a car moves along the road.",
      "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/kling/kling_i2v_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/pro/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/pro/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/pro/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/pro/text-to-video",
          arguments={
              "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/pro/text-to-video", {
        input: {
            prompt: "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/pro/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse.",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v2.fal.media/files/fb33a862b94d4d7195e610e4cbc5d392_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Elements">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/pro/elements`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/pro/elements`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/pro/elements/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/pro/elements",
          arguments={
              "prompt": "A cute girl and a baby cow sleeping together on a bed",
              "input_image_urls": [
                  "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
                  "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/pro/elements", {
        input: {
            prompt: "A cute girl and a baby cow sleeping together on a bed",
            input_image_urls: [
              "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
              "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/pro/elements \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A cute girl and a baby cow sleeping together on a bed",
        "input_image_urls": [
          "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
          "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="input_image_urls" type="list<string>" required>
      List of image URLs to use for video generation. Supports up to 4 images.
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A cute girl and a baby cow sleeping together on a bed",
      "input_image_urls": [
        "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
        "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
      ],
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 3910577,
        "url": "https://v3.fal.media/files/penguin/twy6u1yv09NvqsX0mMFM2_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Effects">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/pro/effects`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/pro/effects`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/pro/effects/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/pro/effects",
          arguments={
              "effect_scene": "hug"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/pro/effects", {
        input: {
            effect_scene: "hug"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/pro/effects \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "effect_scene": "hug"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="input_image_urls" type="list<string>">
      URL of images to be used for hug, kiss or heart\_gesture video.
    </ParamField>

    <ParamField body="effect_scene" type="EffectSceneEnum" required>
      The effect scene to use for the video generation

      Possible values: `hug`, `kiss`, `heart_gesture`, `squish`, `expansion`, `fuzzyfuzzy`, `bloombloom`, `dizzydizzy`, `jelly_press`, `jelly_slice`, `jelly_squish`, `jelly_jiggle`, `pixelpixel`, `yearbook`, `instant_film`, `anime_figure`, `rocketrocket`, `fly_fly`, `disappear`, `lightning_power`, `bullet_time`, `bullet_time_360`, `media_interview`, `day_to_night`, `let's_ride`, `jumpdrop`, `swish_swish`, `running_man`, `jazz_jazz`, `swing_swing`, `skateskate`, `building_sweater`, `pure_white_wings`, `black_wings`, `golden_wing`, `pink_pink_wings`, `rampage_ape`, `a_list_look`, `countdown_teleport`, `firework_2026`, `instant_christmas`, `birthday_star`, `firework`, `celebration`, `tiger_hug_pro`, `pet_lion_pro`, `guardian_spirit`, `squeeze_scream`, `inner_voice`, `memory_alive`, `guess_what`, `eagle_snatch`, `hug_from_past`, `instant_kid`, `dollar_rain`, `cry_cry`, `building_collapse`, `mushroom`, `jesus_hug`, `shark_alert`, `lie_flat`, `polar_bear_hug`, `brown_bear_hug`, `office_escape_plow`, `watermelon_bomb`, `boss_coming`, `wig_out`, `car_explosion`, `tiger_hug`, `siblings`, `construction_worker`, `snatched`, `felt_felt`, `plushcut`, `drunk_dance`, `drunk_dance_pet`, `daoma_dance`, `bouncy_dance`, `smooth_sailing_dance`, `new_year_greeting`, `lion_dance`, `prosperity`, `great_success`, `golden_horse_fortune`, `red_packet_box`, `lucky_horse_year`, `lucky_red_packet`, `lucky_money_come`, `lion_dance_pet`, `dumpling_making_pet`, `fish_making_pet`, `pet_red_packet`, `lantern_glow`, `expression_challenge`, `overdrive`, `heart_gesture_dance`, `poping`, `martial_arts`, `running`, `nezha`, `motorcycle_dance`, `subject_3_dance`, `ghost_step_dance`, `phantom_jewel`, `zoom_out`, `cheers_2026`, `kiss_pro`, `fight_pro`, `hug_pro`, `heart_gesture_pro`, `dollar_rain_pro`, `pet_bee_pro`, `santa_random_surprise`, `magic_match_tree`, `happy_birthday`, `thumbs_up_pro`, `surprise_bouquet`, `bouquet_drop`, `3d_cartoon_1_pro`, `glamour_photo_shoot`, `box_of_joy`, `first_toast_of_the_year`, `my_santa_pic`, `santa_gift`, `steampunk_christmas`, `snowglobe`, `christmas_photo_shoot`, `ornament_crash`, `santa_express`, `particle_santa_surround`, `coronation_of_frost`, `spark_in_the_snow`, `scarlet_and_snow`, `cozy_toon_wrap`, `bullet_time_lite`, `magic_cloak`, `balloon_parade`, `jumping_ginger_joy`, `c4d_cartoon_pro`, `venomous_spider`, `throne_of_king`, `luminous_elf`, `woodland_elf`, `japanese_anime_1`, `american_comics`, `snowboarding`, `witch_transform`, `vampire_transform`, `pumpkin_head_transform`, `demon_transform`, `mummy_transform`, `zombie_transform`, `cute_pumpkin_transform`, `cute_ghost_transform`, `knock_knock_halloween`, `halloween_escape`, `baseball`, `trampoline`, `trampoline_night`, `pucker_up`, `feed_mooncake`, `flyer`, `dishwasher`, `pet_chinese_opera`, `magic_fireball`, `gallery_ring`, `pet_moto_rider`, `muscle_pet`, `pet_delivery`, `mythic_style`, `steampunk`, `3d_cartoon_2`, `pet_chef`, `santa_gifts`, `santa_hug`, `girlfriend`, `boyfriend`, `heart_gesture_1`, `pet_wizard`, `smoke_smoke`, `gun_shot`, `double_gun`, `pet_warrior`, `long_hair`, `pet_dance`, `wool_curly`, `pet_bee`, `marry_me`, `piggy_morph`, `ski_ski`, `magic_broom`, `splashsplash`, `surfsurf`, `fairy_wing`, `angel_wing`, `dark_wing`, `emoji`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "input_image_urls": [
        "https://storage.googleapis.com/falserverless/juggernaut_examples/VHXMavzPyI27zi6JseyL4.png",
        "https://storage.googleapis.com/falserverless/juggernaut_examples/QEW5VrzccxGva7mPfEXjf.png"
      ],
      "effect_scene": "hug",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "url": "https://storage.googleapis.com/falserverless/kling/kling_ex.mp4.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Kling AI v1.6 Pro - Professional Image-to-Video Generation

Transform static images into dynamic, fluid video content with Kling AI v1.6 Pro. This advanced image-to-video model by Kuaishou delivers professional-grade motion synthesis ideal for content creators, marketers, and developers.

### Overview

Kling AI v1.6 Pro excels at generating natural, smooth video animations from single images. The model specializes in realistic motion patterns while preserving the original image's quality and artistic intent.

Key Capabilities:

* Natural motion synthesis with fluid transitions
* High-fidelity output maintaining source image details
* Flexible video duration (5 or 10 seconds) and aspect ratio options
* Production-ready API with robust error handling
* Support for advanced features like motion brushes and special effects

### Getting Started

Setting up Kling AI is straightforward. First, install your preferred SDK:

For JavaScript/TypeScript:

```bash theme={null}
npm install --save @fal-ai/client
```

For Python:

```bash theme={null}
pip install fal-client
```

Configure your authentication:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_API_KEY"
});
```

### Implementation Guide

Here's a basic example of generating a video from an image:

```typescript theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/kling-video/v1.6/pro/image-to-video", {
  input: {
    prompt: "Snowflakes fall as a car moves along the road.",
    image_url: "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg",
    duration: "5",
    aspect_ratio: "16:9",
    negative_prompt: "blur, distort, and low quality",
    cfg_scale: 0.5
  }
});

console.log(result.video.url);
```

### API Parameters

* `prompt` (required): Text description of the desired motion and scene
* `image_url` (required): URL of the input image
* `duration`: Video duration - "5" or "10" seconds
* `aspect_ratio`: Output aspect ratio (e.g., "16:9", "9:16", "1:1")
* `negative_prompt`: Elements to avoid in the generation
* `cfg_scale`: Classifier Free Guidance scale (default: 0.5)
* `static_mask_url`: URL for static motion brush mask
* `dynamic_mask_url`: URL for dynamic motion brush mask
* `special_fx`: Special effects like "hug", "kiss", "heart\_gesture", "squish", "expansion"

### Advanced Features

#### Motion Brush Control

```typescript theme={null}
const result = await fal.subscribe("fal-ai/kling-video/v1.6/pro/image-to-video", {
  input: {
    prompt: "Dynamic scene with controlled motion",
    image_url: "your-image-url",
    static_mask_url: "static-mask-url",
    dynamic_masks: [{
      mask_url: "dynamic-mask-url",
      trajectories: [
        { x: 279, y: 219 },
        { x: 417, y: 65 }
      ]
    }]
  }
});
```

#### Multi-Image Generation

For creating videos from multiple reference images (up to 4):

```typescript theme={null}
const result = await fal.subscribe("fal-ai/kling-video/v1.6/standard/elements", {
  input: {
    prompt: "A cute girl and a baby cow sleeping together",
    input_image_urls: [
      "first-image-url",
      "second-image-url"
    ]
  }
});
```

### Technical Specifications

Processing Capabilities:

* Input formats: JPG, JPEG, PNG, WebP, GIF, AVIF
* Output format: MP4
* Resolution: 1080p
* Duration options: 5 or 10 seconds
* Processing time: Approximately 6 minutes

### Best Practices

For optimal results:

Start with high-quality source images. The model performs best with clear, well-lit images that have distinct subjects and depth.

Consider your motion requirements. The cfg\_scale parameter controls prompt adherence - lower values (0.3-0.5) for more creative freedom, higher values for stricter prompt following.

Test different duration settings. 5-second clips often produce more focused results, while 10-second videos allow for more complex motion development.

### Model Variants

Kling offers two quality tiers:

* **Pro Mode**: Higher quality, longer processing time
* **Standard Mode**: Faster processing, good for quick iterations

Access standard mode at: `fal-ai/kling-video/v1.6/standard/image-to-video`

### Queue Management

For asynchronous processing:

```typescript theme={null}
// Submit request
const { request_id } = await fal.queue.submit("fal-ai/kling-video/v1.6/pro/image-to-video", {
  input: {
    prompt: "Your video description",
    image_url: "your-image-url"
  }
});

// Check status
const status = await fal.queue.status("fal-ai/kling-video/v1.6/pro/image-to-video", {
  requestId: request_id,
  logs: true
});

// Get result
const result = await fal.queue.result("fal-ai/kling-video/v1.6/pro/image-to-video", {
  requestId: request_id
});
```

### Pricing and Usage

* **Cost**: \$0.095 per video second
* 5-second video: \$0.475
* 10-second video: \$0.95
* Processing time: Approximately 6 minutes

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Support and Resources

For technical support or to discuss specific use cases, connect with our developer community. We maintain comprehensive documentation and example repositories to help you implement Kling AI effectively in your projects.

* API Documentation: [fal.ai/models/fal-ai/kling-video/v1.6/pro/image-to-video/api](https://fal.ai/models/fal-ai/kling-video/v1.6/pro/image-to-video/api)
* Discord Community: [discord.com/invite/fal-ai](https://discord.com/invite/fal-ai)
* Support: [support@fal.ai](mailto:support@fal.ai)

### Ready to Transform Your Images?

Get started today by creating your API key at [fal.ai](https://fal.ai) and experience professional-grade video generation capabilities with Kling AI v1.6 Pro.

## Related

* [Kling 1.6](/model-api-reference/video-generation-api/kling-1.6) — Video Generation
* [Kling 1.6 Elements](/model-api-reference/video-generation-api/kling-1.6-elements) — Video Generation
* [Kling 1.0](/model-api-reference/video-generation-api/kling-1.0) — Video Generation
* [Kling 1.5](/model-api-reference/video-generation-api/kling-1.5) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`
* `cfg_scale` range: 0 to 1


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v1.6-standard.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V1.6 Standard API

> API reference for Kling Video V1.6 Standard. Generate video clips from your images using Kling 1.6 (std)

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/standard/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/standard/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/standard/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/standard/image-to-video",
          arguments={
              "prompt": "Snowflakes fall as a car moves forward along the road.",
              "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/standard/image-to-video", {
        input: {
            prompt: "Snowflakes fall as a car moves forward along the road.",
            image_url: "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/standard/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Snowflakes fall as a car moves forward along the road.",
        "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="image_url" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Snowflakes fall as a car moves forward along the road.",
      "image_url": "https://storage.googleapis.com/falserverless/kling/kling_input.jpeg",
      "duration": "5",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/kling/kling_i2v_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/standard/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/standard/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/standard/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/standard/text-to-video",
          arguments={
              "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/standard/text-to-video", {
        input: {
            prompt: "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/standard/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A stylish woman walks down a Tokyo street filled with warm glowing neon and animated city signage. She wears a black leather jacket, a long red dress, and black boots, and carries a black purse.",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v2.fal.media/files/fb33a862b94d4d7195e610e4cbc5d392_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Elements">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/standard/elements`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/standard/elements`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/standard/elements/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/standard/elements",
          arguments={
              "prompt": "A cute girl and a baby cow sleeping together on a bed",
              "input_image_urls": [
                  "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
                  "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/standard/elements", {
        input: {
            prompt: "A cute girl and a baby cow sleeping together on a bed",
            input_image_urls: [
              "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
              "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/standard/elements \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A cute girl and a baby cow sleeping together on a bed",
        "input_image_urls": [
          "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
          "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
        ]
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="input_image_urls" type="list<string>" required>
      List of image URLs to use for video generation. Supports up to 4 images.
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A cute girl and a baby cow sleeping together on a bed",
      "input_image_urls": [
        "https://storage.googleapis.com/falserverless/web-examples/kling-elements/first_image.jpeg",
        "https://storage.googleapis.com/falserverless/web-examples/kling-elements/second_image.png"
      ],
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 3910577,
        "url": "https://v3.fal.media/files/penguin/twy6u1yv09NvqsX0mMFM2_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Effects">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v1.6/standard/effects`
    **Endpoint ID:** `fal-ai/kling-video/v1.6/standard/effects`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v1.6/standard/effects/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v1.6/standard/effects",
          arguments={
              "effect_scene": "hug"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v1.6/standard/effects", {
        input: {
            effect_scene: "hug"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v1.6/standard/effects \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "effect_scene": "hug"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="input_image_urls" type="list<string>">
      URL of images to be used for hug, kiss or heart\_gesture video.
    </ParamField>

    <ParamField body="effect_scene" type="EffectSceneEnum" required>
      The effect scene to use for the video generation

      Possible values: `hug`, `kiss`, `heart_gesture`, `squish`, `expansion`, `fuzzyfuzzy`, `bloombloom`, `dizzydizzy`, `jelly_press`, `jelly_slice`, `jelly_squish`, `jelly_jiggle`, `pixelpixel`, `yearbook`, `instant_film`, `anime_figure`, `rocketrocket`, `fly_fly`, `disappear`, `lightning_power`, `bullet_time`, `bullet_time_360`, `media_interview`, `day_to_night`, `let's_ride`, `jumpdrop`, `swish_swish`, `running_man`, `jazz_jazz`, `swing_swing`, `skateskate`, `building_sweater`, `pure_white_wings`, `black_wings`, `golden_wing`, `pink_pink_wings`, `rampage_ape`, `a_list_look`, `countdown_teleport`, `firework_2026`, `instant_christmas`, `birthday_star`, `firework`, `celebration`, `tiger_hug_pro`, `pet_lion_pro`, `guardian_spirit`, `squeeze_scream`, `inner_voice`, `memory_alive`, `guess_what`, `eagle_snatch`, `hug_from_past`, `instant_kid`, `dollar_rain`, `cry_cry`, `building_collapse`, `mushroom`, `jesus_hug`, `shark_alert`, `lie_flat`, `polar_bear_hug`, `brown_bear_hug`, `office_escape_plow`, `watermelon_bomb`, `boss_coming`, `wig_out`, `car_explosion`, `tiger_hug`, `siblings`, `construction_worker`, `snatched`, `felt_felt`, `plushcut`, `drunk_dance`, `drunk_dance_pet`, `daoma_dance`, `bouncy_dance`, `smooth_sailing_dance`, `new_year_greeting`, `lion_dance`, `prosperity`, `great_success`, `golden_horse_fortune`, `red_packet_box`, `lucky_horse_year`, `lucky_red_packet`, `lucky_money_come`, `lion_dance_pet`, `dumpling_making_pet`, `fish_making_pet`, `pet_red_packet`, `lantern_glow`, `expression_challenge`, `overdrive`, `heart_gesture_dance`, `poping`, `martial_arts`, `running`, `nezha`, `motorcycle_dance`, `subject_3_dance`, `ghost_step_dance`, `phantom_jewel`, `zoom_out`, `cheers_2026`, `kiss_pro`, `fight_pro`, `hug_pro`, `heart_gesture_pro`, `dollar_rain_pro`, `pet_bee_pro`, `santa_random_surprise`, `magic_match_tree`, `happy_birthday`, `thumbs_up_pro`, `surprise_bouquet`, `bouquet_drop`, `3d_cartoon_1_pro`, `glamour_photo_shoot`, `box_of_joy`, `first_toast_of_the_year`, `my_santa_pic`, `santa_gift`, `steampunk_christmas`, `snowglobe`, `christmas_photo_shoot`, `ornament_crash`, `santa_express`, `particle_santa_surround`, `coronation_of_frost`, `spark_in_the_snow`, `scarlet_and_snow`, `cozy_toon_wrap`, `bullet_time_lite`, `magic_cloak`, `balloon_parade`, `jumping_ginger_joy`, `c4d_cartoon_pro`, `venomous_spider`, `throne_of_king`, `luminous_elf`, `woodland_elf`, `japanese_anime_1`, `american_comics`, `snowboarding`, `witch_transform`, `vampire_transform`, `pumpkin_head_transform`, `demon_transform`, `mummy_transform`, `zombie_transform`, `cute_pumpkin_transform`, `cute_ghost_transform`, `knock_knock_halloween`, `halloween_escape`, `baseball`, `trampoline`, `trampoline_night`, `pucker_up`, `feed_mooncake`, `flyer`, `dishwasher`, `pet_chinese_opera`, `magic_fireball`, `gallery_ring`, `pet_moto_rider`, `muscle_pet`, `pet_delivery`, `mythic_style`, `steampunk`, `3d_cartoon_2`, `pet_chef`, `santa_gifts`, `santa_hug`, `girlfriend`, `boyfriend`, `heart_gesture_1`, `pet_wizard`, `smoke_smoke`, `gun_shot`, `double_gun`, `pet_warrior`, `long_hair`, `pet_dance`, `wool_curly`, `pet_bee`, `marry_me`, `piggy_morph`, `ski_ski`, `magic_broom`, `splashsplash`, `surfsurf`, `fairy_wing`, `angel_wing`, `dark_wing`, `emoji`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "input_image_urls": [
        "https://storage.googleapis.com/falserverless/juggernaut_examples/VHXMavzPyI27zi6JseyL4.png",
        "https://storage.googleapis.com/falserverless/juggernaut_examples/QEW5VrzccxGva7mPfEXjf.png"
      ],
      "effect_scene": "hug",
      "duration": "5"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "url": "https://storage.googleapis.com/falserverless/kling/kling_ex.mp4.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling 1.6](/model-api-reference/video-generation-api/kling-1.6) — Video Generation
* [Kling 1.6 Elements](/model-api-reference/video-generation-api/kling-1.6-elements) — Video Generation
* [Kling 1.0](/model-api-reference/video-generation-api/kling-1.0) — Video Generation
* [Kling 1.5](/model-api-reference/video-generation-api/kling-1.5) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2-master.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2 Master API

> API reference for Kling Video V2 Master. Generate video clips from your images using Kling 2.0 Master

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2/master/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2/master/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2/master/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2/master/image-to-video",
          arguments={
              "prompt": "slow-motion sequence captures the catastrophic implosion of a skyscraper, dust and debris billowing outwards in a chaotic ballet of destruction, while a haunting, orchestral score underscores the sheer power and finality of the event.",
              "image_url": "https://v3.fal.media/files/elephant/rkH-9qoXtXu3rAYTsx9V5_image.webp"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2/master/image-to-video", {
        input: {
            prompt: "slow-motion sequence captures the catastrophic implosion of a skyscraper, dust and debris billowing outwards in a chaotic ballet of destruction, while a haunting, orchestral score underscores the sheer power and finality of the event.",
            image_url: "https://v3.fal.media/files/elephant/rkH-9qoXtXu3rAYTsx9V5_image.webp"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2/master/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "slow-motion sequence captures the catastrophic implosion of a skyscraper, dust and debris billowing outwards in a chaotic ballet of destruction, while a haunting, orchestral score underscores the sheer power and finality of the event.",
        "image_url": "https://v3.fal.media/files/elephant/rkH-9qoXtXu3rAYTsx9V5_image.webp"
      }'
      ```
    </CodeGroup>

    ## Examples

    > A close-up reveals a woman's delicate fingers gracefully holding a perfume bottle, its crystal facets catching the light, a slow, deliberate movement emphasizing the product's luxurious quality;  the scene is bathed in soft, warm lighting, creating an intimate and sensual atmosphere. Camera zoom out...

    <video src="https://v3.fal.media/files/zebra/vvzj5u7wv9wk06GA4zTJX_output.mp4" controls width="100%" />

    > Under a vast, clear sky, a Shub-Niggurath shepherd in futuristic soldier gear and a shaved-sides haircut smiles and laughs faintly while casually posing near a cybernetics clinic set against a sandy, rocky landscape, a relaxed picnic spread laid out nearby.

    <video src="https://v3.fal.media/files/kangaroo/IkMxgPpvf3jZ5UKfrlnEY_output.mp4" controls width="100%" />

    > A warm, golden light bathes a cozy bedroom where a fluffy Persian cat and a scruffy terrier sleep curled together on a plush bed, their gentle breaths creating a peaceful atmosphere; the scene unfolds in a slow, deliberate pace with the camera maintaining a steady position, focusing on the subtle mo...

    <video src="https://v3.fal.media/files/lion/DDHlO3zS6d9QvQTZqC6L0_output.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="image_url" type="string" required>
      URL of the image to be used for the video
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "slow-motion sequence captures the catastrophic implosion of a skyscraper, dust and debris billowing outwards in a chaotic ballet of destruction, while a haunting, orchestral score underscores the sheer power and finality of the event.",
      "image_url": "https://v3.fal.media/files/elephant/rkH-9qoXtXu3rAYTsx9V5_image.webp",
      "duration": "5",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/koala/VvGXP5xEhTR9ovGjpulJ7_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2/master/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2/master/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2/master/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2/master/text-to-video",
          arguments={
              "prompt": "A slow-motion drone shot descending from above a maze of neon-lit Tokyo alleyways at night during heavy rainfall. The camera gradually focuses on a lone figure in a luminescent white raincoat standing perfectly still amid the bustling crowd, all carrying black umbrellas. As the camera continues its downward journey, we see the raindrops creating rippling patterns on puddles that reflect the kaleidoscope of colors from the surrounding signs, creating a mirror world beneath the city."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2/master/text-to-video", {
        input: {
            prompt: "A slow-motion drone shot descending from above a maze of neon-lit Tokyo alleyways at night during heavy rainfall. The camera gradually focuses on a lone figure in a luminescent white raincoat standing perfectly still amid the bustling crowd, all carrying black umbrellas. As the camera continues its downward journey, we see the raindrops creating rippling patterns on puddles that reflect the kaleidoscope of colors from the surrounding signs, creating a mirror world beneath the city."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2/master/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A slow-motion drone shot descending from above a maze of neon-lit Tokyo alleyways at night during heavy rainfall. The camera gradually focuses on a lone figure in a luminescent white raincoat standing perfectly still amid the bustling crowd, all carrying black umbrellas. As the camera continues its downward journey, we see the raindrops creating rippling patterns on puddles that reflect the kaleidoscope of colors from the surrounding signs, creating a mirror world beneath the city."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A slow-motion drone shot descending from above a maze of neon-lit Tokyo alleyways at night during heavy rainfall. The camera gradually focuses on a lone figure in a luminescent white raincoat standing perfectly still amid the bustling crowd, all carrying black umbrellas. As the camera continues its downward journey, we see the raindrops creating rippling patterns on puddles that reflect the kaleidoscope of colors from the surrounding signs, creating a mirror world beneath the city.",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/rabbit/5fu6OSZdvV825r2s_c0S8_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Kling AI v2 Master - Professional Image-to-Video Generation

Transform static images into dynamic, fluid video content with Kling AI v2 Master. Built by Kuaishou and optimized for professional creative workflows, this advanced AI model generates high-quality video animations from single images with unprecedented control and natural motion.

### Overview

Kling AI v2 Master excels at creating smooth, realistic video animations from still images. Whether you're a content creator, marketing professional, or developer building video applications, this model delivers production-ready results through an intuitive API. As the premium tier offering, it provides superior motion fluidity and cinematic quality for professional-grade video creation.

#### Key Capabilities

Transform any still image into fluid video content with:

* Natural motion patterns that respect physics and object relationships
* Precise control over animation duration (5 or 10 seconds)
* Consistent quality across diverse image types
* Professional-grade cinematic output
* Enhanced visual aesthetics and motion dynamics

### Getting Started

Getting up and running with Kling AI is straightforward. First, install your preferred SDK:

JavaScript/TypeScript:

```bash theme={null}
npm install --save @fal-ai/client
```

Python:

```bash theme={null}
pip install fal-client
```

#### Authentication

Configure your API credentials:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY_HERE"
});
```

#### Basic Usage

Here's a simple example of generating a video from an image:

```typescript theme={null}
const result = await fal.subscribe("fal-ai/kling-video/v2/master/image-to-video", {
  input: {
    prompt: "slow-motion sequence captures the catastrophic implosion of a skyscraper",
    image_url: "https://example.com/source-image.jpg",
    duration: "5",
    aspect_ratio: "16:9",
    negative_prompt: "blur, distort, and low quality",
    cfg_scale: 0.5
  }
});

console.log(result.video.url);
```

### API Parameters

* `prompt` (required): Text description of the desired motion and scene
* `image_url` (required): URL of the input image
* `duration`: Video duration - "5" or "10" seconds
* `aspect_ratio`: Output aspect ratio (e.g., "16:9", "9:16", "1:1")
* `negative_prompt`: Elements to avoid in the generation
* `cfg_scale`: Classifier Free Guidance scale (default: 0.5)
* `static_mask_url`: URL for static motion brush mask
* `dynamic_mask_url`: URL for dynamic motion brush mask
* `special_fx`: Special effects options
* `input_image_urls`: Array of up to 4 images for multi-image generation

### Advanced Features

The v2 Master model provides sophisticated controls for professional applications:

#### Motion Control

Adjust motion intensity and patterns through intuitive parameters. Fine-tune the balance between dramatic movement and natural flow to match your creative vision using cfg\_scale and motion masks.

#### Quality Settings

Master tier delivers the highest quality output with enhanced detail and smoother motion, ideal for professional productions and cinematic content.

#### Format Options

Export to multiple video formats with control over resolution and aspect ratio to optimize for different distribution channels.

### Queue Management

For asynchronous processing:

```typescript theme={null}
// Submit request
const { request_id } = await fal.queue.submit("fal-ai/kling-video/v2/master/image-to-video", {
  input: {
    prompt: "Your cinematic description",
    image_url: "your-image-url",
    duration: "10"
  }
});

// Check status
const status = await fal.queue.status("fal-ai/kling-video/v2/master/image-to-video", {
  requestId: request_id,
  logs: true
});

// Get result
const result = await fal.queue.result("fal-ai/kling-video/v2/master/image-to-video", {
  requestId: request_id
});
```

### Best Practices

For optimal results:

Start with high-quality source images. The model performs best with clear, well-lit images at high resolution.

Test different cfg\_scale values. Begin with moderate settings (0.5) and adjust based on your content needs.

Consider your target platform. Adjust aspect ratio and duration settings to match your distribution requirements while maintaining quality.

### Technical Support

Our comprehensive documentation covers advanced usage scenarios, parameter tuning, and troubleshooting. For additional support:

* Visit our documentation portal for detailed guides
* Join our developer community for peer support
* Contact our technical team for enterprise assistance

### Pricing and Usage

Premium pricing for professional quality:

* **5-second video**: \$1.40
* **Additional seconds**: \$0.28 per second
* 10-second video: \$2.80

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Model Variants

Kling offers multiple quality tiers:

* **Master**: This model - Premium quality for professional use
* **Standard**: `fal-ai/kling-video/v2/standard/image-to-video` - Cost-efficient option
* **v2.1 Versions**: Latest iteration with additional improvements

### Support and Resources

* API Documentation: [fal.ai/models/fal-ai/kling-video/v2/master/image-to-video/api](https://fal.ai/models/fal-ai/kling-video/v2/master/image-to-video/api)
* Discord Community: [discord.com/invite/fal-ai](https://discord.com/invite/fal-ai)
* Support: [support@fal.ai](mailto:support@fal.ai)

### Ready to Create Cinematic Videos?

Get started with Kling AI v2 Master today and experience professional-grade video generation capabilities. Create your API key at [fal.ai](https://fal.ai) and transform your images into stunning, cinematic videos.

## Related

* [Kling 2.0 Master](/model-api-reference/video-generation-api/kling-2.0-master) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2.1-master.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2.1 Master API

> API reference for Kling Video V2.1 Master. Kling 2.1 Master: The premium endpoint for Kling 2.1, designed for top-tier image-to-video generation with unparalleled motion fluidity, cinematic visuals, a

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.1/master/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2.1/master/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.1/master/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2.1/master/image-to-video",
          arguments={
              "prompt": "Sunlight dapples through budding branches, illuminating a vibrant tapestry of greens and browns as a pair of robins meticulously weave twigs and mud into a cradle of life, their tiny forms a whirlwind of activity against a backdrop of blossoming spring.  The scene unfolds with a gentle, observational pace, allowing the viewer to fully appreciate the intricate details of nest construction, the soft textures of downy feathers contrasted against the rough bark of the branches, the delicate balance of strength and fragility in their creation.",
              "image_url": "https://v3.fal.media/files/zebra/9Nrm22YyLojSTPJbZYNhh_image.webp"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2.1/master/image-to-video", {
        input: {
            prompt: "Sunlight dapples through budding branches, illuminating a vibrant tapestry of greens and browns as a pair of robins meticulously weave twigs and mud into a cradle of life, their tiny forms a whirlwind of activity against a backdrop of blossoming spring.  The scene unfolds with a gentle, observational pace, allowing the viewer to fully appreciate the intricate details of nest construction, the soft textures of downy feathers contrasted against the rough bark of the branches, the delicate balance of strength and fragility in their creation.",
            image_url: "https://v3.fal.media/files/zebra/9Nrm22YyLojSTPJbZYNhh_image.webp"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2.1/master/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Sunlight dapples through budding branches, illuminating a vibrant tapestry of greens and browns as a pair of robins meticulously weave twigs and mud into a cradle of life, their tiny forms a whirlwind of activity against a backdrop of blossoming spring.  The scene unfolds with a gentle, observational pace, allowing the viewer to fully appreciate the intricate details of nest construction, the soft textures of downy feathers contrasted against the rough bark of the branches, the delicate balance of strength and fragility in their creation.",
        "image_url": "https://v3.fal.media/files/zebra/9Nrm22YyLojSTPJbZYNhh_image.webp"
      }'
      ```
    </CodeGroup>

    ## Examples

    > Sunlight streams through the window, illuminating the ancient bonsai tree and the gardener's weathered hands as they delicately prune a wayward branch, the soft rustle of shears a counterpoint to the quiet intensity of the moment.  The close-up reveals the intricate texture of the bark, the deep gre...

    <video src="https://v3.fal.media/files/rabbit/fzwNd7kWSLkxFjzuMtrVH_output.mp4" controls width="100%" />

    > Bathed in the warm glow of a single, strategically placed lamp, the jeweler’s weathered hands delicately cradle a fiery opal, its iridescent depths shimmering like a captured sunset; each careful turn reveals new constellations of color, while the close-up shot emphasizes the stone’s alluring textur...

    <video src="https://v3.fal.media/files/rabbit/PbFnNcVm4oOmIADyoWguL_output.mp4" controls width="100%" />

    > Swirls of ivory frosting, smooth as porcelain, rise and fall across a towering six-tiered cake, their delicate peaks catching the warm light, a symphony of creamy white against the rich mahogany of the cake stand.  Each delicate floral arrangement, painstakingly crafted from sugar paste, adds a burs...

    <video src="https://v3.fal.media/files/panda/Vv8_-iXA5LeoNjsG6imIc_output.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="image_url" type="string" required>
      URL of the image to be used for the video
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Sunlight dapples through budding branches, illuminating a vibrant tapestry of greens and browns as a pair of robins meticulously weave twigs and mud into a cradle of life, their tiny forms a whirlwind of activity against a backdrop of blossoming spring.  The scene unfolds with a gentle, observational pace, allowing the viewer to fully appreciate the intricate details of nest construction, the soft textures of downy feathers contrasted against the rough bark of the branches, the delicate balance of strength and fragility in their creation.",
      "image_url": "https://v3.fal.media/files/zebra/9Nrm22YyLojSTPJbZYNhh_image.webp",
      "duration": "5",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/rabbit/YuUWKFq508zzWIiQ0i2vt_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.1/master/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2.1/master/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.1/master/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2.1/master/text-to-video",
          arguments={
              "prompt": "Warm, earthy tones bathe the scene as the potter's hands, rough and calloused, coax a shapeless lump of clay into a vessel of elegant curves, the slow, deliberate movements highlighted by the subtle shifting light; the clay's cool, damp texture contrasts sharply with the warmth of the potter's touch, creating a captivating interplay between material and maker."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2.1/master/text-to-video", {
        input: {
            prompt: "Warm, earthy tones bathe the scene as the potter's hands, rough and calloused, coax a shapeless lump of clay into a vessel of elegant curves, the slow, deliberate movements highlighted by the subtle shifting light; the clay's cool, damp texture contrasts sharply with the warmth of the potter's touch, creating a captivating interplay between material and maker."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2.1/master/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Warm, earthy tones bathe the scene as the potter'\''s hands, rough and calloused, coax a shapeless lump of clay into a vessel of elegant curves, the slow, deliberate movements highlighted by the subtle shifting light; the clay'\''s cool, damp texture contrasts sharply with the warmth of the potter'\''s touch, creating a captivating interplay between material and maker."
      }'
      ```
    </CodeGroup>

    ## Examples

    > Golden sunlight bathes the bustling street market, illuminating the vendor's deft hands as they knead vibrant dough, the flour dusting the air like a soft, ethereal snow;  the sizzle of the seasoned meat, a rhythmic counterpoint to the chatter of the crowd, creates a symphony of sights and sounds, c...

    <video src="https://v3.fal.media/files/elephant/rf9dUthNKPrlmQXKpzhll_output.mp4" controls width="100%" />

    > A breathtaking vista unfolds as the camera captures the inky blackness of the night sky mirroring the deep indigo of the ocean, where waves, edged with an ethereal, electric blue glow, crash gently against the shore, their phosphorescent foam leaving trails of shimmering light like liquid stardust.

    <video src="https://v3.fal.media/files/lion/bh7MmcDsPws1syU8euzO5_output.mp4" controls width="100%" />

    > Molten rivers of incandescent orange and crimson lava, sluggishly tracing paths of destruction across the scorched earth, illuminate the night with an infernal glow;  their viscous surfaces, a tapestry of bubbling textures and crackling crusts, slowly creep onward, leaving behind a trail of solidifi...

    <video src="https://v3.fal.media/files/penguin/AdyDUWgDWpw13y2ejsy1M_output.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Warm, earthy tones bathe the scene as the potter's hands, rough and calloused, coax a shapeless lump of clay into a vessel of elegant curves, the slow, deliberate movements highlighted by the subtle shifting light; the clay's cool, damp texture contrasts sharply with the warmth of the potter's touch, creating a captivating interplay between material and maker.",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3.fal.media/files/lion/0wTlhR7GCXFI-_BZXGy99_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling 2.1 (standard)](/model-api-reference/video-generation-api/kling-2.1-standard) — Video Generation
* [Kling 2.1 (pro)](/model-api-reference/video-generation-api/kling-2.1-pro) — Video Generation
* [Kling 2.1 Master](/model-api-reference/video-generation-api/kling-2.1-master) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2.1-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2.1 Pro API

> API reference for Kling Video V2.1 Pro. Kling 2.1 Pro is an advanced endpoint for the Kling 2.1 model, offering professional-grade videos with enhanced visual fidelity, precise camera movements, and d

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.1/pro/image-to-video`
**Endpoint ID:** `fal-ai/kling-video/v2.1/pro/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.1/pro/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/v2.1/pro/image-to-video",
      arguments={
          "prompt": "Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.",
          "image_url": "https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/v2.1/pro/image-to-video", {
    input: {
        prompt: "Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.",
        image_url: "https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/v2.1/pro/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.",
    "image_url": "https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp"
  }'
  ```
</CodeGroup>

## Examples

> Golden sunlight bathes a weathered old man, his hands, gnarled like ancient olive branches, scattering seeds onto the cobblestones where a flock of iridescent pigeons descends,

<video src="https://v3.fal.media/files/lion/PqeSJnszNGpIM4QN8nGGs_output.mp4" controls width="100%" />

> Golden sunlight bathes the rugged mountain peak as a lone yogi finds stillness amidst the windswept, rocky terrain, their movements a fluid dance between earth and sky;  breath becoming one with the vastness of the alpine landscape, a testament to the quiet power found in moments of mindful connecti...

<video src="https://v3.fal.media/files/panda/pxDM7XwZGaKpkKPzDoUMN_output.mp4" controls width="100%" />

> Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the gliste...

<video src="https://v3.fal.media/files/rabbit/Y5I8-7u3e7ogVSvPin1TS_output.mp4" controls width="100%" />

### Input Schema

<ParamField body="prompt" type="string" required />

<ParamField body="image_url" type="string" required>
  URL of the image to be used for the video
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  The duration of the generated video in seconds Default value: `"5"`

  Possible values: `5`, `10`
</ParamField>

<ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
  Default value: `"blur, distort, and low quality"`
</ParamField>

<ParamField body="cfg_scale" type="float" default="0.5">
  The CFG (Classifier Free Guidance) scale is a measure of how close you want
  the model to stick to your prompt. Default value: `0.5`

  Range: `0` to `1`
</ParamField>

<ParamField body="tail_image_url" type="string">
  URL of the image to be used for the end of the video
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.",
  "image_url": "https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp",
  "duration": "5",
  "negative_prompt": "blur, distort, and low quality",
  "cfg_scale": 0.5
}
```

### Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3.fal.media/files/rabbit/Y5I8-7u3e7ogVSvPin1TS_output.mp4"
  }
}
```

## Kling AI v2.1 Pro - Professional Image-to-Video Generation

Transform static images into dynamic, fluid video content with Kling AI v2.1 Pro, the advanced image-to-video generation model from Kuaishou. Perfect for content creators, marketers, and developers who need high-quality video content at scale.

### Overview

Kling AI v2.1 Pro brings professional-grade video generation capabilities to your applications. Built on advanced machine learning architecture, it excels at creating natural motion patterns and seamless transitions from single images with enhanced visual fidelity, precise camera movements, and dynamic motion control.

Key Capabilities:

* Generate 5 or 10-second videos from any input image
* Advanced motion interpolation for smooth transitions
* Preserve fine details and textures throughout animation
* Support for diverse image types and subjects
* Professional-grade visual quality perfect for cinematic storytelling

### Getting Started

Getting up and running with Kling AI is straightforward. First, set up your development environment:

Using npm:

```bash theme={null}
npm install --save @fal-ai/client
```

Using pip:

```python theme={null}
pip install fal-client
```

Configure your authentication:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY_HERE"
});
```

### Making Your First API Call

Here's a simple example of generating a video from an image:

```typescript theme={null}
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/kling-video/v2.1/pro/image-to-video", {
  input: {
    prompt: "Sunlight dapples through budding branches, illuminating a vibrant tapestry of greens",
    image_url: "https://example.com/your-image.jpg",
    duration: "5",
    aspect_ratio: "16:9",
    negative_prompt: "blur, distort, and low quality",
    cfg_scale: 0.5
  }
});

console.log(result.video.url);
```

### API Parameters

* `prompt` (required): Text description of the desired motion and scene
* `image_url` (required): URL of the input image
* `duration`: Video duration - "5" or "10" seconds
* `aspect_ratio`: Output aspect ratio (e.g., "16:9", "9:16", "1:1")
* `negative_prompt`: Elements to avoid in the generation
* `cfg_scale`: Classifier Free Guidance scale (default: 0.5)
* `static_mask_url`: URL for static motion brush mask
* `dynamic_mask_url`: URL for dynamic motion brush mask
* `special_fx`: Special effects like "hug", "kiss", "heart\_gesture", "squish", "expansion"
* `input_image_urls`: Array of up to 4 images for multi-image generation

### Advanced Features

The Pro version includes several advanced capabilities that set it apart:

#### Motion Control

Fine-tune the intensity and direction of motion with precise controls using motion brush masks and cfg\_scale parameters.

#### Quality Preservation

Advanced interpolation algorithms maintain image quality throughout the video sequence, ensuring crisp details and accurate color reproduction.

#### Special Effects

```typescript theme={null}
const result = await fal.subscribe("fal-ai/kling-video/v2.1/pro/image-to-video", {
  input: {
    prompt: "Romantic scene with special effects",
    image_url: "your-image-url",
    special_fx: "heart_gesture"
  }
});
```

### Model Variants

Kling 2.1 offers multiple quality tiers:

* **Pro**: Professional-grade quality (this model)
* **Standard**: `fal-ai/kling-video/v2.1/standard/image-to-video` - Cost-efficient option
* **Master**: `fal-ai/kling-video/v2.1/master/image-to-video` - Premium tier with unparalleled quality

### Best Practices

To achieve optimal results:

1. Provide high-quality input images (recommended: 1080p or higher)
2. Write detailed prompts describing motion, camera movement, and scene dynamics
3. Use negative prompts to avoid unwanted elements
4. Test different cfg\_scale values (0.3-0.7) for motion control
5. Consider aspect ratio based on your target platform

### Technical Specifications

Processing Capabilities:

* Input formats: JPG, JPEG, PNG, WEBP, GIF, AVIF
* Output format: MP4
* Resolution: Up to 1080p
* Frame rate: Standard video frame rates
* Processing time: Approximately 5 minutes

### Queue Management

For asynchronous processing:

```typescript theme={null}
// Submit request
const { request_id } = await fal.queue.submit("fal-ai/kling-video/v2.1/pro/image-to-video", {
  input: {
    prompt: "Your detailed video description",
    image_url: "your-image-url",
    duration: "10"
  }
});

// Check status
const status = await fal.queue.status("fal-ai/kling-video/v2.1/pro/image-to-video", {
  requestId: request_id,
  logs: true
});

// Get result
const result = await fal.queue.result("fal-ai/kling-video/v2.1/pro/image-to-video", {
  requestId: request_id
});
```

### Pricing and Usage

* **5-second video**: \$0.45
* **Additional seconds**: \$0.09 per second
* 10-second video: \$0.90
* Processing time: Approximately 5 minutes

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Support and Resources

Need help? Access comprehensive support through:

* Technical documentation at [docs.fal.ai](https://docs.fal.ai)
* API Reference: [fal.ai/models/fal-ai/kling-video/v2.1/pro/image-to-video/api](https://fal.ai/models/fal-ai/kling-video/v2.1/pro/image-to-video/api)
* Community forums for peer support
* Direct support channels for Pro users

### Ready to Create Professional Videos?

Get started with Kling AI v2.1 Pro today by signing up at [fal.ai](https://fal.ai) and generating your API key. Transform your static images into engaging, cinematic videos with professional-grade quality.

## Related

* [Kling 2.1 (standard)](/model-api-reference/video-generation-api/kling-2.1-standard) — Video Generation
* [Kling 2.1 Master](/model-api-reference/video-generation-api/kling-2.1-master) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2.1-standard.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2.1 Standard API

> API reference for Kling Video V2.1 Standard. Kling 2.1 Standard is a cost-efficient endpoint for the Kling 2.1 model, delivering high-quality image-to-video generation

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.1/standard/image-to-video`
**Endpoint ID:** `fal-ai/kling-video/v2.1/standard/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.1/standard/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/v2.1/standard/image-to-video",
      arguments={
          "prompt": "As the sun dips below the horizon, painting the sky in fiery hues of orange and purple, powerful waves relentlessly crash against jagged, dark rocks, their white foam a stark contrast to the deepening twilight; the textured surface of the rocks, wet and glistening, reflects the vibrant colors, creating a mesmerizing spectacle of nature's raw power and breathtaking beauty",
          "image_url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-image-to-video.jpg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/v2.1/standard/image-to-video", {
    input: {
        prompt: "As the sun dips below the horizon, painting the sky in fiery hues of orange and purple, powerful waves relentlessly crash against jagged, dark rocks, their white foam a stark contrast to the deepening twilight; the textured surface of the rocks, wet and glistening, reflects the vibrant colors, creating a mesmerizing spectacle of nature's raw power and breathtaking beauty",
        image_url: "https://storage.googleapis.com/falserverless/model_tests/kling/kling-image-to-video.jpg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/v2.1/standard/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "As the sun dips below the horizon, painting the sky in fiery hues of orange and purple, powerful waves relentlessly crash against jagged, dark rocks, their white foam a stark contrast to the deepening twilight; the textured surface of the rocks, wet and glistening, reflects the vibrant colors, creating a mesmerizing spectacle of nature'\''s raw power and breathtaking beauty",
    "image_url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-image-to-video.jpg"
  }'
  ```
</CodeGroup>

## Examples

> A soft, ethereal light bathes the windowpane as countless raindrops dance and collide, their translucent forms creating shimmering, ephemeral patterns against the glass; the gentle rhythm of the falling water creates a mesmerizing, almost hypnotic effect, complemented by a subtle, melancholic piano ...

<video src="https://v3.fal.media/files/panda/CSekH2UBpK0byk9wU7hug_output.mp4" controls width="100%" />

> As the sun dips below the horizon, painting the sky in fiery hues of orange and purple, powerful waves relentlessly crash against jagged, dark rocks, their white foam a stark contrast to the deepening twilight; the textured surface of the rocks, wet and glistening, reflects the vibrant colors, creat...

<video src="https://v3.fal.media/files/panda/aIxNQwcs5syCT5sYT5_HB_output.mp4" controls width="100%" />

> A tapestry of deep indigo and velvety black slowly yields to the first blush of dawn,  as pinpricks of amber light bloom into fiery streaks across the cityscape, revealing a textured landscape of concrete canyons and glowing windows; the city's awakening unfolds like a dream, a symphony of vibrant h...

<video src="https://v3.fal.media/files/rabbit/_Y-5S3Y3d5onS7ZgjVh1B_output.mp4" controls width="100%" />

### Input Schema

<ParamField body="prompt" type="string" required />

<ParamField body="image_url" type="string" required>
  URL of the image to be used for the video
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  The duration of the generated video in seconds Default value: `"5"`

  Possible values: `5`, `10`
</ParamField>

<ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
  Default value: `"blur, distort, and low quality"`
</ParamField>

<ParamField body="cfg_scale" type="float" default="0.5">
  The CFG (Classifier Free Guidance) scale is a measure of how close you want
  the model to stick to your prompt. Default value: `0.5`

  Range: `0` to `1`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "As the sun dips below the horizon, painting the sky in fiery hues of orange and purple, powerful waves relentlessly crash against jagged, dark rocks, their white foam a stark contrast to the deepening twilight; the textured surface of the rocks, wet and glistening, reflects the vibrant colors, creating a mesmerizing spectacle of nature's raw power and breathtaking beauty",
  "image_url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-image-to-video.jpg",
  "duration": "5",
  "negative_prompt": "blur, distort, and low quality",
  "cfg_scale": 0.5
}
```

### Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3.fal.media/files/koala/17e3xh08J4_PkHS_0cbwF_output.mp4"
  }
}
```

## Kling AI v2.1 Standard - Cost-Efficient Image-to-Video Generation

Transform static images into fluid, natural-looking videos with Kling AI v2.1 Standard. This powerful image-to-video model delivers professional-quality motion synthesis ideal for content creators, marketers, and developers.

### Overview

Kling AI v2.1 Standard brings static images to life through advanced motion synthesis technology. Created by Kuaishou, this model excels at generating natural movement while preserving the original image's quality and details. As a cost-efficient endpoint for the Kling 2.1 model, it delivers high-quality image-to-video generation at an accessible price point.

#### Key Capabilities

Transform single images into dynamic videos with:

* Natural motion synthesis that respects physics and object relationships
* Consistent quality throughout the generated video sequence
* Preservation of fine details and textures from source images
* Support for diverse content types including people, animals, objects, and scenes
* Flexible duration options (5 or 10 seconds)

### Popular Use Cases

**Content Creation**
Generate marketing visuals, social media assets, and blog illustrations at scale. Perfect for agencies and content teams who need consistent, high-quality imagery.

**Product Development**\
Create concept art, UI mockups, and design variations for rapid prototyping. Ideal for designers exploring visual directions.

**E-commerce**
Generate product lifestyle images, seasonal campaigns, and A/B testing visuals to boost conversion rates.

**Entertainment**
Produce game assets, storyboard illustrations, and creative concept art for media projects.

### Getting Started

Getting up and running with Kling AI is straightforward. Here's how to begin:

1. Get your API key at [fal.ai/login](https://fal.ai/login)
2. Install the client library for your preferred language
3. Make your first API call

#### Installation

For JavaScript/TypeScript projects:

```bash theme={null}
npm install --save @fal-ai/client
```

For Python projects:

```bash theme={null}
pip install fal-client
```

#### Basic Usage

Here's a simple example of generating a video from an image:

```typescript theme={null}
import { fal } from "@fal-ai/client";

fal.config({
  credentials: "YOUR_FAL_KEY"
});

const result = await fal.subscribe("fal-ai/kling-video/v2.1/standard/image-to-video", {
  input: {
    prompt: "As the sun dips below the horizon, painting the sky in fiery hues",
    image_url: "https://example.com/your-image.jpg",
    duration: "5",
    aspect_ratio: "16:9",
    negative_prompt: "blur, distort, and low quality",
    cfg_scale: 0.5
  }
});

console.log(result.video.url);
```

### API Parameters

* `prompt` (required): Text description of the desired motion and scene
* `image_url` (required): URL of the input image
* `duration`: Video duration - "5" or "10" seconds
* `aspect_ratio`: Output aspect ratio (e.g., "16:9", "9:16", "1:1")
* `negative_prompt`: Elements to avoid in the generation
* `cfg_scale`: Classifier Free Guidance scale (default: 0.5)
* `static_mask_url`: URL for static motion brush mask
* `dynamic_mask_url`: URL for dynamic motion brush mask
* `special_fx`: Special effects like "hug", "kiss", "heart\_gesture", "squish", "expansion"
* `input_image_urls`: Array of up to 4 images for multi-image generation

### Technical Specifications

Performance characteristics:

* Input formats: JPG, JPEG, PNG, WEBP, GIF, AVIF
* Output format: MP4
* Duration options: 5 or 10 seconds
* Processing time: Variable based on load
* Video resolution: Maintains input quality

### Best Practices

To achieve optimal results:

Create videos that engage viewers by following these guidelines:

* Use high-quality source images with clear subjects
* Ensure proper lighting and contrast in your input images
* Consider the intended motion when framing your source image
* Test different cfg\_scale values (0.3-0.7) to find the right motion control
* Write detailed prompts describing the desired motion and scene dynamics

### Queue Management

For asynchronous processing:

```typescript theme={null}
// Submit request
const { request_id } = await fal.queue.submit("fal-ai/kling-video/v2.1/standard/image-to-video", {
  input: {
    prompt: "Your detailed video description",
    image_url: "your-image-url"
  }
});

// Check status
const status = await fal.queue.status("fal-ai/kling-video/v2.1/standard/image-to-video", {
  requestId: request_id,
  logs: true
});

// Get result
const result = await fal.queue.result("fal-ai/kling-video/v2.1/standard/image-to-video", {
  requestId: request_id
});
```

### Pricing and Usage

Cost-efficient pricing structure:

* **5-second video**: \$0.25
* **Additional seconds**: \$0.05 per second
* 10-second video: \$0.50

[View detailed pricing](https://fal.ai/pricing) or [contact sales](mailto:support@fal.ai) for enterprise solutions.

### Model Variants

Kling 2.1 offers multiple quality tiers:

* **Standard**: This model - Cost-efficient option
* **Pro**: `fal-ai/kling-video/v2.1/pro/image-to-video` - Professional grade
* **Master**: `fal-ai/kling-video/v2.1/master/image-to-video` - Premium quality

### Migration Guide

Coming from another platform? Our migration tools and guides make it simple to switch to Kling AI. The API structure follows industry standards with intuitive parameter naming.

### Support and Resources

* API Documentation: [fal.ai/models/fal-ai/kling-video/v2.1/standard/image-to-video/api](https://fal.ai/models/fal-ai/kling-video/v2.1/standard/image-to-video/api)
* Discord Community: [discord.com/invite/fal-ai](https://discord.com/invite/fal-ai)
* Support: [support@fal.ai](mailto:support@fal.ai)

Ready to get started? [Create your free account](https://fal.ai/login) and begin transforming your images into engaging videos with Kling AI v2.1 Standard.

## Related

* [Kling 2.1 (pro)](/model-api-reference/video-generation-api/kling-2.1-pro) — Video Generation
* [Kling 2.1 Master](/model-api-reference/video-generation-api/kling-2.1-master) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2.5-turbo-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2.5 Turbo Pro API

> API reference for Kling Video V2.5 Turbo Pro. Kling 2.5 Turbo Pro: Top-tier image-to-video generation with unparalleled motion fluidity, cinematic visuals, and exceptional prompt precision.

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.5-turbo/pro/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2.5-turbo/pro/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2.5-turbo/pro/image-to-video",
          arguments={
              "prompt": "A stark starting line divides two powerful cars, engines revving for the challenge ahead. They surge forward in the heat of competition, a blur of speed and chrome. The finish line looms as they vie for victory.",
              "image_url": "https://v3.fal.media/files/panda/HnY2yf-BbzlrVQxR-qP6m_9912d0932988453aadf3912fc1901f52.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2.5-turbo/pro/image-to-video", {
        input: {
            prompt: "A stark starting line divides two powerful cars, engines revving for the challenge ahead. They surge forward in the heat of competition, a blur of speed and chrome. The finish line looms as they vie for victory.",
            image_url: "https://v3.fal.media/files/panda/HnY2yf-BbzlrVQxR-qP6m_9912d0932988453aadf3912fc1901f52.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2.5-turbo/pro/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A stark starting line divides two powerful cars, engines revving for the challenge ahead. They surge forward in the heat of competition, a blur of speed and chrome. The finish line looms as they vie for victory.",
        "image_url": "https://v3.fal.media/files/panda/HnY2yf-BbzlrVQxR-qP6m_9912d0932988453aadf3912fc1901f52.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="image_url" type="string" required>
      URL of the image to be used for the video
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="tail_image_url" type="string">
      URL of the image to be used for the end of the video
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A stark starting line divides two powerful cars, engines revving for the challenge ahead. They surge forward in the heat of competition, a blur of speed and chrome. The finish line looms as they vie for victory.",
      "image_url": "https://v3.fal.media/files/panda/HnY2yf-BbzlrVQxR-qP6m_9912d0932988453aadf3912fc1901f52.jpg",
      "duration": "5",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-v2.5-turbo-pro-image-to-video-output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.5-turbo/pro/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2.5-turbo/pro/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2.5-turbo/pro/text-to-video",
          arguments={
              "prompt": "A noble lord walks among his people, his presence a comforting reassurance. He greets them with a gentle smile, embodying their hopes and earning their respect through simple interactions. The atmosphere is intimate and sincere, highlighting the bond between the leader and community."
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2.5-turbo/pro/text-to-video", {
        input: {
            prompt: "A noble lord walks among his people, his presence a comforting reassurance. He greets them with a gentle smile, embodying their hopes and earning their respect through simple interactions. The atmosphere is intimate and sincere, highlighting the bond between the leader and community."
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2.5-turbo/pro/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A noble lord walks among his people, his presence a comforting reassurance. He greets them with a gentle smile, embodying their hopes and earning their respect through simple interactions. The atmosphere is intimate and sincere, highlighting the bond between the leader and community."
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A noble lord walks among his people, his presence a comforting reassurance. He greets them with a gentle smile, embodying their hopes and earning their respect through simple interactions. The atmosphere is intimate and sincere, highlighting the bond between the leader and community.",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/model_tests/kling/kling-v2.5-turbo-pro-text-to-video-output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling v2.5 Text to Video](/model-api-reference/video-generation-api/kling-v2.5-text-to-video) — Video Generation
* [Kling Video](/model-api-reference/video-generation-api/kling-video) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2.5-turbo-standard.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2.5 Turbo Standard API

> API reference for Kling Video V2.5 Turbo Standard. Kling 2.5 Turbo Standard: Top-tier image-to-video generation with unparalleled motion fluidity, cinematic visuals, and exceptional prompt precision.

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.5-turbo/standard/image-to-video`
**Endpoint ID:** `fal-ai/kling-video/v2.5-turbo/standard/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/standard/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/v2.5-turbo/standard/image-to-video",
      arguments={
          "prompt": "In a dimly lit room, a playful cat's eyes light up, fixated on a dancing red dot. With boundless energy, it pounces and leaps, chasing the elusive beam across the floor and up the walls. The simple joy of the hunt unfolds in clear, uncomplicated visuals.",
          "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_v25_std_i2v_input.png"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/v2.5-turbo/standard/image-to-video", {
    input: {
        prompt: "In a dimly lit room, a playful cat's eyes light up, fixated on a dancing red dot. With boundless energy, it pounces and leaps, chasing the elusive beam across the floor and up the walls. The simple joy of the hunt unfolds in clear, uncomplicated visuals.",
        image_url: "https://storage.googleapis.com/falserverless/example_inputs/kling_v25_std_i2v_input.png"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/v2.5-turbo/standard/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "In a dimly lit room, a playful cat'\''s eyes light up, fixated on a dancing red dot. With boundless energy, it pounces and leaps, chasing the elusive beam across the floor and up the walls. The simple joy of the hunt unfolds in clear, uncomplicated visuals.",
    "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_v25_std_i2v_input.png"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="prompt" type="string" required />

<ParamField body="image_url" type="string" required>
  URL of the image to be used for the video
</ParamField>

<ParamField body="duration" type="DurationEnum" default="5">
  The duration of the generated video in seconds Default value: `"5"`

  Possible values: `5`, `10`
</ParamField>

<ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
  Default value: `"blur, distort, and low quality"`
</ParamField>

<ParamField body="cfg_scale" type="float" default="0.5">
  The CFG (Classifier Free Guidance) scale is a measure of how close you want
  the model to stick to your prompt. Default value: `0.5`

  Range: `0` to `1`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "In a dimly lit room, a playful cat's eyes light up, fixated on a dancing red dot. With boundless energy, it pounces and leaps, chasing the elusive beam across the floor and up the walls. The simple joy of the hunt unfolds in clear, uncomplicated visuals.",
  "image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling_v25_std_i2v_input.png",
  "duration": "5",
  "negative_prompt": "blur, distort, and low quality",
  "cfg_scale": 0.5
}
```

### Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_outputs/kling_v25_std_i2v_output.mp4"
  }
}
```

## Related

* [Kling Video](/model-api-reference/video-generation-api/kling-video) — Video Generation
* [Kling v2.5 Text to Video](/model-api-reference/video-generation-api/kling-v2.5-text-to-video) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `cfg_scale` range: 0 to 1


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2.6-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2.6 Pro API

> API reference for Kling Video V2.6 Pro. Kling 2.6 Pro: Top-tier image-to-video with cinematic visuals, fluid motion, and native audio generation.

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.6/pro/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2.6/pro/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.6/pro/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2.6/pro/image-to-video",
          arguments={
              "prompt": "A king walks slowly and says \"My people, here I am! I am here to save you all\"",
              "start_image_url": "https://v3b.fal.media/files/b/0a84ab29/BSJXz9Ht-jgRgMf4IGxLU_upscaled.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2.6/pro/image-to-video", {
        input: {
            prompt: "A king walks slowly and says \"My people, here I am! I am here to save you all\"",
            start_image_url: "https://v3b.fal.media/files/b/0a84ab29/BSJXz9Ht-jgRgMf4IGxLU_upscaled.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2.6/pro/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A king walks slowly and says \"My people, here I am! I am here to save you all\"",
        "start_image_url": "https://v3b.fal.media/files/b/0a84ab29/BSJXz9Ht-jgRgMf4IGxLU_upscaled.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="start_image_url" type="string" required>
      URL of the image to be used for the video
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate native audio for the video. Supports Chinese and English voice output. Other languages are automatically translated to English. For English speech, use lowercase letters; for acronyms or proper nouns, use uppercase. Default value: `true`
    </ParamField>

    <ParamField body="voice_ids" type="list<string>">
      Optional Voice IDs for video generation. Reference voices in your prompt with \<\<\<voice\_1>>> and \<\<\<voice\_2>>> (maximum 2 voices per task). Get voice IDs from the kling video create-voice endpoint: [https://fal.ai/models/fal-ai/kling-video/create-voice](https://fal.ai/models/fal-ai/kling-video/create-voice)
    </ParamField>

    <ParamField body="end_image_url" type="string">
      URL of the image to be used for the end of the video
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A king walks slowly and says \"My people, here I am! I am here to save you all\"",
      "start_image_url": "https://v3b.fal.media/files/b/0a84ab29/BSJXz9Ht-jgRgMf4IGxLU_upscaled.png",
      "duration": "5",
      "negative_prompt": "blur, distort, and low quality",
      "generate_audio": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 11814817,
        "url": "https://v3b.fal.media/files/b/0a84ab51/Qr1twf8UgtD5rZHpNXC2P_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.6/pro/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v2.6/pro/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.6/pro/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2.6/pro/text-to-video",
          arguments={
              "prompt": "Old friends reuniting at a train station after 20 years, one exclaims 'Is that really you?!' other tearfully replies 'I promised I'd come back, didn't I?', train whistle, steam hissing, emotional orchestral swell, crowd murmur"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2.6/pro/text-to-video", {
        input: {
            prompt: "Old friends reuniting at a train station after 20 years, one exclaims 'Is that really you?!' other tearfully replies 'I promised I'd come back, didn't I?', train whistle, steam hissing, emotional orchestral swell, crowd murmur"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2.6/pro/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Old friends reuniting at a train station after 20 years, one exclaims '\''Is that really you?!'\'' other tearfully replies '\''I promised I'\''d come back, didn'\''t I?'\'', train whistle, steam hissing, emotional orchestral swell, crowd murmur"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required />

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `5`, `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate native audio for the video. Supports Chinese and English voice output. Other languages are automatically translated to English. For English speech, use lowercase letters; for acronyms or proper nouns, use uppercase. Default value: `true`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Old friends reuniting at a train station after 20 years, one exclaims 'Is that really you?!' other tearfully replies 'I promised I'd come back, didn't I?', train whistle, steam hissing, emotional orchestral swell, crowd murmur",
      "duration": "5",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5,
      "generate_audio": true
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 8195664,
        "url": "https://v3b.fal.media/files/b/0a84ab71/8hPbLs7n59WhWY-BN69yX_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Motion Control">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.6/pro/motion-control`
    **Endpoint ID:** `fal-ai/kling-video/v2.6/pro/motion-control`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.6/pro/motion-control/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v2.6/pro/motion-control",
          arguments={
              "image_url": "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
              "video_url": "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
              "character_orientation": "video"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v2.6/pro/motion-control", {
        input: {
            image_url: "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
            video_url: "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
            character_orientation: "video"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v2.6/pro/motion-control \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
        "video_url": "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
        "character_orientation": "video"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" />

    <ParamField body="image_url" type="string" required>
      Reference image URL. The characters, backgrounds, and other elements in the generated video are based on this reference image. Characters should have clear body proportions, avoid occlusion, and occupy more than 5% of the image area.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. The character actions in the generated video will be consistent with this reference video. Should contain a realistic style character with entire body or upper body visible, including head, without obstruction. Duration limit depends on character\_orientation: 10s max for 'image', 30s max for 'video'.
    </ParamField>

    <ParamField body="keep_original_sound" type="boolean" default="true">
      Whether to keep the original sound from the reference video. Default value: `true`
    </ParamField>

    <ParamField body="character_orientation" type="CharacterOrientationEnum" required>
      Controls whether the output character's orientation matches the reference image or video. 'video': orientation matches reference video - better for complex motions (max 30s). 'image': orientation matches reference image - better for following camera movements (max 10s).

      Possible values: `image`, `video`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An african american woman dancing",
      "image_url": "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
      "video_url": "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
      "keep_original_sound": true,
      "character_orientation": "video"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 35299865,
        "url": "https://v3b.fal.media/files/b/0a875336/8p3rFiXtx3fE2TLoh59KP_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

Kuaishou's Kling 2.6 Pro delivers cinematic image-to-video generation with native audio synthesis at $0.07 per second (audio off) or $0.14 per second (audio on). Trading compute intensity for production-grade motion quality and integrated speech generation, this positions as a top-tier solution for content creators requiring broadcast-ready output. Built for teams that need audio-visual coherence without post-production stitching.

**Built for:** Social Media Content Creation | Marketing Video Production | Cinematic Prototyping

***

## Native Audio Generation Meets Fluid Motion

Kling 2.6 Pro's architecture integrates speech synthesis directly into the video generation pipeline, supporting Chinese and English voice output with automatic translation for other languages. This contrasts with standard image-to-video models that require separate audio workflows and manual synchronization.

**What this means for you:**

* **Synchronized audio-visual output:** Generate videos with native speech that matches lip movements and scene timing, eliminating post-production audio alignment work
* **Flexible duration control:** Choose between 5-second or 10-second outputs based on content requirements and budget constraints
* **Single-image animation:** Transform static images into fluid video sequences with cinematic motion quality and scene continuity
* **Prompt-driven speech:** Embed dialogue directly in prompts (e.g., "A king walks slowly and says 'My people, here I am!'") for automatic voice generation with proper capitalization handling for English pronunciation

***

## Performance That Scales

Kling 2.6 Pro prioritizes output quality and audio integration over generation speed, positioning as a production-focused solution rather than rapid iteration tool.

| Metric               | Result                                       | Context                                        |
| :------------------- | :------------------------------------------- | :--------------------------------------------- |
| **Duration Options** | 5s or 10s                                    | Configurable via API parameter                 |
| **Cost per Second**  | $0.07 (no audio) / $0.14 (with audio)        | 5s video with audio = \$0.70 total             |
| **Audio Languages**  | Chinese, English (native) + auto-translation | Uppercase for acronyms/proper nouns in English |
| **Input Format**     | Single image URL                             | Accepts jpg, jpeg, png, webp, gif, avif        |

***

## Technical Specifications

| Spec                 | Details                                     |
| :------------------- | :------------------------------------------ |
| **Architecture**     | Kling 2.6 Pro                               |
| **Input Formats**    | Image URL (jpg, jpeg, png, webp, gif, avif) |
| **Output Formats**   | MP4 video with optional audio track         |
| **Duration Control** | 5 or 10 seconds (configurable)              |
| **License**          | Commercial use permitted (Partner)          |

[API Documentation](https://fal.ai/models/fal-ai/kling-video/v2.6/pro/image-to-video/api)

***

## How It Stacks Up

**Kling Video Image to Video (v2.5-turbo)** - Kling 2.6 Pro trades generation speed for native audio synthesis and enhanced motion quality, making it ideal for production workflows requiring integrated speech output. The [v2.5-turbo variant](https://fal.ai/models/fal-ai/kling-video/v2.5-turbo/pro/image-to-video) prioritizes faster iteration cycles for teams testing concepts without audio requirements.

**Kling 1.6 Image to Video** - Kling 2.6 Pro offers native audio generation and refined motion fidelity compared to the [1.6 baseline](https://fal.ai/models/fal-ai/kling-video/v1.6/pro/image-to-video), positioning as the premium tier for broadcast-quality output. Version 1.6 remains viable for projects where audio integration isn't critical.

**Kling 2.0 Master Image to Video** - Kling 2.6 Pro extends the 2.0 architecture with improved speech synthesis capabilities and motion coherence. The [2.0 Master variant](https://fal.ai/models/fal-ai/kling-video/v2/master/image-to-video) serves workflows requiring the previous generation's specific characteristics or [pricing structure](https://fal.ai/pricing).

**Kling 2.1 (standard) Image to Video** - Kling 2.6 Pro delivers enhanced audio quality and cinematic motion compared to the [2.1 standard tier](https://fal.ai/models/fal-ai/kling-video/v2.1/standard/image-to-video). The 2.1 standard remains cost-effective for projects where Pro-level audio fidelity isn't essential.

## Related

* [Kling Video v2.6 Motion Control \[Standard\]](/model-api-reference/video-generation-api/kling-video-v2.6-motion-control) — Video Generation
* [Kling Video v2.6 Text to Video](/model-api-reference/video-generation-api/kling-video-v2.6-text-to-video) — Video Generation
* [Kling Video v2.6 Image to Video](/model-api-reference/video-generation-api/kling-video-v2.6-image-to-video) — Video Generation

## Limitations

* `duration` restricted to: `5`, `10`
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`
* `cfg_scale` range: 0 to 1
* `character_orientation` restricted to: `image`, `video`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v2.6-standard.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V2.6 Standard API

> API reference for Kling Video V2.6 Standard. Transfer movements from a reference video to any character image. Cost-effective mode for motion transfer, perfect for portraits and simple animations.

**Endpoint:** `POST https://fal.run/fal-ai/kling-video/v2.6/standard/motion-control`
**Endpoint ID:** `fal-ai/kling-video/v2.6/standard/motion-control`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v2.6/standard/motion-control/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/kling-video/v2.6/standard/motion-control",
      arguments={
          "image_url": "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
          "video_url": "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
          "character_orientation": "video"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/kling-video/v2.6/standard/motion-control", {
    input: {
        image_url: "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
        video_url: "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
        character_orientation: "video"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/kling-video/v2.6/standard/motion-control \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
    "video_url": "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
    "character_orientation": "video"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="prompt" type="string" />

<ParamField body="image_url" type="string" required>
  Reference image URL. The characters, backgrounds, and other elements in the generated video are based on this reference image. Characters should have clear body proportions, avoid occlusion, and occupy more than 5% of the image area.
</ParamField>

<ParamField body="video_url" type="string" required>
  Reference video URL. The character actions in the generated video will be consistent with this reference video. Should contain a realistic style character with entire body or upper body visible, including head, without obstruction. Duration limit depends on character\_orientation: 10s max for 'image', 30s max for 'video'.
</ParamField>

<ParamField body="keep_original_sound" type="boolean" default="true">
  Whether to keep the original sound from the reference video. Default value: `true`
</ParamField>

<ParamField body="character_orientation" type="CharacterOrientationEnum" required>
  Controls whether the output character's orientation matches the reference image or video. 'video': orientation matches reference video - better for complex motions (max 30s). 'image': orientation matches reference image - better for following camera movements (max 10s).

  Possible values: `image`, `video`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video
</ParamField>

### Input Example

```json theme={null}
{
  "prompt": "An african american woman dancing",
  "image_url": "https://v3b.fal.media/files/b/0a875302/8NaxQrQxDNHppHtqcchMm.png",
  "video_url": "https://v3b.fal.media/files/b/0a8752bc/2xrNS217ngQ3wzXqA7LXr_output.mp4",
  "keep_original_sound": true,
  "character_orientation": "video"
}
```

### Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "file_name": "output.mp4",
    "file_size": 35299865,
    "url": "https://v3b.fal.media/files/b/0a875336/8p3rFiXtx3fE2TLoh59KP_output.mp4"
  }
}
```

## Related

* [Kling Video v2.6 Image to Video](/model-api-reference/video-generation-api/kling-video-v2.6-image-to-video) — Video Generation
* [Kling Video v2.6 Text to Video](/model-api-reference/video-generation-api/kling-video-v2.6-text-to-video) — Video Generation
* [Kling Video v2.6 Motion Control \[Pro\]](/model-api-reference/video-generation-api/kling-video-v2.6-motion-control) — Video Generation

## Limitations

* `character_orientation` restricted to: `image`, `video`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v3-pro.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V3 Pro API

> API reference for Kling Video V3 Pro. Kling 3.0 Pro: Top-tier text-to-video with cinematic visuals, fluid motion, and native audio generation, with multi-shot support.

<Tabs>
  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v3/pro/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v3/pro/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v3/pro/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v3/pro/text-to-video",
          arguments={},
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v3/pro/text-to-video", {
        input: {},
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v3/pro/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{}'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string">
      Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    <ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
      List of prompts for multi-shot video generation. If provided, overrides the single prompt and divides the video into multiple shots with specified prompts and durations.
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate native audio for the video. Supports Chinese and English voice output. Other languages are automatically translated to English. For English speech, use lowercase letters; for acronyms or proper nouns, use uppercase. Default value: `true`
    </ParamField>

    <ParamField body="shot_type" type="ShotTypeEnum" default="customize">
      The type of multi-shot video generation Default value: `"customize"`

      Possible values: `customize`, `intelligent`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Close-up of glowing fireflies dancing in a dark forest at twilight. Soft bioluminescent particles float through the air. Shallow depth of field, bokeh lights in background. Magical atmosphere, gentle movement.",
      "duration": "5",
      "multi_prompt": null,
      "generate_audio": true,
      "shot_type": "customize",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 8062911,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-v3/pro-t2v/out.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v3/pro/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v3/pro/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v3/pro/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v3/pro/image-to-video",
          arguments={
              "start_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/pro-i2v/start_image.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v3/pro/image-to-video", {
        input: {
            start_image_url: "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/pro-i2v/start_image.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v3/pro/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "start_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/pro-i2v/start_image.png"
      }'
      ```
    </CodeGroup>

    ## Examples

    <video src="https://v3b.fal.media/files/b/0a9270c0/M0OE5-o3n7Pj85CWWpGt2_output.mp4" controls width="100%" />

    > Motorcycle racing through traffic at dangerous speeds

    <video src="https://v3b.fal.media/files/b/0a8d2087/7Ps8bBagTdb-frW9zj1BT_output.mp4" controls width="100%" />

    > Motorcycle racing through traffic at dangerous speeds

    <video src="https://v3b.fal.media/files/b/0a920eb0/5ecOVwqw-5zFU3_Py4xCK_output.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string">
      Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
    </ParamField>

    <ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
      List of prompts for multi-shot video generation. If provided, divides the video into multiple shots.
    </ParamField>

    <ParamField body="start_image_url" type="string" required>
      URL of the image to be used for the video
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate native audio for the video. Supports Chinese and English voice output. Other languages are automatically translated to English. For English speech, use lowercase letters; for acronyms or proper nouns, use uppercase. Default value: `true`
    </ParamField>

    <ParamField body="end_image_url" type="string">
      URL of the image to be used for the end of the video
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ComboElementInput>">
      Elements (characters/objects) to include in the video. Each example can either be an image set (frontal + reference images) or a video. Reference in prompt as @Element1, @Element2, etc.
    </ParamField>

    <ParamField body="shot_type" type="string" default="customize">
      The type of multi-shot video generation. Required when multi\_prompt is provided. Default value: `"customize"`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "The craftsman slowly examines the bowl, turning it gently in his weathered hands. His eyes reflect years of wisdom. Subtle smile forms on his face. Dust particles drift in warm light. Breathing motion, blinking eyes.",
      "multi_prompt": null,
      "start_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/pro-i2v/start_image.png",
      "duration": "12",
      "generate_audio": true,
      "elements": [
        {
          "frontal_image_url": "https://v3b.fal.media/files/b/0a8cfd5f/-kZL-ha3Iuelku5IHXC-A_glasses.png",
          "reference_image_urls": [
            "https://v3b.fal.media/files/b/0a8cfd62/psPCmzrD1y9vDgdyNfKAL_glasses_back.png"
          ]
        },
        {
          "video_url": "https://v3b.fal.media/files/b/0a8cfd66/b03SOiQvKLlFx_jqdNZ9z_child_video.mp4"
        }
      ],
      "shot_type": "customize",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "out.mp4",
        "file_size": 8431922,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-v3/pro-i2v/out.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Motion Control">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v3/pro/motion-control`
    **Endpoint ID:** `fal-ai/kling-video/v3/pro/motion-control`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v3/pro/motion-control/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v3/pro/motion-control",
          arguments={
              "image_url": "https://v3b.fal.media/files/b/0a90ffa7/TNErq9yD7ZxGRATjfAqnh_EIgJSN67.png",
              "video_url": "https://v3b.fal.media/files/b/0a90ff92/hklvF__w53diz6Rve7f5__JuDW2xl0mr6sJ_Kjz3Vxe_vidoeook%20(1)_1.mp4",
              "character_orientation": "image"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v3/pro/motion-control", {
        input: {
            image_url: "https://v3b.fal.media/files/b/0a90ffa7/TNErq9yD7ZxGRATjfAqnh_EIgJSN67.png",
            video_url: "https://v3b.fal.media/files/b/0a90ff92/hklvF__w53diz6Rve7f5__JuDW2xl0mr6sJ_Kjz3Vxe_vidoeook%20(1)_1.mp4",
            character_orientation: "image"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v3/pro/motion-control \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://v3b.fal.media/files/b/0a90ffa7/TNErq9yD7ZxGRATjfAqnh_EIgJSN67.png",
        "video_url": "https://v3b.fal.media/files/b/0a90ff92/hklvF__w53diz6Rve7f5__JuDW2xl0mr6sJ_Kjz3Vxe_vidoeook%20(1)_1.mp4",
        "character_orientation": "image"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" />

    <ParamField body="image_url" type="string" required>
      Reference image URL. The characters, backgrounds, and other elements in the generated video are based on this reference image. Characters should have clear body proportions, avoid occlusion, and occupy more than 5% of the image area.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. The character actions in the generated video will be consistent with this reference video. Should contain a realistic style character with entire body or upper body visible, including head, without obstruction. Duration limit depends on character\_orientation: 10s max for 'image', 30s max for 'video'.
    </ParamField>

    <ParamField body="keep_original_sound" type="boolean" default="true">
      Whether to keep the original sound from the reference video. Default value: `true`
    </ParamField>

    <ParamField body="character_orientation" type="CharacterOrientationEnum" required>
      Controls whether the output character's orientation matches the reference image or video. 'video': orientation matches reference video - better for complex motions (max 30s). 'image': orientation matches reference image - better for following camera movements (max 10s).

      Possible values: `image`, `video`
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ImageElementInput>">
      Optional element for facial consistency binding. Upload a facial element to enhance identity preservation in the generated video. Only 1 element is supported. Reference in prompt as @Element1. Element binding is only supported when character\_orientation is 'video'.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A man dancing",
      "image_url": "https://v3b.fal.media/files/b/0a90ffa7/TNErq9yD7ZxGRATjfAqnh_EIgJSN67.png",
      "video_url": "https://v3b.fal.media/files/b/0a90ff92/hklvF__w53diz6Rve7f5__JuDW2xl0mr6sJ_Kjz3Vxe_vidoeook%20(1)_1.mp4",
      "keep_original_sound": true,
      "character_orientation": "image",
      "elements": null
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3b.fal.media/files/b/0a90ffb9/CnmmxIvK05VAq4gG8WiEQ_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling Video v3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-video-v3-image-to-video) — Video Generation
* [Kling Video v3 Text to Video \[Standard\]](/model-api-reference/video-generation-api/kling-video-v3-text-to-video) — Video Generation
* [Kling Video](/model-api-reference/video-generation-api/kling-video) — Video Generation

## Limitations

* `shot_type` restricted to: `customize`, `intelligent`
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`
* `cfg_scale` range: 0 to 1
* `character_orientation` restricted to: `image`, `video`


# https://fal.ai/docs/model-api-reference/video-generation-api/kling-video-v3-standard.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kling Video V3 Standard API

> API reference for Kling Video V3 Standard. Kling 3.0 Standard: Top-tier image-to-video with cinematic visuals, fluid motion, and native audio generation, with custom element support.

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v3/standard/image-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v3/standard/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v3/standard/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v3/standard/image-to-video",
          arguments={
              "start_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/standard-i2v/start_image.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v3/standard/image-to-video", {
        input: {
            start_image_url: "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/standard-i2v/start_image.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v3/standard/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "start_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/standard-i2v/start_image.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string">
      Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
    </ParamField>

    <ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
      List of prompts for multi-shot video generation. If provided, divides the video into multiple shots.
    </ParamField>

    <ParamField body="start_image_url" type="string" required>
      URL of the image to be used for the video
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate native audio for the video. Supports Chinese and English voice output. Other languages are automatically translated to English. For English speech, use lowercase letters; for acronyms or proper nouns, use uppercase. Default value: `true`
    </ParamField>

    <ParamField body="end_image_url" type="string">
      URL of the image to be used for the end of the video
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ComboElementInput>">
      Elements (characters/objects) to include in the video. Each example can either be an image set (frontal + reference images) or a video. Reference in prompt as @Element1, @Element2, etc.
    </ParamField>

    <ParamField body="shot_type" type="string" default="customize">
      The type of multi-shot video generation. Required when multi\_prompt is provided. Default value: `"customize"`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Camera slowly orbits around the vase. Soft light shifts across the ceramic surface. The pampas grass sways gently. Shadows move elegantly. Smooth continuous motion, premium feel.",
      "multi_prompt": null,
      "start_image_url": "https://storage.googleapis.com/falserverless/example_inputs/kling-v3/standard-i2v/start_image.png",
      "duration": "12",
      "generate_audio": true,
      "elements": [
        {
          "frontal_image_url": "https://v3b.fal.media/files/b/0a8cfd5f/-kZL-ha3Iuelku5IHXC-A_glasses.png",
          "reference_image_urls": [
            "https://v3b.fal.media/files/b/0a8cfd62/psPCmzrD1y9vDgdyNfKAL_glasses_back.png"
          ]
        },
        {
          "video_url": "https://v3b.fal.media/files/b/0a8cfd66/b03SOiQvKLlFx_jqdNZ9z_child_video.mp4"
        }
      ],
      "shot_type": "customize",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "out.mp4",
        "file_size": 3149129,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-v3/standard-i2v/out.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v3/standard/text-to-video`
    **Endpoint ID:** `fal-ai/kling-video/v3/standard/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v3/standard/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v3/standard/text-to-video",
          arguments={},
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v3/standard/text-to-video", {
        input: {},
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v3/standard/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{}'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string">
      Text prompt for video generation. Either prompt or multi\_prompt must be provided, but not both.
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="5">
      The duration of the generated video in seconds Default value: `"5"`

      Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
    </ParamField>

    <ParamField body="multi_prompt" type="list<KlingV3MultiPromptElement>">
      List of prompts for multi-shot video generation. If provided, overrides the single prompt and divides the video into multiple shots with specified prompts and durations.
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate native audio for the video. Supports Chinese and English voice output. Other languages are automatically translated to English. For English speech, use lowercase letters; for acronyms or proper nouns, use uppercase. Default value: `true`
    </ParamField>

    <ParamField body="shot_type" type="ShotTypeEnum" default="customize">
      The type of multi-shot video generation Default value: `"customize"`

      Possible values: `customize`, `intelligent`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video frame Default value: `"16:9"`

      Possible values: `16:9`, `9:16`, `1:1`
    </ParamField>

    <ParamField body="negative_prompt" type="string" default="blur, distort, and low quality">
      Default value: `"blur, distort, and low quality"`
    </ParamField>

    <ParamField body="cfg_scale" type="float" default="0.5">
      The CFG (Classifier Free Guidance) scale is a measure of how close you want
      the model to stick to your prompt. Default value: `0.5`

      Range: `0` to `1`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Cinematic drone shot flying through ancient stone ruins covered in moss and vines at golden hour. Camera starts low, rises through crumbling archways, revealing a vast misty valley beyond. Volumetric light rays pierce through gaps in the stone. Epic scale, photorealistic, 8K quality.",
      "duration": "5",
      "multi_prompt": null,
      "generate_audio": true,
      "shot_type": "customize",
      "aspect_ratio": "16:9",
      "negative_prompt": "blur, distort, and low quality",
      "cfg_scale": 0.5
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "file_name": "output.mp4",
        "file_size": 6797486,
        "url": "https://storage.googleapis.com/falserverless/example_outputs/kling-v3/standard-t2v/out.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Motion Control">
    **Endpoint:** `POST https://fal.run/fal-ai/kling-video/v3/standard/motion-control`
    **Endpoint ID:** `fal-ai/kling-video/v3/standard/motion-control`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/kling-video/v3/standard/motion-control/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/kling-video/v3/standard/motion-control",
          arguments={
              "image_url": "https://v3b.fal.media/files/b/0a90ee31/VHtWK5BZMa-XoT6gahJKS_077.png",
              "video_url": "https://v3b.fal.media/files/b/0a90edae/3nvl30ic9g2otKRcOV5nO_output.mp4",
              "character_orientation": "video"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/kling-video/v3/standard/motion-control", {
        input: {
            image_url: "https://v3b.fal.media/files/b/0a90ee31/VHtWK5BZMa-XoT6gahJKS_077.png",
            video_url: "https://v3b.fal.media/files/b/0a90edae/3nvl30ic9g2otKRcOV5nO_output.mp4",
            character_orientation: "video"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/kling-video/v3/standard/motion-control \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://v3b.fal.media/files/b/0a90ee31/VHtWK5BZMa-XoT6gahJKS_077.png",
        "video_url": "https://v3b.fal.media/files/b/0a90edae/3nvl30ic9g2otKRcOV5nO_output.mp4",
        "character_orientation": "video"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" />

    <ParamField body="image_url" type="string" required>
      Reference image URL. The characters, backgrounds, and other elements in the generated video are based on this reference image. Characters should have clear body proportions, avoid occlusion, and occupy more than 5% of the image area.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      Reference video URL. The character actions in the generated video will be consistent with this reference video. Should contain a realistic style character with entire body or upper body visible, including head, without obstruction. Duration limit depends on character\_orientation: 10s max for 'image', 30s max for 'video'.
    </ParamField>

    <ParamField body="keep_original_sound" type="boolean" default="true">
      Whether to keep the original sound from the reference video. Default value: `true`
    </ParamField>

    <ParamField body="character_orientation" type="CharacterOrientationEnum" required>
      Controls whether the output character's orientation matches the reference image or video. 'video': orientation matches reference video - better for complex motions (max 30s). 'image': orientation matches reference image - better for following camera movements (max 10s).

      Possible values: `image`, `video`
    </ParamField>

    <ParamField body="elements" type="list<KlingV3ImageElementInput>">
      Optional element for facial consistency binding. Upload a facial element to enhance identity preservation in the generated video. Only 1 element is supported. Reference in prompt as @Element1. Element binding is only supported when character\_orientation is 'video'.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "An man dancing",
      "image_url": "https://v3b.fal.media/files/b/0a90ee31/VHtWK5BZMa-XoT6gahJKS_077.png",
      "video_url": "https://v3b.fal.media/files/b/0a90edae/3nvl30ic9g2otKRcOV5nO_output.mp4",
      "keep_original_sound": true,
      "character_orientation": "video",
      "elements": null
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3b.fal.media/files/b/0a90ee68/7-xpX-LTxX_nRHL776FrZ_output.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Kling Video v3 Text to Video \[Pro\]](/model-api-reference/video-generation-api/kling-video-v3-text-to-video) — Video Generation
* [Kling Video v3 Image to Video \[Pro\]](/model-api-reference/video-generation-api/kling-video-v3-image-to-video) — Video Generation
* [Kling Video](/model-api-reference/video-generation-api/kling-video) — Video Generation

## Limitations

* `cfg_scale` range: 0 to 1
* `shot_type` restricted to: `customize`, `intelligent`
* `aspect_ratio` restricted to: `16:9`, `9:16`, `1:1`
* `character_orientation` restricted to: `image`, `video`


# https://fal.ai/docs/model-api-reference/video-generation-api/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Video Generation API

> Video Generation API reference. Generate videos from text prompts or images using cutting-edge video generation models.

## Overview

Generate videos from text prompts or images using cutting-edge video generation models. These models support text-to-video, image-to-video, and video-to-video workflows.

## Top Models

<CardGroup cols={2}>
  <Card title="Seedance 2.0 Text to Video API API" href="/model-api-reference/video-generation-api/bytedance-seedance-2.0-text-to-video">
    ByteDance's most advanced text-to-video model. Cinematic output with native audio, multi-shot editing, real-world physics, and director-level camera control.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a9460e7/626QXDcTbiOI5I3LPidrR_1ae86d7b0fbb47b3b6d1a41e7fc00956.jpg" alt="Example output from Seedance 2.0 Text to Video API" noZoom />
    </Frame>
  </Card>

  <Card title="Kling Video v3 Text to Video [Pro] API" href="/model-api-reference/video-generation-api/kling-video-v3-pro">
    Kling 3.0 Pro: Top-tier text-to-video with cinematic visuals, fluid motion, and native audio generation, with multi-shot support.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8cfd13/t6TSkWzl6cFAzvO1PCdDu_f38263f637d245929f03881454951540.jpg" alt="Example output from Kling Video v3 Text to Video [Pro]" noZoom />
    </Frame>
  </Card>

  <Card title="Sora 2 API" href="/model-api-reference/video-generation-api/sora-2-text-to-video">
    Text-to-video endpoint for Sora 2, OpenAI's state-of-the-art video model capable of creating richly detailed, dynamic clips with audio from natural language or images.

    <Frame>
      <img src="https://v3.fal.media/files/penguin/eOGowiQKXIKwyDfwgeWQO_b80784431c524553a564ebdd7550d7e6.jpg" alt="Example output from Sora 2" noZoom />
    </Frame>
  </Card>

  <Card title="Veo 3.1 API" href="/model-api-reference/video-generation-api/veo3.1">
    Veo 3.1 by Google, the most advanced AI video generation model in the world. With sound on!

    <Frame>
      <img src="https://v3b.fal.media/files/b/tiger/TGTZBJyLk9HdwjB6SB90e.png" alt="Example output from Veo 3.1" noZoom />
    </Frame>
  </Card>

  <Card title="Grok Imagine Video API" href="/model-api-reference/video-generation-api/xai-grok-imagine-video">
    Generate videos from images with audio using xAI's Grok Imagine Video model.

    <Frame>
      <img src="https://v3b.fal.media/files/b/0a8a0dd0/3wXg362MQ0pczC2ZQFBfW_c153dd469fd14b75bbd9fa6d27f1b63e.jpg" alt="Example output from Grok Imagine Video" noZoom />
    </Frame>
  </Card>

  <Card title="Topaz Video Upscale API" href="/model-api-reference/video-generation-api/topaz-upscale">
    Professional-grade video upscaling using Topaz technology. Enhance your videos with high-quality upscaling.

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/topaz-video-upscale.png" alt="Example output from Topaz Video Upscale" noZoom />
    </Frame>
  </Card>

  <Card title="SeedVR2 API" href="/model-api-reference/video-generation-api/seedvr-upscale">
    Upscale your videos using SeedVR2 with temporal consistency!

    <Frame>
      <img src="https://v3.fal.media/files/koala/cAs3xUC9Lx-jlQh-27-60_4dddbb5a9bac42da86ddf20a5b9d30b3.jpg" alt="Example output from SeedVR2" noZoom />
    </Frame>
  </Card>

  <Card title="Video API" href="/model-api-reference/video-generation-api/bria-video">
    Automatically remove backgrounds from videos -perfect for creating clean, professional content without a green screen.

    <Frame>
      <img src="https://storage.googleapis.com/fal_cdn/fal/Sound-2.jpg" alt="Example output from Video" noZoom />
    </Frame>
  </Card>

  <Card title="Birefnet API" href="/model-api-reference/video-generation-api/birefnet-v2">
    Video background removal version of bilateral reference framework (BiRefNet) for high-resolution dichotomous image segmentation (DIS)

    <Frame>
      <img src="https://v3b.fal.media/files/b/monkey/SKrLsOM3RMOk-QuNj8-io_6356be1b301e454394d2e0a853b98c76.jpg" alt="Example output from Birefnet" noZoom />
    </Frame>
  </Card>
</CardGroup>

Explore all video generation models on [fal.ai/models](https://fal.ai/models).

## Quick Start

Get started with **Bytedance Seedance 2.0 Text To Video**:

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "bytedance/seedance-2.0/text-to-video",
      arguments={
          "prompt": "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("bytedance/seedance-2.0/text-to-video", {
    input: {
        prompt: "An octopus finds a football in the ocean and excitedly calls its octopus friends to come and play. Cut scene to an octopus football game under the sea."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```
</CodeGroup>

## Pricing

For detailed pricing information, see the [fal.ai pricing page](https://fal.ai/pricing) or individual model pages.


# https://fal.ai/docs/model-api-reference/video-generation-api/seedvr-upscale.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Seedvr Upscale API

> API reference for Seedvr Upscale. Upscale your videos using SeedVR2 with temporal consistency!

**Endpoint:** `POST https://fal.run/fal-ai/seedvr/upscale/video`
**Endpoint ID:** `fal-ai/seedvr/upscale/video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/seedvr/upscale/video/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/seedvr/upscale/video",
      arguments={
          "video_url": "https://storage.googleapis.com/falserverless/example_inputs/seedvr-input.mp4"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/seedvr/upscale/video", {
    input: {
        video_url: "https://storage.googleapis.com/falserverless/example_inputs/seedvr-input.mp4"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/seedvr/upscale/video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "video_url": "https://storage.googleapis.com/falserverless/example_inputs/seedvr-input.mp4"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="video_url" type="string" required>
  The input video to be processed
</ParamField>

<ParamField body="upscale_mode" type="UpscaleModeEnum" default="factor">
  The mode to use for the upscale. If 'target', the upscale factor will be calculated based on the target resolution. If 'factor', the upscale factor will be used directly. Default value: `"factor"`

  Possible values: `target`, `factor`
</ParamField>

<ParamField body="upscale_factor" type="float" default="2">
  Upscaling factor to be used. Will multiply the dimensions with this factor when `upscale_mode` is `factor`. Default value: `2`

  Range: `1` to `10`
</ParamField>

<ParamField body="target_resolution" type="TargetResolutionEnum" default="1080p">
  The target resolution to upscale to when `upscale_mode` is `target`. Default value: `"1080p"`

  Possible values: `720p`, `1080p`, `1440p`, `2160p`
</ParamField>

<ParamField body="seed" type="integer">
  The random seed used for the generation process.
</ParamField>

<ParamField body="noise_scale" type="float" default="0.1">
  The noise scale to use for the generation process. Default value: `0.1`

  Range: `0` to `1`, step: `0.001`
</ParamField>

<ParamField body="output_format" type="OutputFormatEnum" default="X264 (.mp4)">
  The format of the output video. Default value: `"X264 (.mp4)"`

  Possible values: `X264 (.mp4)`, `VP9 (.webm)`, `PRORES4444 (.mov)`, `GIF (.gif)`
</ParamField>

<ParamField body="output_quality" type="OutputQualityEnum" default="high">
  The quality of the output video. Default value: `"high"`

  Possible values: `low`, `medium`, `high`, `maximum`
</ParamField>

<ParamField body="output_write_mode" type="OutputWriteModeEnum" default="balanced">
  The write mode of the output video. Default value: `"balanced"`

  Possible values: `fast`, `balanced`, `small`
</ParamField>

<ParamField body="sync_mode" type="boolean" default="false">
  If `True`, the media will be returned as a data URI and the output data won't be available in the request history.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  Upscaled video file after processing
</ParamField>

<ParamField body="seed" type="integer" required>
  The random seed used for the generation process.
</ParamField>

### Input Example

```json theme={null}
{
  "video_url": "https://storage.googleapis.com/falserverless/example_inputs/seedvr-input.mp4",
  "upscale_mode": "factor",
  "upscale_factor": 2,
  "target_resolution": "1080p",
  "noise_scale": 0.1,
  "output_format": "X264 (.mp4)",
  "output_quality": "high",
  "output_write_mode": "balanced",
  "sync_mode": false
}
```

### Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "url": "https://storage.googleapis.com/falserverless/example_outputs/seedvr-output.mp4"
  }
}
```

## Related

* [SeedVR2](/model-api-reference/image-generation-api/seedvr2) — Image Generation

## Limitations

* `upscale_mode` restricted to: `target`, `factor`
* `upscale_factor` range: 1 to 10
* `target_resolution` restricted to: `720p`, `1080p`, `1440p`, `2160p`
* `noise_scale` range: 0 to 1 (step 0.001)
* `output_format` restricted to: `X264 (.mp4)`, `VP9 (.webm)`, `PRORES4444 (.mov)`, `GIF (.gif)`
* `output_quality` restricted to: `low`, `medium`, `high`, `maximum`
* `output_write_mode` restricted to: `fast`, `balanced`, `small`


# https://fal.ai/docs/model-api-reference/video-generation-api/sora-2-characters.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sora 2 Characters API

> API reference for Sora 2 Characters. Generate character ids to use with Sora 2 generations

**Endpoint:** `POST https://fal.run/fal-ai/sora-2/characters`
**Endpoint ID:** `fal-ai/sora-2/characters`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/sora-2/characters/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/sora-2/characters",
      arguments={
          "video_url": "",
          "name": ""
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/sora-2/characters", {
    input: {
        video_url: "",
        name: ""
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/sora-2/characters \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "video_url": "",
    "name": ""
  }'
  ```
</CodeGroup>

## Related

* [Sora 2](/model-api-reference/video-generation-api/sora-2) — Video Generation

## Capabilities

* Video input

## API Reference

### Input Schema

<ParamField body="video_url" type="string" required>
  URL of an MP4 video (minimum 720p, max \~2.67:1 aspect ratio) to define the character. Videos exceeding 1080p are automatically scaled down. Non-standard aspect ratios are automatically padded to 16:9 (landscape) or 9:16 (portrait). Videos longer than 4 seconds are trimmed to the first 4 seconds.
</ParamField>

<ParamField body="name" type="string" required>
  Name for the character (1–80 characters). Refer to this name in prompts when using the character.
</ParamField>

### Output Schema

<ParamField body="id" type="string" required>
  API character ID (format char\_...). Use this in character\_ids when generating video.
</ParamField>

<ParamField body="name" type="string" required>
  The character name
</ParamField>

## Input Example

```json theme={null}
{
  "video_url": "",
  "name": ""
}
```

## Output Example

```json theme={null}
{
  "id": "char_123",
  "name": ""
}
```


# https://fal.ai/docs/model-api-reference/video-generation-api/sora-2-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sora 2 Image To Video API

> API reference for Sora 2 Image To Video. Image-to-video endpoint for Sora 2, OpenAI's state-of-the-art video model capable of creating richly detailed, dynamic clips with audio from natural language o

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/sora-2/image-to-video`
    **Endpoint ID:** `fal-ai/sora-2/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/sora-2/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/sora-2/image-to-video",
          arguments={
              "prompt": "Front-facing 'invisible' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: 'This is insanely fun! You've got to try it—book a tandem and go!' Natural wind roar, voice close-mic'd and slightly compressed so it's intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/sora-2/image-to-video", {
        input: {
            prompt: "Front-facing 'invisible' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: 'This is insanely fun! You've got to try it—book a tandem and go!' Natural wind roar, voice close-mic'd and slightly compressed so it's intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/sora-2/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Front-facing '\''invisible'\'' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: '\''This is insanely fun! You'\''ve got to try it—book a tandem and go!'\'' Natural wind roar, voice close-mic'\''d and slightly compressed so it'\''s intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="auto">
      The resolution of the generated video Default value: `"auto"`

      Possible values: `auto`, `720p`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video Default value: `"auto"`

      Possible values: `auto`, `9:16`, `16:9`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="4">
      Duration of the generated video in seconds Default value: `"4"`

      Possible values: `4`, `8`, `12`, `16`, `20`
    </ParamField>

    <ParamField body="delete_video" type="boolean" default="true">
      Whether to delete the video after generation for privacy reasons. If True, the video cannot be used for remixing and will be permanently deleted. Default value: `true`
    </ParamField>

    <ParamField body="model" type="ModelEnum" default="sora-2">
      The model to use for the generation. When the default model is selected, the latest snapshot of the model will be used - otherwise, select a specific snapshot of the model. Default value: `"sora-2"`

      Possible values: `sora-2`, `sora-2-2025-12-08`, `sora-2-2025-10-06`
    </ParamField>

    <ParamField body="detect_and_block_ip" type="boolean" default="false">
      If enabled, the prompt (and image for image-to-video) will be checked for known intellectual property references and the request will be blocked if any are detected.
    </ParamField>

    <ParamField body="character_ids" type="list<string>">
      Up to two character IDs (from create-character) to use in the video. Refer to characters by name in the prompt. When set, only the OpenAI provider is used.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The URL of the image to use as the first frame
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video
    </ParamField>

    <ParamField body="video_id" type="string" required>
      The ID of the generated video
    </ParamField>

    <ParamField body="thumbnail" type="ImageFile">
      Thumbnail image for the video
    </ParamField>

    <ParamField body="spritesheet" type="ImageFile">
      Spritesheet image for the video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Front-facing 'invisible' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: 'This is insanely fun! You've got to try it—book a tandem and go!' Natural wind roar, voice close-mic'd and slightly compressed so it's intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
      "resolution": "auto",
      "aspect_ratio": "auto",
      "duration": 4,
      "delete_video": true,
      "model": "sora-2",
      "detect_and_block_ip": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "url": "https://storage.googleapis.com/falserverless/example_outputs/sora_2_i2v_output.mp4"
      },
      "video_id": "video_123"
    }
    ```
  </Tab>

  <Tab title="Pro">
    **Endpoint:** `POST https://fal.run/fal-ai/sora-2/image-to-video/pro`
    **Endpoint ID:** `fal-ai/sora-2/image-to-video/pro`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/sora-2/image-to-video/pro/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/sora-2/image-to-video/pro",
          arguments={
              "prompt": "Front-facing 'invisible' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: 'This is insanely fun! You've got to try it—book a tandem and go!' Natural wind roar, voice close-mic'd and slightly compressed so it's intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/sora-2/image-to-video/pro", {
        input: {
            prompt: "Front-facing 'invisible' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: 'This is insanely fun! You've got to try it—book a tandem and go!' Natural wind roar, voice close-mic'd and slightly compressed so it's intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/sora-2/image-to-video/pro \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Front-facing '\''invisible'\'' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: '\''This is insanely fun! You'\''ve got to try it—book a tandem and go!'\'' Natural wind roar, voice close-mic'\''d and slightly compressed so it'\''s intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="auto">
      The resolution of the generated video Default value: `"auto"`

      Possible values: `auto`, `720p`, `1080p`, `true_1080p`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video Default value: `"auto"`

      Possible values: `auto`, `9:16`, `16:9`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="4">
      Duration of the generated video in seconds Default value: `"4"`

      Possible values: `4`, `8`, `12`, `16`, `20`
    </ParamField>

    <ParamField body="delete_video" type="boolean" default="true">
      Whether to delete the video after generation for privacy reasons. If True, the video cannot be used for remixing and will be permanently deleted. Default value: `true`
    </ParamField>

    <ParamField body="detect_and_block_ip" type="boolean" default="false">
      If enabled, the prompt (and image for image-to-video) will be checked for known intellectual property references and the request will be blocked if any are detected.
    </ParamField>

    <ParamField body="character_ids" type="list<string>">
      Up to two character IDs (from create-character) to use in the video. Refer to characters by name in the prompt. When set, only the OpenAI provider is used.
    </ParamField>

    <ParamField body="image_url" type="string" required>
      The URL of the image to use as the first frame
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video
    </ParamField>

    <ParamField body="video_id" type="string" required>
      The ID of the generated video
    </ParamField>

    <ParamField body="thumbnail" type="ImageFile">
      Thumbnail image for the video
    </ParamField>

    <ParamField body="spritesheet" type="ImageFile">
      Spritesheet image for the video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Front-facing 'invisible' action-cam on a skydiver in freefall above bright clouds; camera locked on his face. He speaks over the wind with clear lipsync: 'This is insanely fun! You've got to try it—book a tandem and go!' Natural wind roar, voice close-mic'd and slightly compressed so it's intelligible. Midday sun, goggles and jumpsuit flutter, altimeter visible, parachute rig on shoulders. Energetic but stable framing with subtle shake; brief horizon roll. End on first tug of canopy and wind noise dropping.",
      "resolution": "auto",
      "aspect_ratio": "auto",
      "duration": 4,
      "delete_video": true,
      "detect_and_block_ip": false,
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/sora-2-i2v-input.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "url": "https://storage.googleapis.com/falserverless/example_outputs/sora-2-pro-i2v-output.mp4"
      },
      "video_id": "video_123"
    }
    ```
  </Tab>
</Tabs>

## Related

* [Sora 2](/model-api-reference/video-generation-api/sora-2) — Video Generation

## Limitations

* `resolution` restricted to: `auto`, `720p`
* `aspect_ratio` restricted to: `auto`, `9:16`, `16:9`
* `duration` restricted to: `4`, `8`, `12`, `16`, `20`
* `model` restricted to: `sora-2`, `sora-2-2025-12-08`, `sora-2-2025-10-06`
* `resolution` restricted to: `auto`, `720p`, `1080p`, `true_1080p`


# https://fal.ai/docs/model-api-reference/video-generation-api/sora-2-text-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sora 2 Text To Video API

> API reference for Sora 2 Text To Video. Text-to-video endpoint for Sora 2, OpenAI's state-of-the-art video model capable of creating richly detailed, dynamic clips with audio from natural language or 

<Tabs>
  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/sora-2/text-to-video`
    **Endpoint ID:** `fal-ai/sora-2/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/sora-2/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/sora-2/text-to-video",
          arguments={
              "prompt": "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/sora-2/text-to-video", {
        input: {
            prompt: "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/sora-2/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="resolution" type="string" default="720p">
      The resolution of the generated video Default value: `"720p"`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `9:16`, `16:9`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="4">
      Duration of the generated video in seconds Default value: `"4"`

      Possible values: `4`, `8`, `12`, `16`, `20`
    </ParamField>

    <ParamField body="delete_video" type="boolean" default="true">
      Whether to delete the video after generation for privacy reasons. If True, the video cannot be used for remixing and will be permanently deleted. Default value: `true`
    </ParamField>

    <ParamField body="model" type="ModelEnum" default="sora-2">
      The model to use for the generation. When the default model is selected, the latest snapshot of the model will be used - otherwise, select a specific snapshot of the model. Default value: `"sora-2"`

      Possible values: `sora-2`, `sora-2-2025-12-08`, `sora-2-2025-10-06`
    </ParamField>

    <ParamField body="detect_and_block_ip" type="boolean" default="false">
      If enabled, the prompt (and image for image-to-video) will be checked for known intellectual property references and the request will be blocked if any are detected.
    </ParamField>

    <ParamField body="character_ids" type="list<string>">
      Up to two character IDs (from create-character) to use in the video. Refer to characters by name in the prompt. When set, only the OpenAI provider is used.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video
    </ParamField>

    <ParamField body="video_id" type="string" required>
      The ID of the generated video
    </ParamField>

    <ParamField body="thumbnail" type="ImageFile">
      Thumbnail image for the video
    </ParamField>

    <ParamField body="spritesheet" type="ImageFile">
      Spritesheet image for the video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music",
      "resolution": "720p",
      "aspect_ratio": "16:9",
      "duration": 4,
      "delete_video": true,
      "model": "sora-2",
      "detect_and_block_ip": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "url": "https://storage.googleapis.com/falserverless/example_outputs/sora_t2v_output.mp4"
      },
      "video_id": "video_123"
    }
    ```
  </Tab>

  <Tab title="Pro">
    **Endpoint:** `POST https://fal.run/fal-ai/sora-2/text-to-video/pro`
    **Endpoint ID:** `fal-ai/sora-2/text-to-video/pro`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/sora-2/text-to-video/pro/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/sora-2/text-to-video/pro",
          arguments={
              "prompt": "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/sora-2/text-to-video/pro", {
        input: {
            prompt: "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/sora-2/text-to-video/pro \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music"
      }'
      ```
    </CodeGroup>

    ## Examples

    > A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natur...

    <video src="https://v3b.fal.media/files/b/0a91c0be/Yy-egGFV8E2ujRLxmrLKj_5vtsOrfM.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="1080p">
      The resolution of the generated video Default value: `"1080p"`

      Possible values: `720p`, `1080p`, `true_1080p`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      The aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `9:16`, `16:9`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="4">
      Duration of the generated video in seconds Default value: `"4"`

      Possible values: `4`, `8`, `12`, `16`, `20`
    </ParamField>

    <ParamField body="delete_video" type="boolean" default="true">
      Whether to delete the video after generation for privacy reasons. If True, the video cannot be used for remixing and will be permanently deleted. Default value: `true`
    </ParamField>

    <ParamField body="detect_and_block_ip" type="boolean" default="false">
      If enabled, the prompt (and image for image-to-video) will be checked for known intellectual property references and the request will be blocked if any are detected.
    </ParamField>

    <ParamField body="character_ids" type="list<string>">
      Up to two character IDs (from create-character) to use in the video. Refer to characters by name in the prompt. When set, only the OpenAI provider is used.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video
    </ParamField>

    <ParamField body="video_id" type="string" required>
      The ID of the generated video
    </ParamField>

    <ParamField body="thumbnail" type="ImageFile">
      Thumbnail image for the video
    </ParamField>

    <ParamField body="spritesheet" type="ImageFile">
      Spritesheet image for the video
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A dramatic Hollywood breakup scene at dusk on a quiet suburban street. A man and a woman in their 30s face each other, speaking softly but emotionally, lips syncing to breakup dialogue. Cinematic lighting, warm sunset tones, shallow depth of field, gentle breeze moving autumn leaves, realistic natural sound, no background music",
      "resolution": "1080p",
      "aspect_ratio": "16:9",
      "duration": 4,
      "delete_video": true,
      "detect_and_block_ip": false
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "url": "https://storage.googleapis.com/falserverless/example_outputs/sora-2-pro-t2v-output.mp4"
      },
      "video_id": "video_123"
    }
    ```
  </Tab>
</Tabs>

OpenAI's Sora 2 Pro generates up to 25-second videos with synchronized audio at \$0.50 per second for 1080p output. With **unprecedented length and audio integration**, Sora 2 excels where most competing models cap at 10 seconds without sound. Built for filmmakers, content creators, and developers who need production-ready clips with natural dialogue and environmental audio.

**Use Cases:** Cinematic Scene Generation | Marketing Video Production | AI-Assisted Filmmaking

***

## Performance

At $0.50/second for 1080p (or $0.30/second for 720p), Sora 2 Pro is a premium text-to-video solution, trading cost efficiency for industry-leading output length and **native audio synthesis**.

| Metric                 | Result                                                                                                                                                       | Context                                                       |
| :--------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------ |
| **Maximum Duration**   | Up to 25 seconds                                                                                                                                             | 2.5x longer than most competing models (10s standard)         |
| **Resolution Options** | 720p, 1080p                                                                                                                                                  | Two quality tiers with tiered pricing                         |
| **Cost per Second**    | $0.30 (720p), $0.50 (1080p)                                                                                                                                  | Premium pricing for audio-enabled, extended-duration output   |
| **Aspect Ratios**      | 9:16, 16:9                                                                                                                                                   | Vertical and horizontal formats for social and cinematic use  |
| **Audio Synthesis**    | Native audio generation                                                                                                                                      | Synchronized dialogue, ambient sound, and environmental audio |
| **Related Endpoints**  | [Sora 2 Video to Video](https://fal.ai/models/fal-ai/sora-2/video-to-video/remix), [Sora 2 Text to Video](https://fal.ai/models/fal-ai/sora-2/text-to-video) | Pro vs Standard tiers and remix capabilities                  |

***

## Audio-First Video Generation

Sora 2 Pro breaks from traditional silent video generation by synthesizing audio alongside visual content. Dialogue lip-syncing, environmental sounds, and ambient audio emerge from the same text prompt that describes the scene.

**What this means for you:**

* **Synchronized dialogue generation:** Characters speak naturally with accurate lip-sync to match emotional tone and scene context, no separate audio track required

* **Environmental audio integration:** Ambient sounds (wind, traffic, footsteps) generate contextually based on visual elements described in your prompt

* **Extended temporal coherence:** 25-second maximum duration maintains visual and audio consistency across longer narrative arcs than standard 4-10 second models

* **Flexible duration control:** Generate 4, 8, or 12-second clips for rapid iteration, or push to 25 seconds for complete scene development

***

## Technical Specifications

| Spec                   | Details                                                  |
| :--------------------- | :------------------------------------------------------- |
| **Architecture**       | Sora 2 Pro                                               |
| **Input Formats**      | Text prompts (natural language descriptions)             |
| **Output Formats**     | MP4 video with audio, optional thumbnail and spritesheet |
| **Resolution Options** | 720p ($0.30/s), 1080p ($0.50/s)                          |
| **Duration Range**     | 4, 8, 12 seconds (standard), up to 25 seconds (extended) |
| **Aspect Ratios**      | 9:16 (vertical), 16:9 (horizontal)                       |
| **License**            | Commercial use via OpenAI API or fal credits             |

[API Documentation](https://fal.ai/models/fal-ai/sora-2/text-to-video/pro/api) | [Quickstart Guide](https://docs.fal.ai/model-apis/quickstart) | [Enterprise Pricing](https://fal.ai/pricing)

***

## How It Stacks Up

**[Sora 2 Text to Video (Standard)](https://fal.ai/models/fal-ai/sora-2/text-to-video)** – Sora 2 Pro trades cost efficiency for extended duration and audio synthesis at premium pricing. Standard Sora 2 remains ideal for **rapid prototyping** and shorter clips where audio isn't required.

**[Hunyuan Video V1.5 Text to Video](https://fal.ai/models/fal-ai/hunyuan-video-v1.5/text-to-video)** – Sora 2 Pro prioritizes audio integration and extended temporal coherence (up to 25s) for narrative-driven content. Hunyuan Video V1.5 emphasizes cost-effective generation for standard-length clips without audio requirements.

**[LongCat Video Text to Video](http://fal.ai/models/fal-ai/longcat-video/text-to-video/720p)** – Sora 2 Pro delivers native audio synthesis and dialogue lip-syncing for production-ready scenes. LongCat Video focuses on visual-only generation with competitive pricing for silent video workflows.

## Related

* [Sora 2](/model-api-reference/video-generation-api/sora-2) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `9:16`, `16:9`
* `duration` restricted to: `4`, `8`, `12`, `16`, `20`
* `model` restricted to: `sora-2`, `sora-2-2025-12-08`, `sora-2-2025-10-06`
* `resolution` restricted to: `720p`, `1080p`, `true_1080p`


# https://fal.ai/docs/model-api-reference/video-generation-api/sora-2-video-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sora 2 Video To Video API

> API reference for Sora 2 Video To Video. Video-to-video remix endpoint for Sora 2, OpenAI’s advanced model that transforms existing videos based on new text or image prompts allowing rich edits, style

**Endpoint:** `POST https://fal.run/fal-ai/sora-2/video-to-video/remix`
**Endpoint ID:** `fal-ai/sora-2/video-to-video/remix`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/sora-2/video-to-video/remix/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/sora-2/video-to-video/remix",
      arguments={
          "video_id": "video_123",
          "prompt": "Change the cat's fur color to purple."
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/sora-2/video-to-video/remix", {
    input: {
        video_id: "video_123",
        prompt: "Change the cat's fur color to purple."
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/sora-2/video-to-video/remix \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "video_id": "video_123",
    "prompt": "Change the cat'\''s fur color to purple."
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="video_id" type="string" required>
  The video\_id from a previous Sora 2 generation. Note: You can only remix videos that were generated by Sora (via text-to-video or image-to-video endpoints), not arbitrary uploaded videos.
</ParamField>

<ParamField body="prompt" type="string" required>
  Updated text prompt that directs the remix generation
</ParamField>

<ParamField body="delete_video" type="boolean" default="true">
  Whether to delete the video after generation for privacy reasons. If True, the video cannot be used for remixing and will be permanently deleted. Default value: `true`
</ParamField>

### Output Schema

<ParamField body="video" type="VideoFile" required>
  The generated video
</ParamField>

<ParamField body="video_id" type="string" required>
  The ID of the generated video
</ParamField>

<ParamField body="thumbnail" type="ImageFile">
  Thumbnail image for the video
</ParamField>

<ParamField body="spritesheet" type="ImageFile">
  Spritesheet image for the video
</ParamField>

### Input Example

```json theme={null}
{
  "video_id": "video_123",
  "prompt": "Change the cat's fur color to purple.",
  "delete_video": true
}
```

### Output Example

```json theme={null}
{
  "video": {
    "content_type": "video/mp4",
    "url": "https://v3b.fal.media/files/b/rabbit/nk1MK6LY90QqScvI4_Yn8.mp4"
  },
  "video_id": "video_123"
}
```

## Related

* [Sora 2](/model-api-reference/video-generation-api/sora-2) — Video Generation


# https://fal.ai/docs/model-api-reference/video-generation-api/topaz-upscale.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Topaz Upscale API

> API reference for Topaz Upscale. Professional-grade video upscaling using Topaz technology. Enhance your videos with high-quality upscaling.

**Endpoint:** `POST https://fal.run/fal-ai/topaz/upscale/video`
**Endpoint ID:** `fal-ai/topaz/upscale/video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/topaz/upscale/video/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/topaz/upscale/video",
      arguments={
          "video_url": "https://v3.fal.media/files/kangaroo/y5-1YTGpun17eSeggZMzX_video-1733468228.mp4"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/topaz/upscale/video", {
    input: {
        video_url: "https://v3.fal.media/files/kangaroo/y5-1YTGpun17eSeggZMzX_video-1733468228.mp4"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/topaz/upscale/video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "video_url": "https://v3.fal.media/files/kangaroo/y5-1YTGpun17eSeggZMzX_video-1733468228.mp4"
  }'
  ```
</CodeGroup>

## Examples

<video src="https://v3b.fal.media/files/b/0a9599a1/0xGqHNlfD6WlZqtpEx4Mu_video.mp4" controls width="100%" />

### Input Schema

<ParamField body="video_url" type="string" required>
  URL of the video to upscale
</ParamField>

<ParamField body="model" type="ModelEnum" default="Proteus">
  Video enhancement model. Proteus is best for most videos, Artemis for denoise+sharpen, Nyx for dedicated denoising, Gaia HQ/CG for rendered content, Gaia 2 for animation and motion graphics at 2x, and Starlight for generative diffusion-based upscaling and enhancement. Default value: `"Proteus"`

  Possible values: `Proteus`, `Artemis HQ`, `Artemis MQ`, `Artemis LQ`, `Nyx`, `Nyx Fast`, `Nyx XL`, `Nyx HF`, `Gaia HQ`, `Gaia CG`, `Gaia 2`, `Starlight Precise 1`, `Starlight Precise 2`, `Starlight Precise 2.5`, `Starlight HQ`, `Starlight Mini`, `Starlight Sharp`, `Starlight Fast 1`, `Starlight Fast 2`
</ParamField>

<ParamField body="upscale_factor" type="float" default="2">
  Factor to upscale the video by (e.g. 2.0 doubles width and height) Default value: `2`

  Range: `1` to `4`
</ParamField>

<ParamField body="target_fps" type="integer">
  Target FPS for frame interpolation. If set, frame interpolation will be enabled.

  Range: `16` to `60`
</ParamField>

<ParamField body="compression" type="float">
  Compression artifact removal level (0.0-1.0). Default varies by model.

  Range: `0` to `1`
</ParamField>

<ParamField body="noise" type="float">
  Noise reduction level (0.0-1.0). Default varies by model.

  Range: `0` to `1`
</ParamField>

<ParamField body="halo" type="float">
  Halo reduction level (0.0-1.0). Default varies by model.

  Range: `0` to `1`
</ParamField>

<ParamField body="grain" type="float">
  Film grain amount (0.0-1.0). Default varies by model.

  Range: `0` to `1`
</ParamField>

<ParamField body="recover_detail" type="float">
  Recover original detail level (0.0-1.0). Higher values preserve more original detail.

  Range: `0` to `1`
</ParamField>

<ParamField body="H264_output" type="boolean" default="false">
  Whether to use H264 codec for output video. Default is H265.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The upscaled video file
</ParamField>

### Input Example

```json theme={null}
{
  "video_url": "https://v3.fal.media/files/kangaroo/y5-1YTGpun17eSeggZMzX_video-1733468228.mp4",
  "model": "Proteus",
  "upscale_factor": 2,
  "H264_output": false
}
```

### Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3.fal.media/files/penguin/ztj_LB4gQlW6HIfVs8zX4_upscaled.mp4"
  }
}
```

## Limitations

* `upscale_factor` range: 1 to 4
* `target_fps` range: 16 to 60
* `compression` range: 0 to 1
* `noise` range: 0 to 1
* `halo` range: 0 to 1
* `grain` range: 0 to 1
* `recover_detail` range: 0 to 1


# https://fal.ai/docs/model-api-reference/video-generation-api/veo3.1.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Veo3.1 API

> API reference for Veo3.1. Veo 3.1 by Google, the most advanced AI video generation model in the world. With sound on!

**Endpoint:** `POST https://fal.run/fal-ai/veo3.1`
**Endpoint ID:** `fal-ai/veo3.1`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/veo3.1",
      arguments={
          "prompt": "Two person street interview in New York City.
  Sample Dialogue:
  Host: \"Did you hear the news?\"
  Person: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\""
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/veo3.1", {
    input: {
        prompt: "Two person street interview in New York City.
  Sample Dialogue:
  Host: \"Did you hear the news?\"
  Person: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\""
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/veo3.1 \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Two person street interview in New York City.\nSample Dialogue:\nHost: \"Did you hear the news?\"\nPerson: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\""
  }'
  ```
</CodeGroup>

## Examples

> First-person view soaring low over a medieval battlefield at dawn, gliding past clashing knights in armor, fire-lit arrows whizzing overhead, splintered catapults burning near fallen soldiers, flying inches above torn flags and mud-soaked ground, ambient sounds of swords striking, war cries, gallopi...

<video src="https://v3.fal.media/files/penguin/D-wlVxx1E8BPr2AG9cxhb_output.mp4" controls width="100%" />

> A colossal, ancient library with impossibly high shelves, where books fly and pages turn on their own. Audio: the rustle of thousands of pages turning, the soft whoosh of flying books, distant, echoing whispers, a grand, magical orchestral piece with swirling harps and enchanted woodwinds.

<video src="https://v3.fal.media/files/zebra/bW6Jj6jeerM5Y4jwo49tN_output.mp4" controls width="100%" />

> A luxury yatch sets sail in the Bosphorus Strait. As it gracefully navigates through the current, the Maiden's Tower comes into view. While continuing its journey, seagulls greet it. The sounds of waves and seagulls can be heard.

<video src="https://v3.fal.media/files/penguin/ZOkKJXXKEDJ9fsNAeMNkE_output.mp4" controls width="100%" />

## Related

* [Veo 3.1 Fast](/model-api-reference/video-generation-api/veo-3.1-fast) — Video Generation
* [Veo 3.1](/model-api-reference/video-generation-api/veo-3.1) — Video Generation
* [Veo3.1 Lite Image to Video](/model-api-reference/video-generation-api/veo3.1-lite-image-to-video) — Video Generation
* [Veo3.1 Lite FLF](/model-api-reference/video-generation-api/veo3.1-lite-flf) — Video Generation
* [Veo3.1 Lite Text to Video](/model-api-reference/video-generation-api/veo3.1-lite-text-to-video) — Video Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Duration control
* Negative prompts
* Reproducible generation (seed)

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt describing the video you want to generate
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  Aspect ratio of the generated video Default value: `"16:9"`

  Possible values: `16:9`, `9:16`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="8s">
  The duration of the generated video. Default value: `"8s"`

  Possible values: `4s`, `6s`, `8s`
</ParamField>

<ParamField body="negative_prompt" type="string">
  A negative prompt to guide the video generation.
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="720p">
  The resolution of the generated video. Default value: `"720p"`

  Possible values: `720p`, `1080p`, `4k`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate audio for the video. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  The seed for the random number generator.
</ParamField>

<ParamField body="auto_fix" type="boolean" default="true">
  Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them. Default value: `true`
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
  The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Two person street interview in New York City.\nSample Dialogue:\nHost: \"Did you hear the news?\"\nPerson: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\"",
  "aspect_ratio": "16:9",
  "duration": "8s",
  "resolution": "720p",
  "generate_audio": true,
  "auto_fix": true,
  "safety_tolerance": "4"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3b.fal.media/files/b/kangaroo/oUCiZjQwEy6bIQdPUSLDF_output.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`
* `duration` restricted to: `4s`, `6s`, `8s`
* `resolution` restricted to: `720p`, `1080p`, `4k`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/video-generation-api/veo3.1-extend-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Veo3.1 Extend Video API

> API reference for Veo3.1 Extend Video. Extend Veo-Created Videos up to 30 seconds

**Endpoint:** `POST https://fal.run/fal-ai/veo3.1/extend-video`
**Endpoint ID:** `fal-ai/veo3.1/extend-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/extend-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/veo3.1/extend-video",
      arguments={
          "prompt": "Continue the scene naturally, maintaining the same style and motion.",
          "video_url": "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/veo3.1/extend-video", {
    input: {
        prompt: "Continue the scene naturally, maintaining the same style and motion.",
        video_url: "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/veo3.1/extend-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "Continue the scene naturally, maintaining the same style and motion.",
    "video_url": "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
  }'
  ```
</CodeGroup>

## Related

* [Veo 3.1](/model-api-reference/video-generation-api/veo-3.1) — Video Generation
* [Veo 3.1 Fast](/model-api-reference/video-generation-api/veo-3.1-fast) — Video Generation
* [Veo3.1 Lite Image to Video](/model-api-reference/video-generation-api/veo3.1-lite-image-to-video) — Video Generation
* [Veo3.1 Lite FLF](/model-api-reference/video-generation-api/veo3.1-lite-flf) — Video Generation
* [Veo3.1 Lite Text to Video](/model-api-reference/video-generation-api/veo3.1-lite-text-to-video) — Video Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Duration control
* Negative prompts
* Reproducible generation (seed)
* Video input

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt describing how the video should be extended
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
  The aspect ratio of the generated video. Default value: `"auto"`

  Possible values: `auto`, `16:9`, `9:16`
</ParamField>

<ParamField body="duration" type="string" default="7s">
  The duration of the generated video. Default value: `"7s"`
</ParamField>

<ParamField body="negative_prompt" type="string">
  A negative prompt to guide the video generation.
</ParamField>

<ParamField body="resolution" type="string" default="720p">
  The resolution of the generated video. Default value: `"720p"`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate audio for the video. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  The seed for the random number generator.
</ParamField>

<ParamField body="auto_fix" type="boolean" default="false">
  Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
  The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="video_url" type="string" required>
  URL of the video to extend. The video should be 720p or 1080p resolution in 16:9 or 9:16 aspect ratio.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The extended video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "Continue the scene naturally, maintaining the same style and motion.",
  "aspect_ratio": "auto",
  "duration": "7s",
  "resolution": "720p",
  "generate_audio": true,
  "auto_fix": false,
  "safety_tolerance": "4",
  "video_url": "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://v3b.fal.media/files/b/0a86711b/B_Z96VS4X9Dfd4M5ArB4H_c666e63f729f4a8fa1145c6727cef97d.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/video-generation-api/veo3.1-fast.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Veo3.1 Fast API

> API reference for Veo3.1 Fast. Faster and more cost effective version of Google's Veo 3.1!

<Tabs>
  <Tab title="Fast">
    **Endpoint:** `POST https://fal.run/fal-ai/veo3.1/fast`
    **Endpoint ID:** `fal-ai/veo3.1/fast`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/fast/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/veo3.1/fast",
          arguments={
              "prompt": "Two person street interview in New York City.
      Sample Dialogue:
      Host: \"Did you hear the news?\"
      Person: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\""
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/veo3.1/fast", {
        input: {
            prompt: "Two person street interview in New York City.
      Sample Dialogue:
      Host: \"Did you hear the news?\"
      Person: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\""
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/veo3.1/fast \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Two person street interview in New York City.\nSample Dialogue:\nHost: \"Did you hear the news?\"\nPerson: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\""
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      Aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `16:9`, `9:16`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="8s">
      The duration of the generated video. Default value: `"8s"`

      Possible values: `4s`, `6s`, `8s`
    </ParamField>

    <ParamField body="negative_prompt" type="string">
      A negative prompt to guide the video generation.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      The resolution of the generated video. Default value: `"720p"`

      Possible values: `720p`, `1080p`, `4k`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="auto_fix" type="boolean" default="true">
      Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them. Default value: `true`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Two person street interview in New York City.\nSample Dialogue:\nHost: \"Did you hear the news?\"\nPerson: \"Yes! Veo 3.1 is now available on fal. If you want to see it, go check their website.\"",
      "aspect_ratio": "16:9",
      "duration": "8s",
      "resolution": "720p",
      "generate_audio": true,
      "auto_fix": true,
      "safety_tolerance": "4"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3b.fal.media/files/b/kangaroo/oUCiZjQwEy6bIQdPUSLDF_output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/veo3.1/fast/image-to-video`
    **Endpoint ID:** `fal-ai/veo3.1/fast/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/fast/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/veo3.1/fast/image-to-video",
          arguments={
              "prompt": "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.
      Sample Dialogue:
      Monkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"
      Polar Bear (Ice): \"And I'm Ice!\"",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/veo3.1/fast/image-to-video", {
        input: {
            prompt: "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.
      Sample Dialogue:
      Monkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"
      Polar Bear (Ice): \"And I'm Ice!\"",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/veo3.1/fast/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.\nSample Dialogue:\nMonkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"\nPolar Bear (Ice): \"And I'\''m Ice!\"",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Only 16:9 and 9:16 are supported. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="8s">
      The duration of the generated video. Default value: `"8s"`

      Possible values: `4s`, `6s`, `8s`
    </ParamField>

    <ParamField body="negative_prompt" type="string">
      A negative prompt to guide the video generation.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      The resolution of the generated video. Default value: `"720p"`

      Possible values: `720p`, `1080p`, `4k`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="auto_fix" type="boolean" default="false">
      Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of the input image to animate. Should be 720p or higher resolution in 16:9 or 9:16 aspect ratio. If the image is not in 16:9 or 9:16 aspect ratio, it will be cropped to fit.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.\nSample Dialogue:\nMonkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"\nPolar Bear (Ice): \"And I'm Ice!\"",
      "aspect_ratio": "auto",
      "duration": "8s",
      "resolution": "720p",
      "generate_audio": true,
      "auto_fix": false,
      "safety_tolerance": "4",
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/model_tests/gallery/veo3-1-i2v.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="First Last Frame To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/veo3.1/fast/first-last-frame-to-video`
    **Endpoint ID:** `fal-ai/veo3.1/fast/first-last-frame-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/fast/first-last-frame-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/veo3.1/fast/first-last-frame-to-video",
          arguments={
              "prompt": "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It's incredible!\"",
              "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
              "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/veo3.1/fast/first-last-frame-to-video", {
        input: {
            prompt: "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It's incredible!\"",
            first_frame_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
            last_frame_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/veo3.1/fast/first-last-frame-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It'\''s incredible!\"",
        "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
        "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="8s">
      The duration of the generated video. Default value: `"8s"`

      Possible values: `4s`, `6s`, `8s`
    </ParamField>

    <ParamField body="negative_prompt" type="string">
      A negative prompt to guide the video generation.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      The resolution of the generated video. Default value: `"720p"`

      Possible values: `720p`, `1080p`, `4k`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="auto_fix" type="boolean" default="false">
      Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="first_frame_url" type="string" required>
      URL of the first frame of the video
    </ParamField>

    <ParamField body="last_frame_url" type="string" required>
      URL of the last frame of the video
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It's incredible!\"",
      "aspect_ratio": "auto",
      "duration": "8s",
      "resolution": "720p",
      "generate_audio": true,
      "auto_fix": false,
      "safety_tolerance": "4",
      "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
      "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://storage.googleapis.com/falserverless/example_outputs/veo31-flf2v-output.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Extend Video">
    **Endpoint:** `POST https://fal.run/fal-ai/veo3.1/fast/extend-video`
    **Endpoint ID:** `fal-ai/veo3.1/fast/extend-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/fast/extend-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/veo3.1/fast/extend-video",
          arguments={
              "prompt": "Continue the scene naturally, maintaining the same style and motion.",
              "video_url": "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/veo3.1/fast/extend-video", {
        input: {
            prompt: "Continue the scene naturally, maintaining the same style and motion.",
            video_url: "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/veo3.1/fast/extend-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Continue the scene naturally, maintaining the same style and motion.",
        "video_url": "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing how the video should be extended
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`
    </ParamField>

    <ParamField body="duration" type="string" default="7s">
      The duration of the generated video. Default value: `"7s"`
    </ParamField>

    <ParamField body="negative_prompt" type="string">
      A negative prompt to guide the video generation.
    </ParamField>

    <ParamField body="resolution" type="string" default="720p">
      The resolution of the generated video. Default value: `"720p"`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="auto_fix" type="boolean" default="false">
      Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="video_url" type="string" required>
      URL of the video to extend. The video should be 720p or 1080p resolution in 16:9 or 9:16 aspect ratio.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The extended video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Continue the scene naturally, maintaining the same style and motion.",
      "aspect_ratio": "auto",
      "duration": "7s",
      "resolution": "720p",
      "generate_audio": true,
      "auto_fix": false,
      "safety_tolerance": "4",
      "video_url": "https://v3b.fal.media/files/b/0a8670fe/pY8UGl4_C452wOm9XUBYO_9ae04df8771c4f3f979fa5cabeca6ada.mp4"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3b.fal.media/files/b/0a86711b/B_Z96VS4X9Dfd4M5ArB4H_c666e63f729f4a8fa1145c6727cef97d.mp4"
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Veo 3.1](/model-api-reference/video-generation-api/veo-3.1) — Video Generation
* [Veo 3.1 Fast](/model-api-reference/video-generation-api/veo-3.1-fast) — Video Generation
* [Veo3.1 Lite Image to Video](/model-api-reference/video-generation-api/veo3.1-lite-image-to-video) — Video Generation
* [Veo3.1 Lite FLF](/model-api-reference/video-generation-api/veo3.1-lite-flf) — Video Generation
* [Veo3.1 Lite Text to Video](/model-api-reference/video-generation-api/veo3.1-lite-text-to-video) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`
* `duration` restricted to: `4s`, `6s`, `8s`
* `resolution` restricted to: `720p`, `1080p`, `4k`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`


# https://fal.ai/docs/model-api-reference/video-generation-api/veo3.1-first-last-frame-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Veo3.1 First Last Frame To Video API

> API reference for Veo3.1 First Last Frame To Video. Generate videos from a first and last framed using Google's Veo 3.1

**Endpoint:** `POST https://fal.run/fal-ai/veo3.1/first-last-frame-to-video`
**Endpoint ID:** `fal-ai/veo3.1/first-last-frame-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/first-last-frame-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/veo3.1/first-last-frame-to-video",
      arguments={
          "prompt": "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It's incredible!\"",
          "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
          "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/veo3.1/first-last-frame-to-video", {
    input: {
        prompt: "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It's incredible!\"",
        first_frame_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
        last_frame_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/veo3.1/first-last-frame-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It'\''s incredible!\"",
    "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
    "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
  }'
  ```
</CodeGroup>

## Related

* [Veo 3.1](/model-api-reference/video-generation-api/veo-3.1) — Video Generation
* [Veo 3.1 Fast](/model-api-reference/video-generation-api/veo-3.1-fast) — Video Generation
* [Veo3.1 Lite Image to Video](/model-api-reference/video-generation-api/veo3.1-lite-image-to-video) — Video Generation
* [Veo3.1 Lite FLF](/model-api-reference/video-generation-api/veo3.1-lite-flf) — Video Generation
* [Veo3.1 Lite Text to Video](/model-api-reference/video-generation-api/veo3.1-lite-text-to-video) — Video Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Duration control
* Negative prompts
* Reproducible generation (seed)

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt describing the video you want to generate
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
  The aspect ratio of the generated video. Default value: `"auto"`

  Possible values: `auto`, `16:9`, `9:16`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="8s">
  The duration of the generated video. Default value: `"8s"`

  Possible values: `4s`, `6s`, `8s`
</ParamField>

<ParamField body="negative_prompt" type="string">
  A negative prompt to guide the video generation.
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="720p">
  The resolution of the generated video. Default value: `"720p"`

  Possible values: `720p`, `1080p`, `4k`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate audio for the video. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  The seed for the random number generator.
</ParamField>

<ParamField body="auto_fix" type="boolean" default="false">
  Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
  The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="first_frame_url" type="string" required>
  URL of the first frame of the video
</ParamField>

<ParamField body="last_frame_url" type="string" required>
  URL of the last frame of the video
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A woman looks into the camera, breathes in, then exclaims energetically, \"have you guys checked out Veo3.1 First-Last-Frame-to-Video on Fal? It's incredible!\"",
  "aspect_ratio": "auto",
  "duration": "8s",
  "resolution": "720p",
  "generate_audio": true,
  "auto_fix": false,
  "safety_tolerance": "4",
  "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
  "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_outputs/veo31-flf2v-output.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`
* `duration` restricted to: `4s`, `6s`, `8s`
* `resolution` restricted to: `720p`, `1080p`, `4k`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/video-generation-api/veo3.1-image-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Veo3.1 Image To Video API

> API reference for Veo3.1 Image To Video. Veo 3.1 is the latest state-of-the art video generation model from Google DeepMind

**Endpoint:** `POST https://fal.run/fal-ai/veo3.1/image-to-video`
**Endpoint ID:** `fal-ai/veo3.1/image-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/image-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/veo3.1/image-to-video",
      arguments={
          "prompt": "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.
  Sample Dialogue:
  Monkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"
  Polar Bear (Ice): \"And I'm Ice!\"",
          "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/veo3.1/image-to-video", {
    input: {
        prompt: "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.
  Sample Dialogue:
  Monkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"
  Polar Bear (Ice): \"And I'm Ice!\"",
        image_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/veo3.1/image-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.\nSample Dialogue:\nMonkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"\nPolar Bear (Ice): \"And I'\''m Ice!\"",
    "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
  }'
  ```
</CodeGroup>

## Related

* [Veo 3.1](/model-api-reference/video-generation-api/veo-3.1) — Video Generation
* [Veo 3.1 Fast](/model-api-reference/video-generation-api/veo-3.1-fast) — Video Generation
* [Veo3.1 Lite Image to Video](/model-api-reference/video-generation-api/veo3.1-lite-image-to-video) — Video Generation
* [Veo3.1 Lite FLF](/model-api-reference/video-generation-api/veo3.1-lite-flf) — Video Generation
* [Veo3.1 Lite Text to Video](/model-api-reference/video-generation-api/veo3.1-lite-text-to-video) — Video Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Duration control
* Negative prompts
* Reproducible generation (seed)
* Image input

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt describing the video you want to generate
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
  The aspect ratio of the generated video. Only 16:9 and 9:16 are supported. Default value: `"auto"`

  Possible values: `auto`, `16:9`, `9:16`
</ParamField>

<ParamField body="duration" type="DurationEnum" default="8s">
  The duration of the generated video. Default value: `"8s"`

  Possible values: `4s`, `6s`, `8s`
</ParamField>

<ParamField body="negative_prompt" type="string">
  A negative prompt to guide the video generation.
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="720p">
  The resolution of the generated video. Default value: `"720p"`

  Possible values: `720p`, `1080p`, `4k`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate audio for the video. Default value: `true`
</ParamField>

<ParamField body="seed" type="integer">
  The seed for the random number generator.
</ParamField>

<ParamField body="auto_fix" type="boolean" default="false">
  Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
  The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="image_url" type="string" required>
  URL of the input image to animate. Should be 720p or higher resolution in 16:9 or 9:16 aspect ratio. If the image is not in 16:9 or 9:16 aspect ratio, it will be cropped to fit.
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A monkey and polar bear host a casual podcast about AI inference, bringing their unique perspectives from different environments (tropical vs. arctic) to discuss how AI systems make decisions and process information.\nSample Dialogue:\nMonkey (Banana): \"Welcome back to Bananas & Ice! I am Banana\"\nPolar Bear (Ice): \"And I'm Ice!\"",
  "aspect_ratio": "auto",
  "duration": "8s",
  "resolution": "720p",
  "generate_audio": true,
  "auto_fix": false,
  "safety_tolerance": "4",
  "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31_i2v_input.jpg"
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/model_tests/gallery/veo3-1-i2v.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`
* `duration` restricted to: `4s`, `6s`, `8s`
* `resolution` restricted to: `720p`, `1080p`, `4k`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/video-generation-api/veo3.1-lite.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Veo3.1 Lite API

> API reference for Veo3.1 Lite. Veo 3.1 Lite balances practical utility with professional capabilities, supporting Text-to-Video and Image-to-Video

<Tabs>
  <Tab title="Lite">
    **Endpoint:** `POST https://fal.run/fal-ai/veo3.1/lite`
    **Endpoint ID:** `fal-ai/veo3.1/lite`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/lite/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/veo3.1/lite",
          arguments={
              "prompt": "A massive blue whale glides through crystal-clear deep ocean water, sunlight rays piercing through the surface above, bioluminescent plankton scattered around, cinematic slow motion"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/veo3.1/lite", {
        input: {
            prompt: "A massive blue whale glides through crystal-clear deep ocean water, sunlight rays piercing through the surface above, bioluminescent plankton scattered around, cinematic slow motion"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/veo3.1/lite \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A massive blue whale glides through crystal-clear deep ocean water, sunlight rays piercing through the surface above, bioluminescent plankton scattered around, cinematic slow motion"
      }'
      ```
    </CodeGroup>

    ## Examples

    > A ballerina performing an elegant pirouette on a moonlit outdoor stage. She wears a flowing white tutu that catches the silver light. Rose petals swirl around her in slow motion. The background is a dark forest with fireflies. Camera orbits slowly around her as she spins. Ethereal, dreamlike, cinema...

    <video src="https://v3b.fal.media/files/b/0a946855/rR-4fWeyUoQgo8g32Y1gy_8263e382d6734cfcb6f9b7160f127065.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      Aspect ratio of the generated video Default value: `"16:9"`

      Possible values: `16:9`, `9:16`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="8s">
      The duration of the generated video. Default value: `"8s"`

      Possible values: `4s`, `6s`, `8s`
    </ParamField>

    <ParamField body="negative_prompt" type="string">
      A negative prompt to guide the video generation.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      The resolution of the generated video. Default value: `"720p"`

      Possible values: `720p`, `1080p`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="auto_fix" type="boolean" default="true">
      Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them. Default value: `true`
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A massive blue whale glides through crystal-clear deep ocean water, sunlight rays piercing through the surface above, bioluminescent plankton scattered around, cinematic slow motion",
      "aspect_ratio": "16:9",
      "duration": "8s",
      "resolution": "720p",
      "generate_audio": true,
      "auto_fix": true,
      "safety_tolerance": "4"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "https://v3b.fal.media/files/b/0a94683f/r4vLtNmFDi_qpglfEX_q9_0a7258527ac84509a0997639765f5c79.mp4"
      }
    }
    ```
  </Tab>

  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/veo3.1/lite/image-to-video`
    **Endpoint ID:** `fal-ai/veo3.1/lite/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/lite/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/veo3.1/lite/image-to-video",
          arguments={
              "prompt": "The subject turns to face the camera and smiles warmly.",
              "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo3-i2v-input.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/veo3.1/lite/image-to-video", {
        input: {
            prompt: "The subject turns to face the camera and smiles warmly.",
            image_url: "https://storage.googleapis.com/falserverless/example_inputs/veo3-i2v-input.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/veo3.1/lite/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "The subject turns to face the camera and smiles warmly.",
        "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo3-i2v-input.png"
      }'
      ```
    </CodeGroup>

    ## Examples

    > Time-lapse of the city transitioning through the day. Shadows shift across buildings, traffic flows in streaks of light, clouds race across the sky. The scene shifts from bright midday to warm golden hour. Smooth hyperlapse feel.

    <video src="https://v3b.fal.media/files/b/0a94686f/UtJVZJIY6D9NwIaB3TVwu_738e51572750421fbb5fc3b78029988a.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing how the image should be animated
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`
    </ParamField>

    <ParamField body="duration" type="DurationEnum" default="8s">
      The duration of the generated video. Default value: `"8s"`

      Possible values: `4s`, `6s`, `8s`
    </ParamField>

    <ParamField body="negative_prompt" type="string">
      A negative prompt to guide the video generation.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      The resolution of the generated video. Default value: `"720p"`

      Possible values: `720p`, `1080p`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="auto_fix" type="boolean" default="false">
      Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of the input image to animate. Should be 720p or higher resolution in 16:9 or 9:16 aspect ratio.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "The subject turns to face the camera and smiles warmly.",
      "aspect_ratio": "auto",
      "duration": "8s",
      "resolution": "720p",
      "generate_audio": true,
      "auto_fix": false,
      "safety_tolerance": "4",
      "image_url": "https://storage.googleapis.com/falserverless/example_inputs/veo3-i2v-input.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019
      }
    }
    ```
  </Tab>

  <Tab title="First Last Frame To Video">
    **Endpoint:** `POST https://fal.run/fal-ai/veo3.1/lite/first-last-frame-to-video`
    **Endpoint ID:** `fal-ai/veo3.1/lite/first-last-frame-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/lite/first-last-frame-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/veo3.1/lite/first-last-frame-to-video",
          arguments={
              "prompt": "A smooth transition between the two frames with natural motion.",
              "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
              "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/veo3.1/lite/first-last-frame-to-video", {
        input: {
            prompt: "A smooth transition between the two frames with natural motion.",
            first_frame_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
            last_frame_url: "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/veo3.1/lite/first-last-frame-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A smooth transition between the two frames with natural motion.",
        "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
        "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
      }'
      ```
    </CodeGroup>

    ## Examples

    > The sun arcs across the sky from sunrise to sunset. Light transitions from cool dawn blue through warm golden midday to deep amber sunset. Shadows rotate and lengthen. Clouds drift and change shape. Smooth time-lapse feel.

    <video src="https://v3b.fal.media/files/b/0a946880/sfDxO-znDhQthS00Pa2Ns_d99979ba04614c3d963ebaa342627b3c.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      The text prompt describing the video you want to generate
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="auto">
      The aspect ratio of the generated video. Default value: `"auto"`

      Possible values: `auto`, `16:9`, `9:16`
    </ParamField>

    <ParamField body="duration" type="string" default="8s">
      The duration of the generated video. Default value: `"8s"`
    </ParamField>

    <ParamField body="negative_prompt" type="string">
      A negative prompt to guide the video generation.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      The resolution of the generated video. Default value: `"720p"`

      Possible values: `720p`, `1080p`
    </ParamField>

    <ParamField body="generate_audio" type="boolean" default="true">
      Whether to generate audio for the video. Default value: `true`
    </ParamField>

    <ParamField body="seed" type="integer">
      The seed for the random number generator.
    </ParamField>

    <ParamField body="auto_fix" type="boolean" default="false">
      Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
    </ParamField>

    <ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
      The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

      Possible values: `1`, `2`, `3`, `4`, `5`, `6`
    </ParamField>

    <ParamField body="first_frame_url" type="string" required>
      URL of the first frame of the video
    </ParamField>

    <ParamField body="last_frame_url" type="string" required>
      URL of the last frame of the video
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="File" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A smooth transition between the two frames with natural motion.",
      "aspect_ratio": "auto",
      "duration": "8s",
      "resolution": "720p",
      "generate_audio": true,
      "auto_fix": false,
      "safety_tolerance": "4",
      "first_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-1.jpeg",
      "last_frame_url": "https://storage.googleapis.com/falserverless/example_inputs/veo31-flf2v-input-2.jpeg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "url": "",
        "content_type": "image/png",
        "file_name": "z9RV14K95DvU.png",
        "file_size": 4404019
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Veo 3.1](/model-api-reference/video-generation-api/veo-3.1) — Video Generation
* [Veo 3.1 Fast](/model-api-reference/video-generation-api/veo-3.1-fast) — Video Generation
* [Veo3.1 Lite Image to Video](/model-api-reference/video-generation-api/veo3.1-lite-image-to-video) — Video Generation
* [Veo3.1 Lite FLF](/model-api-reference/video-generation-api/veo3.1-lite-flf) — Video Generation
* [Veo3.1 Lite Text to Video](/model-api-reference/video-generation-api/veo3.1-lite-text-to-video) — Video Generation

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`
* `duration` restricted to: `4s`, `6s`, `8s`
* `resolution` restricted to: `720p`, `1080p`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`
* `aspect_ratio` restricted to: `auto`, `16:9`, `9:16`


# https://fal.ai/docs/model-api-reference/video-generation-api/veo3.1-reference-to-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Veo3.1 Reference To Video API

> API reference for Veo3.1 Reference To Video. Generate Videos from images using Google's Veo 3.1

**Endpoint:** `POST https://fal.run/fal-ai/veo3.1/reference-to-video`
**Endpoint ID:** `fal-ai/veo3.1/reference-to-video`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/veo3.1/reference-to-video/playground">
  Run this model interactively with your own prompts.
</Card>

## Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/veo3.1/reference-to-video",
      arguments={
          "prompt": "A chimpanzee wearing overalls frolics in the grassy field, gently playing with the butterflies. In the background, a circus tent and carousel beckon.",
          "image_urls": [
              "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-1.png",
              "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-2.png",
              "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-3.png"
          ]
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/veo3.1/reference-to-video", {
    input: {
        prompt: "A chimpanzee wearing overalls frolics in the grassy field, gently playing with the butterflies. In the background, a circus tent and carousel beckon.",
        image_urls: [
          "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-1.png",
          "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-2.png",
          "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-3.png"
        ]
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/veo3.1/reference-to-video \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "prompt": "A chimpanzee wearing overalls frolics in the grassy field, gently playing with the butterflies. In the background, a circus tent and carousel beckon.",
    "image_urls": [
      "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-1.png",
      "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-2.png",
      "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-3.png"
    ]
  }'
  ```
</CodeGroup>

## Related

* [Veo 3.1](/model-api-reference/video-generation-api/veo-3.1) — Video Generation
* [Veo 3.1 Fast](/model-api-reference/video-generation-api/veo-3.1-fast) — Video Generation
* [Veo3.1 Lite Image to Video](/model-api-reference/video-generation-api/veo3.1-lite-image-to-video) — Video Generation
* [Veo3.1 Lite FLF](/model-api-reference/video-generation-api/veo3.1-lite-flf) — Video Generation
* [Veo3.1 Lite Text to Video](/model-api-reference/video-generation-api/veo3.1-lite-text-to-video) — Video Generation

## Capabilities

* Text prompt input
* Aspect ratio control
* Duration control

## API Reference

### Input Schema

<ParamField body="prompt" type="string" required>
  The text prompt describing the video you want to generate
</ParamField>

<ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
  The aspect ratio of the generated video. Default value: `"16:9"`

  Possible values: `16:9`, `9:16`
</ParamField>

<ParamField body="duration" type="string" default="8s">
  The duration of the generated video. Default value: `"8s"`
</ParamField>

<ParamField body="resolution" type="ResolutionEnum" default="720p">
  The resolution of the generated video. Default value: `"720p"`

  Possible values: `720p`, `1080p`, `4k`
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Whether to generate audio for the video. Default value: `true`
</ParamField>

<ParamField body="auto_fix" type="boolean" default="false">
  Whether to automatically attempt to fix prompts that fail content policy or other validation checks by rewriting them.
</ParamField>

<ParamField body="safety_tolerance" type="SafetyToleranceEnum" default="4">
  The safety tolerance level for content moderation. 1 is the most strict (blocks most content), 6 is the least strict. Default value: `"4"`

  Possible values: `1`, `2`, `3`, `4`, `5`, `6`
</ParamField>

<ParamField body="image_urls" type="list<string>" required>
  URLs of the reference images to use for consistent subject appearance
</ParamField>

### Output Schema

<ParamField body="video" type="File" required>
  The generated video.
</ParamField>

## Input Example

```json theme={null}
{
  "prompt": "A chimpanzee wearing overalls frolics in the grassy field, gently playing with the butterflies. In the background, a circus tent and carousel beckon.",
  "aspect_ratio": "16:9",
  "duration": "8s",
  "resolution": "720p",
  "generate_audio": true,
  "auto_fix": false,
  "safety_tolerance": "4",
  "image_urls": [
    "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-1.png",
    "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-2.png",
    "https://storage.googleapis.com/falserverless/example_inputs/veo31-r2v-input-3.png"
  ]
}
```

## Output Example

```json theme={null}
{
  "video": {
    "url": "https://storage.googleapis.com/falserverless/example_outputs/veo31-r2v-output.mp4"
  }
}
```

## Limitations

* `aspect_ratio` restricted to: `16:9`, `9:16`
* `resolution` restricted to: `720p`, `1080p`, `4k`
* `safety_tolerance` restricted to: `1`, `2`, `3`, `4`, `5`, `6`


# https://fal.ai/docs/model-api-reference/video-generation-api/xai-grok-imagine-video.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Xai Grok Imagine Video API

> API reference for Xai Grok Imagine Video. Generate videos from images with audio using xAI's Grok Imagine Video model.

<Tabs>
  <Tab title="Image To Video">
    **Endpoint:** `POST https://fal.run/xai/grok-imagine-video/image-to-video`
    **Endpoint ID:** `xai/grok-imagine-video/image-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/grok-imagine-video/image-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "xai/grok-imagine-video/image-to-video",
          arguments={
              "prompt": "Medieval knight in ornate armor walking through a mystical forest, bioluminescent plants pulsing with light, ancient stone ruins overgrown with glowing vines, over-the-shoulder camera, dark fantasy aesthetic, volumetric fog and Lumen lighting",
              "image_url": "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("xai/grok-imagine-video/image-to-video", {
        input: {
            prompt: "Medieval knight in ornate armor walking through a mystical forest, bioluminescent plants pulsing with light, ancient stone ruins overgrown with glowing vines, over-the-shoulder camera, dark fantasy aesthetic, volumetric fog and Lumen lighting",
            image_url: "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/xai/grok-imagine-video/image-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Medieval knight in ornate armor walking through a mystical forest, bioluminescent plants pulsing with light, ancient stone ruins overgrown with glowing vines, over-the-shoulder camera, dark fantasy aesthetic, volumetric fog and Lumen lighting",
        "image_url": "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of desired changes or motion in the video.
    </ParamField>

    <ParamField body="duration" type="integer" default="6">
      Video duration in seconds. Default value: `6`

      Range: `1` to `15`
    </ParamField>

    <ParamField body="aspect_ratio" type="Enum" default="auto">
      Aspect ratio of the generated video. Default value: `auto`

      Possible values: `auto`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Resolution of the output video. Default value: `"720p"`

      Possible values: `480p`, `720p`
    </ParamField>

    <ParamField body="image_url" type="string" required>
      URL of the input image for video generation.
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Medieval knight in ornate armor walking through a mystical forest, bioluminescent plants pulsing with light, ancient stone ruins overgrown with glowing vines, over-the-shoulder camera, dark fantasy aesthetic, volumetric fog and Lumen lighting",
      "duration": 6,
      "aspect_ratio": "auto",
      "resolution": "720p",
      "image_url": "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "duration": 6.041667,
        "file_name": "0Ci1dviuSnEyUZzBUq-_5_nu7MrAAa.mp4",
        "fps": 24,
        "height": 720,
        "num_frames": 145,
        "url": "https://v3b.fal.media/files/b/0a8b90e0/0Ci1dviuSnEyUZzBUq-_5_nu7MrAAa.mp4",
        "width": 1280
      }
    }
    ```
  </Tab>

  <Tab title="Text To Video">
    **Endpoint:** `POST https://fal.run/xai/grok-imagine-video/text-to-video`
    **Endpoint ID:** `xai/grok-imagine-video/text-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/grok-imagine-video/text-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "xai/grok-imagine-video/text-to-video",
          arguments={
              "prompt": "Anime schoolgirl bursting out of house door, cherry blossoms blowing, morning light, speed lines indicating rush, chibi-ready expressions, classic shojo aesthetic, vibrant colors"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("xai/grok-imagine-video/text-to-video", {
        input: {
            prompt: "Anime schoolgirl bursting out of house door, cherry blossoms blowing, morning light, speed lines indicating rush, chibi-ready expressions, classic shojo aesthetic, vibrant colors"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/xai/grok-imagine-video/text-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Anime schoolgirl bursting out of house door, cherry blossoms blowing, morning light, speed lines indicating rush, chibi-ready expressions, classic shojo aesthetic, vibrant colors"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of the desired video.
    </ParamField>

    <ParamField body="duration" type="integer" default="6">
      Video duration in seconds. Default value: `6`

      Range: `1` to `15`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      Aspect ratio of the generated video. Default value: `"16:9"`

      Possible values: `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="720p">
      Resolution of the output video. Default value: `"720p"`

      Possible values: `480p`, `720p`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Anime schoolgirl bursting out of house door, cherry blossoms blowing, morning light, speed lines indicating rush, chibi-ready expressions, classic shojo aesthetic, vibrant colors",
      "duration": 6,
      "aspect_ratio": "16:9",
      "resolution": "720p"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "duration": 6.041667,
        "file_name": "RUAbFYlssdqnbjNLmE8qP_IX7BNYGP.mp4",
        "fps": 24,
        "height": 720,
        "num_frames": 145,
        "url": "https://v3b.fal.media/files/b/0a8b90e4/RUAbFYlssdqnbjNLmE8qP_IX7BNYGP.mp4",
        "width": 1280
      }
    }
    ```
  </Tab>

  <Tab title="Reference To Video">
    **Endpoint:** `POST https://fal.run/xai/grok-imagine-video/reference-to-video`
    **Endpoint ID:** `xai/grok-imagine-video/reference-to-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/grok-imagine-video/reference-to-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "xai/grok-imagine-video/reference-to-video",
          arguments={
              "prompt": "A @Image1 running through a sunlit meadow, cinematic slow motion",
              "reference_image_urls": [
                  "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
              ]
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("xai/grok-imagine-video/reference-to-video", {
        input: {
            prompt: "A @Image1 running through a sunlit meadow, cinematic slow motion",
            reference_image_urls: [
              "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
            ]
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/xai/grok-imagine-video/reference-to-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "A @Image1 running through a sunlit meadow, cinematic slow motion",
        "reference_image_urls": [
          "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
        ]
      }'
      ```
    </CodeGroup>

    ## Examples

    > This man walking in this road between columns

    <video src="https://v3b.fal.media/files/b/0a937b3e/SCRymQFjmgeuvDXWJkCt6_eEjGlXhW.mp4" controls width="100%" />

    > This man walking in this road between columns

    <video src="https://v3b.fal.media/files/b/0a937b3e/SCRymQFjmgeuvDXWJkCt6_eEjGlXhW.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text prompt describing the video to generate. Use @Image1, @Image2, etc. to reference specific images from reference\_image\_urls in order.
    </ParamField>

    <ParamField body="reference_image_urls" type="list<string>" required>
      One or more reference image URLs to guide the video generation as style and content references. Reference in prompt as @Image1, @Image2, etc. Maximum 7 images.
    </ParamField>

    <ParamField body="duration" type="integer" default="8">
      Video duration in seconds. Default value: `8`

      Range: `1` to `10`
    </ParamField>

    <ParamField body="aspect_ratio" type="AspectRatioEnum" default="16:9">
      Aspect ratio of the generated video. Default value: `"16:9"`

      Possible values: `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="480p">
      Resolution of the output video. Default value: `"480p"`

      Possible values: `480p`, `720p`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "A @Image1 running through a sunlit meadow, cinematic slow motion",
      "reference_image_urls": [
        "https://v3b.fal.media/files/b/0a8b90e0/BFLE9VDlZqsryU-UA3BoD_image_004.png"
      ],
      "duration": 8,
      "aspect_ratio": "16:9",
      "resolution": "480p"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "duration": 8,
        "file_name": "r2v_output.mp4",
        "fps": 24,
        "height": 720,
        "num_frames": 192,
        "url": "https://v3b.fal.media/files/b/0a8b90e4/r2v_output.mp4",
        "width": 1280
      }
    }
    ```
  </Tab>

  <Tab title="Edit Video">
    **Endpoint:** `POST https://fal.run/xai/grok-imagine-video/edit-video`
    **Endpoint ID:** `xai/grok-imagine-video/edit-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/grok-imagine-video/edit-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "xai/grok-imagine-video/edit-video",
          arguments={
              "prompt": "Colorize the video",
              "video_url": "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("xai/grok-imagine-video/edit-video", {
        input: {
            prompt: "Colorize the video",
            video_url: "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/xai/grok-imagine-video/edit-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "Colorize the video",
        "video_url": "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of the desired edit.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      URL of the input video to edit. The video will be resized to a maximum area of 854x480 pixels and truncated to 8 seconds.
    </ParamField>

    <ParamField body="resolution" type="ResolutionEnum" default="auto">
      Resolution of the output video. Default value: `"auto"`

      Possible values: `auto`, `480p`, `720p`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The generated video.
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "Colorize the video",
      "video_url": "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4",
      "resolution": "auto"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "duration": 5.041667,
        "file_name": "EuDrZuQTW9m1phBXOsauz_EpJH3s8X.mp4",
        "fps": 24,
        "height": 720,
        "num_frames": 121,
        "url": "https://v3b.fal.media/files/b/0a8b9113/EuDrZuQTW9m1phBXOsauz_EpJH3s8X.mp4",
        "width": 1280
      }
    }
    ```
  </Tab>

  <Tab title="Extend Video">
    **Endpoint:** `POST https://fal.run/xai/grok-imagine-video/extend-video`
    **Endpoint ID:** `xai/grok-imagine-video/extend-video`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/xai/grok-imagine-video/extend-video/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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(
          "xai/grok-imagine-video/extend-video",
          arguments={
              "prompt": "The camera slowly zooms out to reveal the city skyline at sunset",
              "video_url": "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("xai/grok-imagine-video/extend-video", {
        input: {
            prompt: "The camera slowly zooms out to reveal the city skyline at sunset",
            video_url: "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/xai/grok-imagine-video/extend-video \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "prompt": "The camera slowly zooms out to reveal the city skyline at sunset",
        "video_url": "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4"
      }'
      ```
    </CodeGroup>

    ## Examples

    > Clouds timelapse there are mountains behind

    <video src="https://v3b.fal.media/files/b/0a937b62/EGsarDTK78nSVKlMlPli1_TyYKmwA0.mp4" controls width="100%" />

    ### Input Schema

    <ParamField body="prompt" type="string" required>
      Text description of what should happen next in the video.
    </ParamField>

    <ParamField body="video_url" type="string" required>
      URL of the source video to extend. Must be MP4 format (H.264, H.265, or AV1 codec), 2-15 seconds long.
    </ParamField>

    <ParamField body="duration" type="integer" default="6">
      Length of the extension in seconds. Default value: `6`

      Range: `2` to `10`
    </ParamField>

    ### Output Schema

    <ParamField body="video" type="VideoFile" required>
      The extended video (original + extension stitched together).
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "prompt": "The camera slowly zooms out to reveal the city skyline at sunset",
      "video_url": "https://v3b.fal.media/files/b/0a8b9112/V5Z_NIPE3ppMDWivNo6_q_video_019.mp4",
      "duration": 6
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "video": {
        "content_type": "video/mp4",
        "duration": 16,
        "file_name": "extended_video.mp4",
        "fps": 24,
        "height": 720,
        "num_frames": 384,
        "url": "https://v3b.fal.media/files/b/0a8b9113/extended_video.mp4",
        "width": 1280
      }
    }
    ```
  </Tab>
</Tabs>

## Related

* [Grok Imagine Video](/model-api-reference/video-generation-api/grok-imagine-video) — Video Generation
* [Grok Imagine Reference to Video](/model-api-reference/video-generation-api/grok-imagine-reference-to-video) — Video Generation
* [Grok Imagine Extend Video](/model-api-reference/video-generation-api/grok-imagine-extend-video) — Video Generation

## Limitations

* `duration` range: 1 to 15
* `aspect_ratio` restricted to: `auto`, `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`
* `resolution` restricted to: `480p`, `720p`
* `aspect_ratio` restricted to: `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16`
* `duration` range: 1 to 10
* `resolution` restricted to: `auto`, `480p`, `720p`
* `duration` range: 2 to 10


# https://fal.ai/docs/model-api-reference/vision-api/florence-2-large.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Florence 2 Large API

> API reference for Florence 2 Large. Florence-2 is an advanced vision foundation model that uses a prompt-based approach to handle a wide range of vision and vision-language tasks

<Tabs>
  <Tab title="More Detailed Caption">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/more-detailed-caption`
    **Endpoint ID:** `fal-ai/florence-2-large/more-detailed-caption`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/more-detailed-caption/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/more-detailed-caption",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/more-detailed-caption", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/more-detailed-caption \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="string" required>
      Results from the model
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": ""
    }
    ```
  </Tab>

  <Tab title="Detailed Caption">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/detailed-caption`
    **Endpoint ID:** `fal-ai/florence-2-large/detailed-caption`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/detailed-caption/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/detailed-caption",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/detailed-caption", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/detailed-caption \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="string" required>
      Results from the model
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": ""
    }
    ```
  </Tab>

  <Tab title="Caption">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/caption`
    **Endpoint ID:** `fal-ai/florence-2-large/caption`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/caption/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/caption",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/caption", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/caption \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="string" required>
      Results from the model
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": ""
    }
    ```
  </Tab>

  <Tab title="Ocr">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/ocr`
    **Endpoint ID:** `fal-ai/florence-2-large/ocr`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/ocr/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/ocr",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/ocr", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/ocr \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="string" required>
      Results from the model
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg"
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": ""
    }
    ```
  </Tab>

  <Tab title="Region To Description">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/region-to-description`
    **Endpoint ID:** `fal-ai/florence-2-large/region-to-description`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/region-to-description/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/region-to-description",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
              "region": {
                  "x1": 100,
                  "x2": 200,
                  "y1": 100,
                  "y2": 200
              }
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/region-to-description", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
            region: {
              x1: 100,
              x2: 200,
              y1: 100,
              y2: 200
            }
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/region-to-description \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
        "region": {
          "x1": 100,
          "x2": 200,
          "y1": 100,
          "y2": 200
        }
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    <ParamField body="region" type="Region" required>
      The user input coordinates
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="string" required>
      Results from the model
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
      "region": {
        "x1": 100,
        "x2": 200,
        "y1": 100,
        "y2": 200
      }
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": ""
    }
    ```
  </Tab>

  <Tab title="Region To Category">
    **Endpoint:** `POST https://fal.run/fal-ai/florence-2-large/region-to-category`
    **Endpoint ID:** `fal-ai/florence-2-large/region-to-category`

    <Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/florence-2-large/region-to-category/playground">
      Run this model interactively with your own prompts.
    </Card>

    ### Quick Start

    <CodeGroup>
      ```python title="Python" theme={null}
      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/florence-2-large/region-to-category",
          arguments={
              "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
              "region": {
                  "x1": 100,
                  "x2": 200,
                  "y1": 100,
                  "y2": 200
              }
          },
          with_logs=True,
          on_queue_update=on_queue_update,
      )
      print(result)
      ```

      ```javascript title="JavaScript" theme={null}
      import { fal } from "@fal-ai/client";

      const result = await fal.subscribe("fal-ai/florence-2-large/region-to-category", {
        input: {
            image_url: "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
            region: {
              x1: 100,
              x2: 200,
              y1: 100,
              y2: 200
            }
          },
        logs: true,
        onQueueUpdate: (update) => {
          if (update.status === "IN_PROGRESS") {
            update.logs.map((log) => log.message).forEach(console.log);
          }
        },
      });
      console.log(result.data);
      console.log(result.requestId);
      ```

      ```bash title="cURL" theme={null}
      curl --request POST \
        --url https://fal.run/fal-ai/florence-2-large/region-to-category \
        --header "Authorization: Key $FAL_KEY" \
        --header "Content-Type: application/json" \
        --data '{
        "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
        "region": {
          "x1": 100,
          "x2": 200,
          "y1": 100,
          "y2": 200
        }
      }'
      ```
    </CodeGroup>

    ### Input Schema

    <ParamField body="image_url" type="string" required>
      The URL of the image to be processed.
    </ParamField>

    <ParamField body="region" type="Region" required>
      The user input coordinates
    </ParamField>

    ### Output Schema

    <ParamField body="results" type="string" required>
      Results from the model
    </ParamField>

    ### Input Example

    ```json theme={null}
    {
      "image_url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/car.jpg",
      "region": {
        "x1": 100,
        "x2": 200,
        "y1": 100,
        "y2": 200
      }
    }
    ```

    ### Output Example

    ```json theme={null}
    {
      "results": ""
    }
    ```
  </Tab>
</Tabs>

## Related

* [Florence-2 Large](/model-api-reference/vision-api/florence-2-large) — Vision
* [Florence-2 Large](/model-api-reference/image-generation-api/florence-2-large) — Image Generation


# https://fal.ai/docs/model-api-reference/vision-api/imageutils.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Imageutils API

> API reference for Imageutils. Predict the probability of an image being NSFW.

**Endpoint:** `POST https://fal.run/fal-ai/imageutils/nsfw`
**Endpoint ID:** `fal-ai/imageutils/nsfw`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/fal-ai/imageutils/nsfw/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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/imageutils/nsfw",
      arguments={
          "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("fal-ai/imageutils/nsfw", {
    input: {
        image_url: "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/fal-ai/imageutils/nsfw \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="image_url" type="string" required>
  Input image url.
</ParamField>

### Output Schema

<ParamField body="nsfw_probability" type="float" required>
  The probability of the image being NSFW.
</ParamField>

### Input Example

```json theme={null}
{
  "image_url": "https://storage.googleapis.com/falserverless/model_tests/remove_background/elephant.jpg"
}
```


# https://fal.ai/docs/model-api-reference/vision-api/openrouter-router.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Openrouter Router API

> API reference for Openrouter Router. Run any Vision Language Model with fal. Analyze and understand images using Claude (Anthropic), GPT-5 / GPT-4o (OpenAI), Gemini (Google), Grok (xAI), Llama (Meta),

**Endpoint:** `POST https://fal.run/openrouter/router/vision`
**Endpoint ID:** `openrouter/router/vision`

<Card title="Try it in the Playground" icon="play" href="https://fal.ai/models/openrouter/router/vision/playground">
  Run this model interactively with your own prompts.
</Card>

### Quick Start

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "openrouter/router/vision",
      arguments={
          "image_urls": [
              "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg"
          ],
          "prompt": "Caption this image for a text-to-image model with as much detail as possible.",
          "model": "google/gemini-2.5-flash"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("openrouter/router/vision", {
    input: {
        image_urls: [
          "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg"
        ],
        prompt: "Caption this image for a text-to-image model with as much detail as possible.",
        model: "google/gemini-2.5-flash"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```

  ```bash title="cURL" theme={null}
  curl --request POST \
    --url https://fal.run/openrouter/router/vision \
    --header "Authorization: Key $FAL_KEY" \
    --header "Content-Type: application/json" \
    --data '{
    "image_urls": [
      "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg"
    ],
    "prompt": "Caption this image for a text-to-image model with as much detail as possible.",
    "model": "google/gemini-2.5-flash"
  }'
  ```
</CodeGroup>

### Input Schema

<ParamField body="image_urls" type="list<string>" required>
  List of image URLs to be processed
</ParamField>

<ParamField body="prompt" type="string" required>
  Prompt to be used for the image
</ParamField>

<ParamField body="system_prompt" type="string">
  System prompt to provide context or instructions to the model
</ParamField>

<ParamField body="model" type="string" required>
  Name of the model to use. Charged based on actual token usage.
</ParamField>

<ParamField body="reasoning" type="boolean" default="false">
  Should reasoning be the part of the final answer.
</ParamField>

<ParamField body="temperature" type="float" default="1">
  This setting influences the variety in the model's responses. Lower values lead to more predictable and typical responses, while higher values encourage more diverse and less common responses. At 0, the model always gives the same response for a given input. Default value: `1`

  Range: `0` to `2`
</ParamField>

<ParamField body="max_tokens" type="integer">
  This sets the upper limit for the number of tokens the model can generate in response. It won't produce more than this limit. The maximum value is the context length minus the prompt length.
</ParamField>

### Output Schema

<ParamField body="output" type="string" required>
  Generated output
</ParamField>

<ParamField body="usage" type="UsageInfo" required>
  Token usage information
</ParamField>

### Input Example

```json theme={null}
{
  "image_urls": [
    "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg"
  ],
  "prompt": "Caption this image for a text-to-image model with as much detail as possible.",
  "system_prompt": "Only answer the question, do not provide any additional information or add any prefix/suffix other than the answer of the original question. Don't use markdown.",
  "model": "google/gemini-2.5-flash",
  "reasoning": false,
  "temperature": 1
}
```

### Output Example

```json theme={null}
{
  "output": "A close-up of a tiger's face focusing on its bright orange iris and the area around its eye, with white fur eyebrows and a contrasting black and rich orange striped fur pattern. The word \"FLUX\" is overlaid in bold, white, brush-stroke styled text across the tiger's face.",
  "usage": {
    "completion_tokens": 63,
    "cost": 0.0005595,
    "prompt_tokens": 1340,
    "total_tokens": 1403
  }
}
```

## 🚀 Usage with OpenAI Client

```python theme={null}
from openai import OpenAI
import os

client = OpenAI(
    base_url="https://fal.run/openrouter/router/openai/v1",
    api_key="not-needed",
    default_headers={
        "Authorization": f"Key {os.environ['FAL_KEY']}",
    },
)

response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[
        {
            "role": "system",
            "content": "Only answer the question, do not provide any additional information or add any prefix/suffix other than the answer of the original question. Don't use markdown.",
        },
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Caption this image for a text-to-image model with as much detail as possible."},
                {
                    "type": "image_url",
                    "image_url": "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg",
                },
            ],
        },
    ],
    temperature=1,
)

print(response.choices[0].message.content)
```

## 🚿 Streaming Example

```python theme={null}
from openai import OpenAI
import os

client = OpenAI(
    base_url="https://fal.run/openrouter/router/openai/v1",
    api_key="not-needed",
    default_headers={
        "Authorization": f"Key {os.environ['FAL_KEY']}",
    },
)

stream = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[
        {
            "role": "system",
            "content": "Only answer the question, do not provide any additional information or add any prefix/suffix other than the answer of the original question. Don't use markdown.",
        },
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Caption this image for a text-to-image model with as much detail as possible."},
                {
                    "type": "image_url",
                    "image_url": "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg",
                },
            ],
        },
    ],
    temperature=1,
    stream=True,
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

## 📚 Documentation

For more details, visit the official docs:

* 🔗 [OpenRouter API Docs](https://openrouter.ai/docs/quickstart)
* ⚡ [fal.ai API Docs](https://docs.fal.ai/model-apis)

## Limitations

* `temperature` range: 0 to 2


# https://fal.ai/docs/model-api-reference/vision-api/overview.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Vision API

> Vision API reference. Models for understanding and analyzing images, including captioning, visual question answering, and object detection..

## Overview

Models for understanding and analyzing images, including captioning, visual question answering, and object detection.

## Top Models

<CardGroup cols={2}>
  <Card title="OpenRouter [Vision] API" href="/model-api-reference/vision-api/openrouter-router">
    Run any Vision Language Model with fal. Analyze and understand images using Claude (Anthropic), GPT-5 / GPT-4o (OpenAI), Gemini (Google), Grok (xAI), Llama (Meta), Qwen, Pixtral (Mistral), and more. S

    <Frame>
      <img src="https://v3b.fal.media/files/b/penguin/v-wl5CGbHxNVatcGXntIY_e14c7922d88348769a90469d1c206501.jpg" alt="Example output from OpenRouter [Vision]" noZoom />
    </Frame>
  </Card>

  <Card title="NSFW Filter API" href="/model-api-reference/vision-api/imageutils">
    Predict the probability of an image being NSFW.

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/nsfw-filter.webp" alt="Example output from NSFW Filter" noZoom />
    </Frame>
  </Card>

  <Card title="Florence-2 Large API" href="/model-api-reference/vision-api/florence-2-large">
    Florence-2 is an advanced vision foundation model that uses a prompt-based approach to handle a wide range of vision and vision-language tasks

    <Frame>
      <img src="https://storage.googleapis.com/falserverless/gallery/florence-2-large.jpeg" alt="Example output from Florence-2 Large" noZoom />
    </Frame>
  </Card>
</CardGroup>

Explore all vision models on [fal.ai/models](https://fal.ai/models).

## Quick Start

Get started with **OpenRouter \[Vision]**:

<CodeGroup>
  ```python title="Python" theme={null}
  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(
      "openrouter/router/vision",
      arguments={
          "image_urls": [
              "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg"
          ],
          "prompt": "Caption this image for a text-to-image model with as much detail as possible.",
          "model": "google/gemini-2.5-flash"
      },
      with_logs=True,
      on_queue_update=on_queue_update,
  )
  print(result)
  ```

  ```javascript title="JavaScript" theme={null}
  import { fal } from "@fal-ai/client";

  const result = await fal.subscribe("openrouter/router/vision", {
    input: {
        image_urls: [
          "https://fal.media/files/tiger/4Ew1xYW6oZCs6STQVC7V8_86440216d0fe42e4b826d03a2121468e.jpg"
        ],
        prompt: "Caption this image for a text-to-image model with as much detail as possible.",
        model: "google/gemini-2.5-flash"
      },
    logs: true,
    onQueueUpdate: (update) => {
      if (update.status === "IN_PROGRESS") {
        update.logs.map((log) => log.message).forEach(console.log);
      }
    },
  });
  console.log(result.data);
  console.log(result.requestId);
  ```
</CodeGroup>

## Pricing

For detailed pricing information, see the [fal.ai pricing page](https://fal.ai/pricing) or individual model pages.


# https://fal.ai/docs/platform-apis/v1/account/billing.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Account Billing

> Returns billing information for the authenticated account. Use the `expand`
parameter to include additional details.

**Expandable Fields:**
- `credits` — Current credit balance and currency

**Common Use Cases:**
- Monitor available credit balance programmatically
- Display balance in custom dashboards



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /account/billing
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /account/billing:
    get:
      tags:
        - Account
      summary: Account Billing
      description: >-
        Returns billing information for the authenticated account. Use the
        `expand`

        parameter to include additional details.


        **Expandable Fields:**

        - `credits` — Current credit balance and currency


        **Common Use Cases:**

        - Monitor available credit balance programmatically

        - Display balance in custom dashboards
      operationId: getAccountBilling
      parameters:
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Data to include in the response. Use 'credits' to include current
              credit balance.
            example: credits
          required: false
          description: >-
            Data to include in the response. Use 'credits' to include current
            credit balance.
          name: expand
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Account billing information retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  username:
                    type: string
                    description: Account username
                    example: my-team
                  credits:
                    type: object
                    properties:
                      current_balance:
                        type: number
                        minimum: 0
                        description: Current credit balance available on the account
                        example: 24.5
                      currency:
                        type: string
                        description: Currency code for the balance
                        example: USD
                    required:
                      - current_balance
                      - currency
                    description: >-
                      Credit balance details. Only present when 'credits' is
                      included in expand parameter.
                required:
                  - username
                description: Account billing information with optional expanded details
              example:
                username: my-team
                credits:
                  current_balance: 24.5
                  currency: USD
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/account/focus.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# FOCUS Report

> 
Returns a FOCUS compliant billing report as a CSV download.

> **Availability:** This endpoint is available to enterprise customers with FOCUS reports enabled. Contact your account team or support@fal.ai to request access.

Supports two data sources:
- **invoice**: Finalized invoice data for a billing month. Includes usage charges, credits, and taxes.
- **estimate**: Real-time usage estimates for a date range. Pre-invoice data that may change once invoiced.

The report follows the [FinOps FOCUS specification](https://focus.finops.org/) for cloud billing data interoperability.

**Invoice reports** default to the most recently available billing month.
**Usage estimates** default to the last 24 hours, with a maximum 90-day lookback.
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /account/focus
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /account/focus:
    get:
      tags:
        - Account
      summary: FOCUS Report
      description: >-

        Returns a FOCUS compliant billing report as a CSV download.


        > **Availability:** This endpoint is available to enterprise customers
        with FOCUS reports enabled. Contact your account team or support@fal.ai
        to request access.


        Supports two data sources:

        - **invoice**: Finalized invoice data for a billing month. Includes
        usage charges, credits, and taxes.

        - **estimate**: Real-time usage estimates for a date range. Pre-invoice
        data that may change once invoiced.


        The report follows the [FinOps FOCUS
        specification](https://focus.finops.org/) for cloud billing data
        interoperability.


        **Invoice reports** default to the most recently available billing
        month.

        **Usage estimates** default to the last 24 hours, with a maximum 90-day
        lookback.
            
      operationId: getFocusReport
      parameters:
        - schema:
            type: string
            enum:
              - invoice
              - estimate
            description: >-
              Report source. 'invoice' returns finalized invoice data for a
              billing month. 'estimate' returns real-time usage estimates for a
              date range.
            example: invoice
          required: true
          description: >-
            Report source. 'invoice' returns finalized invoice data for a
            billing month. 'estimate' returns real-time usage estimates for a
            date range.
          name: source
          in: query
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}$
            description: >-
              Invoice billing month (YYYY-MM). The month the invoice was issued
              (e.g. '2025-02' for January charges). Used with source=invoice.
              Defaults to most recent available billing month.
            example: 2025-02
          required: false
          description: >-
            Invoice billing month (YYYY-MM). The month the invoice was issued
            (e.g. '2025-02' for January charges). Used with source=invoice.
            Defaults to most recent available billing month.
          name: billing_month
          in: query
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}$
            description: >-
              Charge month (YYYY-MM). The month charges were incurred. Converted
              to billing_month by adding 1 month (billing in arrears).
              Alternative to billing_month. Used with source=invoice.
            example: 2025-01
          required: false
          description: >-
            Charge month (YYYY-MM). The month charges were incurred. Converted
            to billing_month by adding 1 month (billing in arrears). Alternative
            to billing_month. Used with source=invoice.
          name: charge_month
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            type: string
            default: UTC
            description: >-
              Timezone for date aggregation and boundaries. All timestamps in
              responses are in UTC, but this controls how dates are bucketed.
            example: UTC
          required: false
          description: >-
            Timezone for date aggregation and boundaries. All timestamps in
            responses are in UTC, but this controls how dates are bucketed.
          name: timezone
          in: query
        - schema:
            type: string
            enum:
              - minute
              - hour
              - day
              - week
              - month
            description: >-
              Aggregation timeframe for timeseries data (auto-detected from date
              range if not specified). Auto-detection uses: minute (<2h), hour
              (<2d), day (<64d), week (<183d), month (>=183d).
            example: day
          required: false
          description: >-
            Aggregation timeframe for timeseries data (auto-detected from date
            range if not specified). Auto-detection uses: minute (<2h), hour
            (<2d), day (<64d), week (<183d), month (>=183d).
          name: timeframe
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'true'
            description: >-
              Whether to adjust start/end dates to align with timeframe
              boundaries and use exclusive end. Defaults to true. When true,
              dates are aligned to the start of the timeframe period (e.g.,
              start of day) and end is made exclusive (e.g., start of next day).
              When false, uses exact dates provided.
            example: 'true'
          required: false
          description: >-
            Whether to adjust start/end dates to align with timeframe boundaries
            and use exclusive end. Defaults to true. When true, dates are
            aligned to the start of the timeframe period (e.g., start of day)
            and end is made exclusive (e.g., start of next day). When false,
            uses exact dates provided.
          name: bound_to_timeframe
          in: query
      responses:
        '200':
          description: FOCUS compliant CSV report
          content:
            text/csv:
              schema:
                type: string
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/account/model-access-controls.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Access Controls Report

> 
Returns the current model access controls for your organization as a CSV download.

> **Availability:** This endpoint is available to enterprise customers with model access controls enabled. Contact your account team or support@fal.ai to request access.

The report includes each model's endpoint ID, title, category, enterprise readiness status, and the resolved UI and API access state (ALLOWED or BLOCKED).
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /account/model-access-controls
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /account/model-access-controls:
    get:
      tags:
        - Account
      summary: Model Access Controls Report
      description: >-

        Returns the current model access controls for your organization as a CSV
        download.


        > **Availability:** This endpoint is available to enterprise customers
        with model access controls enabled. Contact your account team or
        support@fal.ai to request access.


        The report includes each model's endpoint ID, title, category,
        enterprise readiness status, and the resolved UI and API access state
        (ALLOWED or BLOCKED).
            
      operationId: getModelAccessControls
      responses:
        '200':
          description: Model access controls CSV report
          content:
            text/csv:
              schema:
                type: string
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/compute/instances/create.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Compute Instance

> Creates a new compute instance with the specified configuration and SSH key.

**Requirements:**
- Requires compute permissions (extra_permissions.compute = true)
- Authentication required via admin API key
- Valid SSH public key required for instance access

**Key Features:**
- Create high-performance GPU instances
- Specify sector for InfiniBand configuration (8x H100 only)
- SSH key-based authentication
- Automatic instance provisioning and region assignment
- Idempotent creation with Idempotency-Key header (optional but recommended)

**Common Use Cases:**
- Spin up compute resources for ML training
- Create GPU instances for inference workloads
- Set up development environments with H100 GPUs
- Deploy distributed training with InfiniBand networking

**Instance Types:**
- `gpu_8x_h100_sxm5`: 8x NVIDIA H100 GPUs (high-performance, supports sector configuration for InfiniBand)
- `gpu_1x_h100_sxm5`: 1x NVIDIA H100 GPU (standard)

**Idempotency:**
- Optional Idempotency-Key header prevents duplicate instance creation on retries
- Responses cached for 10 minutes per unique key

See [fal.ai docs](https://docs.fal.ai/compute) for more details.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json post /compute/instances
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /compute/instances:
    post:
      tags:
        - Compute
      summary: Create Compute Instance
      description: >-
        Creates a new compute instance with the specified configuration and SSH
        key.


        **Requirements:**

        - Requires compute permissions (extra_permissions.compute = true)

        - Authentication required via admin API key

        - Valid SSH public key required for instance access


        **Key Features:**

        - Create high-performance GPU instances

        - Specify sector for InfiniBand configuration (8x H100 only)

        - SSH key-based authentication

        - Automatic instance provisioning and region assignment

        - Idempotent creation with Idempotency-Key header (optional but
        recommended)


        **Common Use Cases:**

        - Spin up compute resources for ML training

        - Create GPU instances for inference workloads

        - Set up development environments with H100 GPUs

        - Deploy distributed training with InfiniBand networking


        **Instance Types:**

        - `gpu_8x_h100_sxm5`: 8x NVIDIA H100 GPUs (high-performance, supports
        sector configuration for InfiniBand)

        - `gpu_1x_h100_sxm5`: 1x NVIDIA H100 GPU (standard)


        **Idempotency:**

        - Optional Idempotency-Key header prevents duplicate instance creation
        on retries

        - Responses cached for 10 minutes per unique key


        See [fal.ai docs](https://docs.fal.ai/compute) for more details.
      operationId: createComputeInstance
      parameters:
        - schema:
            type: string
            description: Optional idempotency key for safe request retries
            example: 550e8400-e29b-41d4-a716-446655440000
          required: false
          description: Optional idempotency key for safe request retries
          name: Idempotency-Key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                instance_type:
                  type: string
                  enum:
                    - gpu_8x_h100_sxm5
                    - gpu_1x_h100_sxm5
                  description: Type of compute instance to create
                  example: gpu_1x_h100_sxm5
                ssh_key:
                  type: string
                  minLength: 1
                  description: >-
                    SSH public key for accessing the instance (e.g., 'ssh-rsa
                    AAAAB3...')
                  example: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC... user@host
                sector:
                  type: string
                  enum:
                    - sector_1
                    - sector_2
                    - sector_3
                  description: >-
                    Sector for InfiniBand configuration (only valid with
                    gpu_8x_h100_sxm5)
                  example: sector_1
              required:
                - instance_type
                - ssh_key
              description: Request body for creating a new compute instance with SSH access
            example:
              instance_type: gpu_8x_h100_sxm5
              ssh_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7Kl4... user@host
              sector: sector_1
      responses:
        '201':
          description: Compute instance created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Unique identifier for the compute instance
                    example: inst_abc123xyz
                  instance_type:
                    type: string
                    enum:
                      - gpu_8x_h100_sxm5
                      - gpu_1x_h100_sxm5
                    description: Type of compute instance (GPU configuration)
                    example: gpu_1x_h100_sxm5
                  region:
                    type: string
                    enum:
                      - us-west
                      - us-central
                      - us-east
                      - eu-north
                      - eu-west
                      - other
                    description: Geographical region where the instance is located
                    example: us-west
                  sector:
                    type: string
                    enum:
                      - sector_1
                      - sector_2
                      - sector_3
                    description: >-
                      Sector identifier for instance placement within the region
                      (if applicable)
                    example: sector_1
                  ip:
                    type: string
                    description: >-
                      IP address of the instance (available when instance is
                      ready)
                    example: 203.0.113.42
                  status:
                    type: string
                    enum:
                      - ready
                      - init
                      - pending
                      - provisioning
                      - stopped
                      - unknown
                    description: Current operational status of the instance
                    example: ready
                  creator_user_nickname:
                    type: string
                    description: Nickname of the user who created this instance
                    example: developer
                required:
                  - id
                  - instance_type
                  - region
                  - status
                description: >-
                  Compute instance details including configuration, location,
                  and status
              example:
                id: inst_abc123xyz
                instance_type: gpu_8x_h100_sxm5
                region: us-west
                sector: sector_1
                status: provisioning
                creator_user_nickname: developer
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/compute/instances/delete.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Delete Compute Instance

> Deletes a specific compute instance by its ID. This action is irreversible.

**Requirements:**
- Requires compute permissions (extra_permissions.compute = true)
- Authentication required via admin API key
- Instance must belong to the authenticated user's workspace

**Key Features:**
- Permanently remove compute instances
- Free up compute resources
- Stop billing for the instance
- Clean up unused resources

**Important:**
- This action cannot be undone
- All data on the instance will be lost
- Instance will be immediately terminated
- Billing stops after deletion

**Common Use Cases:**
- Clean up completed workloads
- Remove failed or stuck instances
- Manage compute costs
- Free up quota for new instances

See [fal.ai docs](https://docs.fal.ai/compute) for more details.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json delete /compute/instances/{id}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /compute/instances/{id}:
    delete:
      tags:
        - Compute
      summary: Delete Compute Instance
      description: >-
        Deletes a specific compute instance by its ID. This action is
        irreversible.


        **Requirements:**

        - Requires compute permissions (extra_permissions.compute = true)

        - Authentication required via admin API key

        - Instance must belong to the authenticated user's workspace


        **Key Features:**

        - Permanently remove compute instances

        - Free up compute resources

        - Stop billing for the instance

        - Clean up unused resources


        **Important:**

        - This action cannot be undone

        - All data on the instance will be lost

        - Instance will be immediately terminated

        - Billing stops after deletion


        **Common Use Cases:**

        - Clean up completed workloads

        - Remove failed or stuck instances

        - Manage compute costs

        - Free up quota for new instances


        See [fal.ai docs](https://docs.fal.ai/compute) for more details.
      operationId: deleteComputeInstance
      parameters:
        - schema:
            type: string
            minLength: 1
            description: Unique identifier for the compute instance
            example: inst_abc123xyz
          required: true
          description: Unique identifier for the compute instance
          name: id
          in: path
      responses:
        '204':
          description: Compute instance deleted successfully
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/compute/instances/get.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Compute Instance

> Retrieves detailed information about a specific compute instance by its ID.

**Requirements:**
- Requires compute permissions (extra_permissions.compute = true)
- Authentication required via admin API key
- Instance must belong to the authenticated user's workspace

**Key Features:**
- Get current instance status and configuration
- Access instance IP address when available
- View region and sector placement
- Check creator information

**Common Use Cases:**
- Monitor specific instance status
- Retrieve connection details (IP address)
- Check instance readiness before use
- Audit instance configuration

See [fal.ai docs](https://docs.fal.ai/compute) for more details.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /compute/instances/{id}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /compute/instances/{id}:
    get:
      tags:
        - Compute
      summary: Get Compute Instance
      description: >-
        Retrieves detailed information about a specific compute instance by its
        ID.


        **Requirements:**

        - Requires compute permissions (extra_permissions.compute = true)

        - Authentication required via admin API key

        - Instance must belong to the authenticated user's workspace


        **Key Features:**

        - Get current instance status and configuration

        - Access instance IP address when available

        - View region and sector placement

        - Check creator information


        **Common Use Cases:**

        - Monitor specific instance status

        - Retrieve connection details (IP address)

        - Check instance readiness before use

        - Audit instance configuration


        See [fal.ai docs](https://docs.fal.ai/compute) for more details.
      operationId: getComputeInstance
      parameters:
        - schema:
            type: string
            minLength: 1
            description: Unique identifier for the compute instance
            example: inst_abc123xyz
          required: true
          description: Unique identifier for the compute instance
          name: id
          in: path
      responses:
        '200':
          description: Successfully retrieved compute instance details
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Unique identifier for the compute instance
                    example: inst_abc123xyz
                  instance_type:
                    type: string
                    enum:
                      - gpu_8x_h100_sxm5
                      - gpu_1x_h100_sxm5
                    description: Type of compute instance (GPU configuration)
                    example: gpu_1x_h100_sxm5
                  region:
                    type: string
                    enum:
                      - us-west
                      - us-central
                      - us-east
                      - eu-north
                      - eu-west
                      - other
                    description: Geographical region where the instance is located
                    example: us-west
                  sector:
                    type: string
                    enum:
                      - sector_1
                      - sector_2
                      - sector_3
                    description: >-
                      Sector identifier for instance placement within the region
                      (if applicable)
                    example: sector_1
                  ip:
                    type: string
                    description: >-
                      IP address of the instance (available when instance is
                      ready)
                    example: 203.0.113.42
                  status:
                    type: string
                    enum:
                      - ready
                      - init
                      - pending
                      - provisioning
                      - stopped
                      - unknown
                    description: Current operational status of the instance
                    example: ready
                  creator_user_nickname:
                    type: string
                    description: Nickname of the user who created this instance
                    example: developer
                required:
                  - id
                  - instance_type
                  - region
                  - status
                description: >-
                  Compute instance details including configuration, location,
                  and status
              example:
                id: inst_abc123xyz
                instance_type: gpu_1x_h100_sxm5
                region: us-west
                sector: sector_1
                ip: 203.0.113.42
                status: ready
                creator_user_nickname: developer
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/compute/instances/list.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List Compute Instances

> Returns a list of all compute instances belonging to the authenticated user's workspace.

**Requirements:**
- Requires compute permissions (extra_permissions.compute = true)
- Authentication required via admin API key

**Key Features:**
- View all instances regardless of status
- Includes instance configuration, region, and current status
- Paginated results for large instance lists

**Common Use Cases:**
- Monitor all active compute resources
- Check instance status and availability
- Audit compute resource usage
- Build compute management dashboards

See [fal.ai docs](https://docs.fal.ai/compute) for more details.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /compute/instances
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /compute/instances:
    get:
      tags:
        - Compute
      summary: List Compute Instances
      description: >-
        Returns a list of all compute instances belonging to the authenticated
        user's workspace.


        **Requirements:**

        - Requires compute permissions (extra_permissions.compute = true)

        - Authentication required via admin API key


        **Key Features:**

        - View all instances regardless of status

        - Includes instance configuration, region, and current status

        - Paginated results for large instance lists


        **Common Use Cases:**

        - Monitor all active compute resources

        - Check instance status and availability

        - Audit compute resource usage

        - Build compute management dashboards


        See [fal.ai docs](https://docs.fal.ai/compute) for more details.
      operationId: listComputeInstances
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: >-
              Maximum number of items to return. Actual maximum depends on query
              type and expansion parameters.
            example: 50
          required: false
          description: >-
            Maximum number of items to return. Actual maximum depends on query
            type and expansion parameters.
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor from previous response. Encodes the page number.
            example: Mg==
          required: false
          description: Pagination cursor from previous response. Encodes the page number.
          name: cursor
          in: query
      responses:
        '200':
          description: Successfully retrieved compute instances
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  instances:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: Unique identifier for the compute instance
                          example: inst_abc123xyz
                        instance_type:
                          type: string
                          enum:
                            - gpu_8x_h100_sxm5
                            - gpu_1x_h100_sxm5
                          description: Type of compute instance (GPU configuration)
                          example: gpu_1x_h100_sxm5
                        region:
                          type: string
                          enum:
                            - us-west
                            - us-central
                            - us-east
                            - eu-north
                            - eu-west
                            - other
                          description: Geographical region where the instance is located
                          example: us-west
                        sector:
                          type: string
                          enum:
                            - sector_1
                            - sector_2
                            - sector_3
                          description: >-
                            Sector identifier for instance placement within the
                            region (if applicable)
                          example: sector_1
                        ip:
                          type: string
                          description: >-
                            IP address of the instance (available when instance
                            is ready)
                          example: 203.0.113.42
                        status:
                          type: string
                          enum:
                            - ready
                            - init
                            - pending
                            - provisioning
                            - stopped
                            - unknown
                          description: Current operational status of the instance
                          example: ready
                        creator_user_nickname:
                          type: string
                          description: Nickname of the user who created this instance
                          example: developer
                      required:
                        - id
                        - instance_type
                        - region
                        - status
                      description: >-
                        Compute instance details including configuration,
                        location, and status
                    description: >-
                      Array of compute instances belonging to the authenticated
                      user
                required:
                  - next_cursor
                  - has_more
                  - instances
                description: >-
                  Response containing a list of compute instances with
                  pagination support
              example:
                instances:
                  - id: inst_abc123xyz
                    instance_type: gpu_1x_h100_sxm5
                    region: us-west
                    sector: sector_1
                    ip: 203.0.113.42
                    status: ready
                    creator_user_nickname: developer
                  - id: inst_def456uvw
                    instance_type: gpu_8x_h100_sxm5
                    region: us-east
                    status: provisioning
                    creator_user_nickname: developer
                next_cursor: null
                has_more: false
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/keys/create.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create API Key

> Creates a new API key with the specified alias.

**Requirements:**
- Authentication required via admin API key

**Important Security Notice:**
The `key_secret` is only returned once at creation time. Store it securely immediately
as it cannot be retrieved again. If lost, you must delete the key and create a new one.

**Key Features:**
- Create API keys programmatically without UI access
- Assign meaningful aliases for key identification
- Keys are immediately active upon creation

**Common Use Cases:**
- Programmatic key provisioning for CI/CD pipelines
- Self-serve key generation for team members
- Automated key rotation workflows
- Integration with secret management systems



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json post /keys
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /keys:
    post:
      tags:
        - Keys
      summary: Create API Key
      description: >-
        Creates a new API key with the specified alias.


        **Requirements:**

        - Authentication required via admin API key


        **Important Security Notice:**

        The `key_secret` is only returned once at creation time. Store it
        securely immediately

        as it cannot be retrieved again. If lost, you must delete the key and
        create a new one.


        **Key Features:**

        - Create API keys programmatically without UI access

        - Assign meaningful aliases for key identification

        - Keys are immediately active upon creation


        **Common Use Cases:**

        - Programmatic key provisioning for CI/CD pipelines

        - Self-serve key generation for team members

        - Automated key rotation workflows

        - Integration with secret management systems
      operationId: createApiKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                alias:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: Required friendly name for the API key
                  example: Production Key
              required:
                - alias
              description: Request body for creating a new API key
            example:
              alias: Production Key
      responses:
        '201':
          description: >-
            API key created successfully. Store the key_secret securely - it
            will not be shown again.
          content:
            application/json:
              schema:
                type: object
                properties:
                  key_id:
                    type: string
                    description: Unique identifier for the newly created API key
                    example: abc123def456
                  key_secret:
                    type: string
                    description: >-
                      Secret portion of the API key. IMPORTANT: This is only
                      returned once at creation time and cannot be retrieved
                      again.
                    example: sk_live_abc123...
                  key:
                    type: string
                    description: >-
                      Full API key in the format 'key_id:key_secret'. Use this
                      value directly for API authorization. IMPORTANT: This is
                      only returned once at creation time and cannot be
                      retrieved again.
                    example: abc123def456:sk_live_abc123...
                required:
                  - key_id
                  - key_secret
                  - key
                description: >-
                  Response containing the newly created API key credentials. The
                  key_secret is only returned once.
              example:
                key_id: abc123def456
                key_secret: sk_live_abc123def456xyz789
                key: abc123def456:sk_live_abc123def456xyz789
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/keys/delete.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Delete API Key

> Deletes an API key by its ID. This action is irreversible.

**Requirements:**
- Authentication required via admin API key
- Key must belong to the authenticated user's workspace

**Key Features:**
- Permanently revoke API key access
- Idempotent operation (safe to retry)
- Optional Idempotency-Key header for safe retries

**Important:**
- This action cannot be undone
- Any applications using this key will immediately lose access
- Returns 204 even if the key doesn't exist (idempotent behavior)

**Common Use Cases:**
- Revoke compromised keys
- Clean up unused keys
- Implement key rotation (delete old, create new)
- Offboard team members



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json delete /keys/{key_id}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /keys/{key_id}:
    delete:
      tags:
        - Keys
      summary: Delete API Key
      description: |-
        Deletes an API key by its ID. This action is irreversible.

        **Requirements:**
        - Authentication required via admin API key
        - Key must belong to the authenticated user's workspace

        **Key Features:**
        - Permanently revoke API key access
        - Idempotent operation (safe to retry)
        - Optional Idempotency-Key header for safe retries

        **Important:**
        - This action cannot be undone
        - Any applications using this key will immediately lose access
        - Returns 204 even if the key doesn't exist (idempotent behavior)

        **Common Use Cases:**
        - Revoke compromised keys
        - Clean up unused keys
        - Implement key rotation (delete old, create new)
        - Offboard team members
      operationId: deleteApiKey
      parameters:
        - schema:
            type: string
            minLength: 1
            description: Unique identifier of the API key to delete
            example: abc123def456
          required: true
          description: Unique identifier of the API key to delete
          name: key_id
          in: path
        - schema:
            type: string
            description: Optional idempotency key for safe request retries
            example: 550e8400-e29b-41d4-a716-446655440000
          required: false
          description: Optional idempotency key for safe request retries
          name: Idempotency-Key
          in: header
      responses:
        '204':
          description: API key deleted successfully (or already deleted)
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/keys/list.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List API Keys

> Returns a list of all API keys belonging to the authenticated user's workspace.

**Requirements:**
- Authentication required via admin API key

**Key Features:**
- View all API keys with their aliases and creation dates
- Optionally expand to include creator information
- Paginated results for workspaces with many keys

**Expansion Options:**
- `expand=creator_info`: Include creator_nickname and creator_email for each key

**Common Use Cases:**
- Audit existing API keys
- Find keys by alias
- Monitor key creation activity
- Build key management interfaces



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /keys
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /keys:
    get:
      tags:
        - Keys
      summary: List API Keys
      description: >-
        Returns a list of all API keys belonging to the authenticated user's
        workspace.


        **Requirements:**

        - Authentication required via admin API key


        **Key Features:**

        - View all API keys with their aliases and creation dates

        - Optionally expand to include creator information

        - Paginated results for workspaces with many keys


        **Expansion Options:**

        - `expand=creator_info`: Include creator_nickname and creator_email for
        each key


        **Common Use Cases:**

        - Audit existing API keys

        - Find keys by alias

        - Monitor key creation activity

        - Build key management interfaces
      operationId: listApiKeys
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: >-
              Maximum number of items to return. Actual maximum depends on query
              type and expansion parameters.
            example: 50
          required: false
          description: >-
            Maximum number of items to return. Actual maximum depends on query
            type and expansion parameters.
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor from previous response. Encodes the page number.
            example: Mg==
          required: false
          description: Pagination cursor from previous response. Encodes the page number.
          name: cursor
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Fields to expand in the response. Available: creator_info
              (includes creator_nickname and creator_email)
            example:
              - creator_info
          required: false
          description: >-
            Fields to expand in the response. Available: creator_info (includes
            creator_nickname and creator_email)
          name: expand
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Successfully retrieved API keys
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  keys:
                    type: array
                    items:
                      type: object
                      properties:
                        key_id:
                          type: string
                          description: Unique identifier for the API key
                          example: abc123def456
                        alias:
                          type: string
                          description: User-provided friendly name for the key
                          example: Production Key
                        scope:
                          type: string
                          enum:
                            - API
                          description: >-
                            Scope of the API key. Only API scope keys can be
                            managed via this API.
                          example: API
                        created_at:
                          type: string
                          description: ISO8601 timestamp when the key was created
                          example: '2025-01-15T12:00:00Z'
                        creator_nickname:
                          type: string
                          description: >-
                            Nickname of the user who created this key (when
                            expanded)
                          example: developer
                        creator_email:
                          type: string
                          description: >-
                            Email of the user who created this key (when
                            expanded)
                          example: developer@example.com
                      required:
                        - key_id
                        - alias
                        - scope
                        - created_at
                      description: API key information
                    description: Array of API keys belonging to the authenticated user
                required:
                  - next_cursor
                  - has_more
                  - keys
                description: Response containing a list of API keys with pagination support
              example:
                keys:
                  - key_id: abc123def456
                    alias: Production Key
                    scope: API
                    created_at: '2025-01-15T12:00:00Z'
                  - key_id: xyz789ghi012
                    alias: Development Key
                    scope: API
                    created_at: '2025-01-10T09:30:00Z'
                next_cursor: null
                has_more: false
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/models.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Model search

> 
Unified endpoint for discovering model endpoints. Supports three usage modes:

**1. List Mode** (no parameters):
Paginated list of all available model endpoints with minimal metadata.

**2. Find Mode** (`endpoint_id` parameter):
Retrieve specific model endpoint(s) by ID. Supports single or multiple IDs.

**3. Search Mode** (search parameters):
Filter models by free-text query, category, or status.

**Expansion:**
Use `expand` to include additional data in each model object:
- `openapi-3.0` — full OpenAPI 3.0 schema in the `openapi` field
- `enterprise_status` — enterprise readiness status (`ready` or `pending`) in the `enterprise_status` field

**Examples of `endpoint_id` values:**
- `fal-ai/flux/dev`
- `fal-ai/wan/v2.2-a14b/text-to-video`
- `fal-ai/minimax/video-01/image-to-video`
- `fal-ai/hunyuan3d-v21`

See [fal.ai Model APIs](https://docs.fal.ai/model-apis) for more details.

**Authentication:** Optional. Providing an API key grants higher rate limits.

**Common Use Cases:**
- Browse available models for integration
- Retrieve metadata for specific endpoints
- Search for models by category or keywords
- Get OpenAPI schemas for code generation
- Build model selection interfaces
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /models
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /models:
    get:
      tags:
        - Models
      summary: Model search
      description: >-

        Unified endpoint for discovering model endpoints. Supports three usage
        modes:


        **1. List Mode** (no parameters):

        Paginated list of all available model endpoints with minimal metadata.


        **2. Find Mode** (`endpoint_id` parameter):

        Retrieve specific model endpoint(s) by ID. Supports single or multiple
        IDs.


        **3. Search Mode** (search parameters):

        Filter models by free-text query, category, or status.


        **Expansion:**

        Use `expand` to include additional data in each model object:

        - `openapi-3.0` — full OpenAPI 3.0 schema in the `openapi` field

        - `enterprise_status` — enterprise readiness status (`ready` or
        `pending`) in the `enterprise_status` field


        **Examples of `endpoint_id` values:**

        - `fal-ai/flux/dev`

        - `fal-ai/wan/v2.2-a14b/text-to-video`

        - `fal-ai/minimax/video-01/image-to-video`

        - `fal-ai/hunyuan3d-v21`


        See [fal.ai Model APIs](https://docs.fal.ai/model-apis) for more
        details.


        **Authentication:** Optional. Providing an API key grants higher rate
        limits.


        **Common Use Cases:**

        - Browse available models for integration

        - Retrieve metadata for specific endpoints

        - Search for models by category or keywords

        - Get OpenAPI schemas for code generation

        - Build model selection interfaces
            
      operationId: getModels
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: >-
              Maximum number of items to return. Actual maximum depends on query
              type and expansion parameters.
            example: 50
          required: false
          description: >-
            Maximum number of items to return. Actual maximum depends on query
            type and expansion parameters.
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor from previous response. Encodes the page number.
            example: Mg==
          required: false
          description: Pagination cursor from previous response. Encodes the page number.
          name: cursor
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Endpoint ID(s) to retrieve (e.g., 'fal-ai/flux/dev'). Can be a
              single value or multiple values (1-50 models). When combined with
              search params, narrows results to these IDs. Use array syntax:
              ?endpoint_id=model1&endpoint_id=model2
            example:
              - fal-ai/flux/dev
              - fal-ai/flux-pro
          required: false
          description: >-
            Endpoint ID(s) to retrieve (e.g., 'fal-ai/flux/dev'). Can be a
            single value or multiple values (1-50 models). When combined with
            search params, narrows results to these IDs. Use array syntax:
            ?endpoint_id=model1&endpoint_id=model2
          name: endpoint_id
          style: form
          explode: true
          in: query
        - schema:
            type: string
            description: >-
              Free-text search query to filter models by name, description, or
              category
            example: text to image
          required: false
          description: >-
            Free-text search query to filter models by name, description, or
            category
          name: q
          in: query
        - schema:
            type: string
            description: >-
              Filter by category (e.g., 'text-to-image', 'image-to-video',
              'training')
            example: text-to-image
          required: false
          description: >-
            Filter by category (e.g., 'text-to-image', 'image-to-video',
            'training')
          name: category
          in: query
        - schema:
            type: string
            enum:
              - active
              - deprecated
            description: Filter models by status - omit to include all statuses
            example: active
          required: false
          description: Filter models by status - omit to include all statuses
          name: status
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Fields to expand in the response. Supported values: 'openapi-3.0'
              (includes full OpenAPI 3.0 schema in 'openapi' field),
              'enterprise_status' (includes enterprise readiness status)
            example:
              - openapi-3.0
              - enterprise_status
          required: false
          description: >-
            Fields to expand in the response. Supported values: 'openapi-3.0'
            (includes full OpenAPI 3.0 schema in 'openapi' field),
            'enterprise_status' (includes enterprise readiness status)
          name: expand
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Successfully retrieved model endpoints
          content:
            application/json:
              schema:
                type: object
                properties:
                  models:
                    type: array
                    items:
                      type: object
                      properties:
                        endpoint_id:
                          type: string
                          description: >-
                            Stable identifier used to call the model (e.g.,
                            'fal-ai/wan/v2.2-a14b/text-to-video',
                            'fal-ai/minimax/video-01/image-to-video',
                            'fal-ai/hunyuan3d-v21')
                        metadata:
                          type: object
                          properties:
                            display_name:
                              type: string
                              description: >-
                                Human-readable label shown on Explore/Model
                                pages
                            category:
                              type: string
                              description: >-
                                Model category (e.g., 'text-to-image',
                                'image-to-video', 'text-to-video',
                                'image-to-3d', 'training')
                            description:
                              type: string
                              description: >-
                                Brief description of the model's capabilities
                                and use cases
                            status:
                              type: string
                              enum:
                                - active
                                - deprecated
                              description: >-
                                'active' or 'deprecated'. Newest models are
                                surfaced in Explore and may be flagged as
                                'new/beta' in tags
                            tags:
                              type: array
                              items:
                                type: string
                              description: >-
                                Freeform tags such as 'new', 'beta', 'pro', or
                                'turbo' (Explore badges)
                            updated_at:
                              type: string
                              description: >-
                                ISO8601 timestamp of when the model was last
                                updated
                            is_favorited:
                              type:
                                - boolean
                                - 'null'
                              description: >-
                                Whether the model is favorited by the
                                authenticated user (null when unauthenticated)
                            thumbnail_url:
                              type: string
                              description: Main thumbnail image URL
                            thumbnail_animated_url:
                              type: string
                              description: Animated thumbnail URL (optional)
                            model_url:
                              type: string
                              description: >-
                                Full model endpoint URL (e.g.,
                                https://fal.run/...)
                            github_url:
                              type: string
                              description: License or GitHub URL (optional)
                            license_type:
                              type: string
                              enum:
                                - commercial
                                - research
                                - private
                              description: License type for the model (optional)
                            date:
                              type: string
                              description: ISO8601 timestamp of model creation
                            group:
                              type: object
                              properties:
                                key:
                                  type: string
                                  description: Group key identifier
                                label:
                                  type: string
                                  description: Human-readable group label
                              required:
                                - key
                                - label
                              description: Model group information (optional)
                            highlighted:
                              type: boolean
                              description: Whether the model is highlighted
                            kind:
                              type: string
                              enum:
                                - inference
                                - training
                              description: Model kind - inference or training (optional)
                            training_endpoint_ids:
                              type: array
                              items:
                                type: string
                              description: >-
                                Related training endpoint IDs (optional, only
                                present when non-empty, for inference models)
                            inference_endpoint_ids:
                              type: array
                              items:
                                type: string
                              description: >-
                                Related inference endpoint IDs (optional, only
                                present when non-empty, for training models)
                            stream_url:
                              type: string
                              description: Streaming endpoint URL (optional)
                            duration_estimate:
                              type: number
                              description: Estimated duration in minutes (optional)
                            pinned:
                              type: boolean
                              description: Whether the model is pinned
                          required:
                            - display_name
                            - category
                            - description
                            - status
                            - tags
                            - updated_at
                            - is_favorited
                            - thumbnail_url
                            - model_url
                            - date
                            - highlighted
                            - pinned
                          description: >-
                            Model metadata (optional - may be absent for
                            endpoints without registry entries)
                        openapi:
                          anyOf:
                            - type: object
                              properties:
                                openapi:
                                  type: string
                                  description: OpenAPI version (e.g., '3.0.4')
                              required:
                                - openapi
                              additionalProperties: {}
                              description: OpenAPI 3.0 specification for the model
                            - type: object
                              properties:
                                error:
                                  type: object
                                  properties:
                                    code:
                                      type: string
                                      description: Error code (e.g., 'expansion_failed')
                                    message:
                                      type: string
                                      description: Human-readable error message
                                  required:
                                    - code
                                    - message
                                  description: Error details for failed OpenAPI expansion
                              required:
                                - error
                              description: Error encountered while expanding OpenAPI schema
                          description: >-
                            OpenAPI 3.0 specification or error (present when
                            expand=openapi-3.0 is requested)
                        enterprise_status:
                          anyOf:
                            - type: string
                              enum:
                                - ready
                                - pending
                              description: >-
                                'ready' means approved for enterprise use,
                                'pending' means awaiting approval
                            - type: object
                              properties:
                                error:
                                  type: object
                                  properties:
                                    code:
                                      type: string
                                      description: Error code (e.g., 'expansion_failed')
                                    message:
                                      type: string
                                      description: Human-readable error message
                                  required:
                                    - code
                                    - message
                                  description: >-
                                    Error details for failed enterprise status
                                    expansion
                              required:
                                - error
                              description: >-
                                Error encountered while expanding enterprise
                                status
                          description: >-
                            Enterprise readiness status (present when
                            expand=enterprise_status is requested)
                      required:
                        - endpoint_id
                      description: >-
                        Model information with optional metadata and expandable
                        fields
                    description: Array of model information
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                required:
                  - models
                  - has_more
                description: Response containing model data with pagination support
              example:
                models:
                  - endpoint_id: fal-ai/flux/dev
                    metadata:
                      display_name: FLUX.1 [dev]
                      category: text-to-image
                      description: Fast text-to-image generation
                      status: active
                      tags:
                        - fast
                        - pro
                      updated_at: '2025-01-15T12:00:00Z'
                      is_favorited: false
                      thumbnail_url: https://fal.media/files/example.jpg
                      model_url: https://fal.run/fal-ai/flux/dev
                      date: '2024-08-01T00:00:00Z'
                      highlighted: true
                      pinned: false
                next_cursor: null
                has_more: false
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/models/analytics.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics

> 
Time-bucketed metrics per model endpoint, including request counts, success/error
rates, and latency percentiles. `prepare_duration` reflects queue/prepare
time before execution; `duration` is request execution time. Use with the
Queue/Webhooks flow to monitor SLAs.

**Metric Selection:**
You must specify which metrics to include using the `expand` query
parameter. Only requested metrics will be populated in the response,
allowing you to optimize query performance and data transfer.

**Available Metrics:**
- `request_count`: Total number of requests in the time bucket
- `success_count`: Number of successful requests (2xx responses)
- `user_error_count`: Number of user errors (4xx responses)
- `error_count`: Number of server errors (5xx responses)
- `p50_prepare_duration`: 50th percentile queue/prepare time
- `p75_prepare_duration`: 75th percentile queue/prepare time
- `p90_prepare_duration`: 90th percentile queue/prepare time
- `p50_duration`: 50th percentile request execution duration
- `p75_duration`: 75th percentile request execution duration
- `p90_duration`: 90th percentile request execution duration

**Key Features:**
- Selective metric inclusion via expand parameter
- Performance metrics (latency percentiles, duration stats)
- Reliability metrics (success/error rates, request counts)
- Time-bucketed data for trend analysis
- Single or multi-model analytics
- Flexible date range and timeframe options

**Common Use Cases:**
- Monitor model performance and reliability
- Generate performance dashboards
- Analyze latency trends and patterns
- Track error rates and success metrics

See [Queue API docs](https://docs.fal.ai/model-apis/model-endpoints/queue) for more details.
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /models/analytics
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /models/analytics:
    get:
      tags:
        - Models
        - Analytics
      summary: Analytics
      description: >-

        Time-bucketed metrics per model endpoint, including request counts,
        success/error

        rates, and latency percentiles. `prepare_duration` reflects
        queue/prepare

        time before execution; `duration` is request execution time. Use with
        the

        Queue/Webhooks flow to monitor SLAs.


        **Metric Selection:**

        You must specify which metrics to include using the `expand` query

        parameter. Only requested metrics will be populated in the response,

        allowing you to optimize query performance and data transfer.


        **Available Metrics:**

        - `request_count`: Total number of requests in the time bucket

        - `success_count`: Number of successful requests (2xx responses)

        - `user_error_count`: Number of user errors (4xx responses)

        - `error_count`: Number of server errors (5xx responses)

        - `p50_prepare_duration`: 50th percentile queue/prepare time

        - `p75_prepare_duration`: 75th percentile queue/prepare time

        - `p90_prepare_duration`: 90th percentile queue/prepare time

        - `p50_duration`: 50th percentile request execution duration

        - `p75_duration`: 75th percentile request execution duration

        - `p90_duration`: 90th percentile request execution duration


        **Key Features:**

        - Selective metric inclusion via expand parameter

        - Performance metrics (latency percentiles, duration stats)

        - Reliability metrics (success/error rates, request counts)

        - Time-bucketed data for trend analysis

        - Single or multi-model analytics

        - Flexible date range and timeframe options


        **Common Use Cases:**

        - Monitor model performance and reliability

        - Generate performance dashboards

        - Analyze latency trends and patterns

        - Track error rates and success metrics


        See [Queue API
        docs](https://docs.fal.ai/model-apis/model-endpoints/queue) for more
        details.
            
      operationId: getAnalytics
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: >-
              Maximum number of items to return. Actual maximum depends on query
              type and expansion parameters.
            example: 50
          required: false
          description: >-
            Maximum number of items to return. Actual maximum depends on query
            type and expansion parameters.
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor from previous response. Encodes the page number.
            example: Mg==
          required: false
          description: Pagination cursor from previous response. Encodes the page number.
          name: cursor
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            type: string
            default: UTC
            description: >-
              Timezone for date aggregation and boundaries. All timestamps in
              responses are in UTC, but this controls how dates are bucketed.
            example: UTC
          required: false
          description: >-
            Timezone for date aggregation and boundaries. All timestamps in
            responses are in UTC, but this controls how dates are bucketed.
          name: timezone
          in: query
        - schema:
            type: string
            enum:
              - minute
              - hour
              - day
              - week
              - month
            description: >-
              Aggregation timeframe for timeseries data (auto-detected from date
              range if not specified). Auto-detection uses: minute (<2h), hour
              (<2d), day (<64d), week (<183d), month (>=183d).
            example: day
          required: false
          description: >-
            Aggregation timeframe for timeseries data (auto-detected from date
            range if not specified). Auto-detection uses: minute (<2h), hour
            (<2d), day (<64d), week (<183d), month (>=183d).
          name: timeframe
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'true'
            description: >-
              Whether to adjust start/end dates to align with timeframe
              boundaries and use exclusive end. Defaults to true. When true,
              dates are aligned to the start of the timeframe period (e.g.,
              start of day) and end is made exclusive (e.g., start of next day).
              When false, uses exact dates provided.
            example: 'true'
          required: false
          description: >-
            Whether to adjust start/end dates to align with timeframe boundaries
            and use exclusive end. Defaults to true. When true, dates are
            aligned to the start of the timeframe period (e.g., start of day)
            and end is made exclusive (e.g., start of next day). When false,
            uses exact dates provided.
          name: bound_to_timeframe
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
              Supports comma-separated values: ?endpoint_id=model1,model2 or
              array syntax: ?endpoint_id=model1&endpoint_id=model2
            example:
              - fal-ai/flux/dev
          required: true
          description: >-
            Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
            Supports comma-separated values: ?endpoint_id=model1,model2 or array
            syntax: ?endpoint_id=model1&endpoint_id=model2
          name: endpoint_id
          style: form
          explode: true
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            default:
              - time_series
              - request_count
            description: >-
              Data and metrics to include in the response. Use 'time_series' for
              time-bucketed data, metric names for specific metrics in time
              series, and 'summary' for aggregate statistics. At least one of
              'time_series' or 'summary' and at least one metric are required.
            example:
              - request_count
              - success_count
          required: false
          description: >-
            Data and metrics to include in the response. Use 'time_series' for
            time-bucketed data, metric names for specific metrics in time
            series, and 'summary' for aggregate statistics. At least one of
            'time_series' or 'summary' and at least one metric are required.
          name: expand
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Analytics data retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  time_series:
                    type: array
                    items:
                      type: object
                      properties:
                        bucket:
                          type: string
                          description: >-
                            Time bucket timestamp in user's timezone with offset
                            (ISO8601 datetime)
                        results:
                          type: array
                          items:
                            type: object
                            properties:
                              endpoint_id:
                                type: string
                                description: Endpoint identifier for these statistics
                              request_count:
                                type: integer
                                minimum: 0
                                description: Total number of requests
                              success_count:
                                type: integer
                                minimum: 0
                                description: Number of successful requests (2xx responses)
                              user_error_count:
                                type: integer
                                minimum: 0
                                description: Number of user errors (4xx responses)
                              error_count:
                                type: integer
                                minimum: 0
                                description: Number of server errors (5xx responses)
                              p50_prepare_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  50th percentile queue/prepare time before
                                  execution in seconds
                              p75_prepare_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  75th percentile queue/prepare time before
                                  execution in seconds
                              p90_prepare_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  90th percentile queue/prepare time before
                                  execution in seconds
                              p50_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  50th percentile request execution duration in
                                  seconds
                              p75_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  75th percentile request execution duration in
                                  seconds
                              p90_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  90th percentile request execution duration in
                                  seconds
                            required:
                              - endpoint_id
                            description: >-
                              Performance and reliability analytics. Only
                              requested metrics (via expand parameter) will be
                              present in the response. 'prepare_duration'
                              reflects queue/prepare time before execution;
                              'duration' is request execution time.
                          description: Analytics records for this time bucket
                      required:
                        - bucket
                        - results
                      description: Time bucket with grouped analytics records
                    description: >-
                      Time series analytics data grouped by time bucket (when
                      expand includes 'time_series'). Each bucket contains all
                      analytics records for that time period.
                  summary:
                    type: array
                    items:
                      type: object
                      properties:
                        endpoint_id:
                          type: string
                          description: Endpoint identifier for these statistics
                        request_count:
                          type: integer
                          minimum: 0
                          description: Total number of requests
                        success_count:
                          type: integer
                          minimum: 0
                          description: Number of successful requests (2xx responses)
                        user_error_count:
                          type: integer
                          minimum: 0
                          description: Number of user errors (4xx responses)
                        error_count:
                          type: integer
                          minimum: 0
                          description: Number of server errors (5xx responses)
                        p50_prepare_duration:
                          type: number
                          minimum: 0
                          description: >-
                            50th percentile queue/prepare time before execution
                            in seconds
                        p75_prepare_duration:
                          type: number
                          minimum: 0
                          description: >-
                            75th percentile queue/prepare time before execution
                            in seconds
                        p90_prepare_duration:
                          type: number
                          minimum: 0
                          description: >-
                            90th percentile queue/prepare time before execution
                            in seconds
                        p50_duration:
                          type: number
                          minimum: 0
                          description: >-
                            50th percentile request execution duration in
                            seconds
                        p75_duration:
                          type: number
                          minimum: 0
                          description: >-
                            75th percentile request execution duration in
                            seconds
                        p90_duration:
                          type: number
                          minimum: 0
                          description: >-
                            90th percentile request execution duration in
                            seconds
                      required:
                        - endpoint_id
                      description: >-
                        Aggregate performance statistics for the entire date
                        range
                    description: Aggregate statistics (when expand includes 'summary')
                required:
                  - next_cursor
                  - has_more
                description: >-
                  Response containing performance analytics with pagination
                  support
              example:
                time_series:
                  - bucket: '2025-01-15T12:00:00-05:00'
                    results:
                      - endpoint_id: fal-ai/flux/dev
                        request_count: 1500
                        success_count: 1450
                        p50_duration: 2.5
                        p90_duration: 4.8
                next_cursor: null
                has_more: false
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/models/pricing.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pricing

> 
Returns unit pricing for requested endpoint IDs. Most models use
**output-based** pricing (e.g., per image/video with proportional
adjustments for resolution/length). Some models use **GPU-based** pricing
depending on architecture. Values are expressed per model's billing unit
in a given currency.

**Authentication:** Required. Users must provide a valid API key. 
Custom pricing or discounts may be applied based on account status.

**Common Use Cases:**
- Display pricing in user interfaces
- Compare pricing across different models
- Build cost estimation tools
- Check current billing rates

See [fal.ai pricing](https://fal.ai/pricing) for more details.
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /models/pricing
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /models/pricing:
    get:
      tags:
        - Models
        - Pricing
      summary: Pricing
      description: >-

        Returns unit pricing for requested endpoint IDs. Most models use

        **output-based** pricing (e.g., per image/video with proportional

        adjustments for resolution/length). Some models use **GPU-based**
        pricing

        depending on architecture. Values are expressed per model's billing unit

        in a given currency.


        **Authentication:** Required. Users must provide a valid API key. 

        Custom pricing or discounts may be applied based on account status.


        **Common Use Cases:**

        - Display pricing in user interfaces

        - Compare pricing across different models

        - Build cost estimation tools

        - Check current billing rates


        See [fal.ai pricing](https://fal.ai/pricing) for more details.
            
      operationId: getPricing
      parameters:
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
              Supports comma-separated values: ?endpoint_id=model1,model2 or
              array syntax: ?endpoint_id=model1&endpoint_id=model2
            example:
              - fal-ai/flux/dev
          required: true
          description: >-
            Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
            Supports comma-separated values: ?endpoint_id=model1,model2 or array
            syntax: ?endpoint_id=model1&endpoint_id=model2
          name: endpoint_id
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Pricing information retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  prices:
                    type: array
                    items:
                      type: object
                      properties:
                        endpoint_id:
                          type: string
                          description: >-
                            Endpoint identifier (e.g.,
                            'fal-ai/wan/v2.2-a14b/text-to-video',
                            'fal-ai/minimax/video-01/image-to-video')
                        unit_price:
                          type: number
                          minimum: 0
                          description: >-
                            Base price per billing unit (often per generated
                            output; may be per GPU-second for some models) in
                            the specified currency
                        unit:
                          type: string
                          description: >-
                            Unit of measurement for billing: 'image', 'video',
                            or provider-specific GPU/compute unit when
                            applicable. Most models use output-based pricing.
                        currency:
                          type: string
                          minLength: 3
                          maxLength: 3
                          description: Three-letter currency code (ISO 4217, e.g., 'USD')
                      required:
                        - endpoint_id
                        - unit_price
                        - unit
                        - currency
                      description: >-
                        Pricing information for a specific model endpoint. Most
                        models use output-based pricing (e.g., per image/video
                        with proportional adjustments for resolution/length).
                        Some models use GPU-based pricing depending on
                        architecture.
                    description: Pricing information for requested endpoints
                required:
                  - next_cursor
                  - has_more
                  - prices
                description: >-
                  Response containing pricing information for requested
                  endpoints
              example:
                prices:
                  - endpoint_id: fal-ai/flux/dev
                    unit_price: 0.025
                    unit: image
                    currency: USD
                next_cursor: null
                has_more: false
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/models/pricing/estimate.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Estimate cost

> 
Computes cost estimates using one of two methods:

**1. Historical API Price** (`historical_api_price`):
- Based on historical pricing per API call from past usage patterns
- Takes `call_quantity` (number of API calls) per endpoint
- Useful for estimating based on actual historical usage patterns
- Example: "How much will 100 calls to flux/dev cost?"

**2. Unit Price** (`unit_price`):
- Based on unit price × expected billing units from pricing service
- Takes `unit_quantity` (number of billing units like images/videos) per endpoint
- Useful when you know the expected output quantity
- Example: "How much will 50 images from flux/dev cost?"

**Authentication:** Required. Users must provide a valid API key.
Custom pricing or discounts may be applied based on account status.

**Common Use Cases:**
- Pre-calculate costs for batch operations
- Display cost estimates in user interfaces
- Budget planning and cost optimization

See [fal.ai pricing](https://fal.ai/pricing) for more details.
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json post /models/pricing/estimate
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /models/pricing/estimate:
    post:
      tags:
        - Models
        - Pricing
      summary: Estimate cost
      description: >-

        Computes cost estimates using one of two methods:


        **1. Historical API Price** (`historical_api_price`):

        - Based on historical pricing per API call from past usage patterns

        - Takes `call_quantity` (number of API calls) per endpoint

        - Useful for estimating based on actual historical usage patterns

        - Example: "How much will 100 calls to flux/dev cost?"


        **2. Unit Price** (`unit_price`):

        - Based on unit price × expected billing units from pricing service

        - Takes `unit_quantity` (number of billing units like images/videos) per
        endpoint

        - Useful when you know the expected output quantity

        - Example: "How much will 50 images from flux/dev cost?"


        **Authentication:** Required. Users must provide a valid API key.

        Custom pricing or discounts may be applied based on account status.


        **Common Use Cases:**

        - Pre-calculate costs for batch operations

        - Display cost estimates in user interfaces

        - Budget planning and cost optimization


        See [fal.ai pricing](https://fal.ai/pricing) for more details.
            
      operationId: estimatePricing
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  properties:
                    estimate_type:
                      type: string
                      enum:
                        - historical_api_price
                      description: >-
                        Estimate type: historical API pricing based on past
                        usage patterns
                    endpoints:
                      type: object
                      additionalProperties:
                        type: object
                        properties:
                          call_quantity:
                            type: integer
                            minimum: 1
                            description: >-
                              Number of API calls to estimate (regardless of
                              units per call)
                        required:
                          - call_quantity
                      description: Map of endpoint IDs to call quantities
                  required:
                    - estimate_type
                    - endpoints
                  description: >-
                    Historical API price estimate: Calculates cost based on
                    historical pricing per API call. Useful for estimating costs
                    based on actual usage patterns.
                - type: object
                  properties:
                    estimate_type:
                      type: string
                      enum:
                        - unit_price
                      description: >-
                        Estimate type: unit price calculation based on billing
                        units
                    endpoints:
                      type: object
                      additionalProperties:
                        type: object
                        properties:
                          unit_quantity:
                            type: number
                            minimum: 0.000001
                            description: >-
                              Number of billing units expected (e.g., number of
                              images, videos, etc.)
                        required:
                          - unit_quantity
                      description: Map of endpoint IDs to unit quantities
                  required:
                    - estimate_type
                    - endpoints
                  description: >-
                    Unit price estimate: Calculates cost based on unit price ×
                    billing units. Useful for estimating costs when you know the
                    expected output quantity.
              example:
                estimate_type: historical_api_price
                endpoints:
                  fal-ai/flux/dev:
                    call_quantity: 100
                  fal-ai/flux/schnell:
                    call_quantity: 50
            examples:
              historical:
                value:
                  estimate_type: historical_api_price
                  endpoints:
                    fal-ai/flux/dev:
                      call_quantity: 100
                    fal-ai/flux/schnell:
                      call_quantity: 50
                summary: Historical API price estimate
              unit_price:
                value:
                  estimate_type: unit_price
                  endpoints:
                    fal-ai/flux/dev:
                      unit_quantity: 50
                    fal-ai/flux-pro:
                      unit_quantity: 25
                summary: Unit price estimate
      responses:
        '200':
          description: Cost estimates calculated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  estimate_type:
                    type: string
                    enum:
                      - historical_api_price
                      - unit_price
                    description: The type of estimate that was performed
                  total_cost:
                    type: number
                    minimum: 0
                    description: Total estimated cost across all endpoints
                  currency:
                    type: string
                    minLength: 3
                    maxLength: 3
                    description: Three-letter currency code (ISO 4217, e.g., 'USD')
                required:
                  - estimate_type
                  - total_cost
                  - currency
                description: Cost estimation response with total cost
                example:
                  estimate_type: historical_api_price
                  total_cost: 3.75
                  currency: USD
              examples:
                historical:
                  value:
                    estimate_type: historical_api_price
                    total_cost: 3.75
                    currency: USD
                  summary: Historical API price estimate result
                unit_price:
                  value:
                    estimate_type: unit_price
                    total_cost: 1.88
                    currency: USD
                  summary: Unit price estimate result
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/models/requests/by-endpoint.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List requests by endpoint

> Lists requests for a specific endpoint.

**Authentication:** Requires API key (user or enterprise).

**Filters:**
- Time range via start / end
- Status (success, error, user_error)
- Request ID
- Pagination via cursor/limit (limit defaults to 50, max 100)

**Sorting:**
- By end time (default) or duration

**Expansions:**
- Include payloads by adding expand=payloads



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /models/requests/by-endpoint
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /models/requests/by-endpoint:
    get:
      tags:
        - Models
        - Requests
      summary: List requests by endpoint
      description: |-
        Lists requests for a specific endpoint.

        **Authentication:** Requires API key (user or enterprise).

        **Filters:**
        - Time range via start / end
        - Status (success, error, user_error)
        - Request ID
        - Pagination via cursor/limit (limit defaults to 50, max 100)

        **Sorting:**
        - By end time (default) or duration

        **Expansions:**
        - Include payloads by adding expand=payloads
      operationId: listRequestsByEndpoint
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
            description: Number of items to return per page (max 100)
            example: 20
          required: false
          description: Number of items to return per page (max 100)
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor encoding the page number
            example: Mg==
          required: false
          description: Pagination cursor encoding the page number
          name: cursor
          in: query
        - schema:
            type: string
            description: Endpoint identifier to filter requests by
            example: fal-ai/flux/dev
          required: true
          description: Endpoint identifier to filter requests by
          name: endpoint_id
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            type: string
            enum:
              - success
              - error
              - user_error
            description: Filter by request status
            example: success
          required: false
          description: Filter by request status
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filter by specific request ID
            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
          required: false
          description: Filter by specific request ID
          name: request_id
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Fields to expand in the response. Use payloads to include input
              and output payloads.
            example:
              - payloads
          required: false
          description: >-
            Fields to expand in the response. Use payloads to include input and
            output payloads.
          name: expand
          style: form
          explode: true
          in: query
        - schema:
            type: string
            enum:
              - ended_at
              - duration
            default: ended_at
            description: Sort results by end time or duration
            example: ended_at
          required: false
          description: Sort results by end time or duration
          name: sort_by
          in: query
      responses:
        '200':
          description: Requests listed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        request_id:
                          type: string
                          format: uuid
                          description: Unique identifier for the request
                          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        endpoint_id:
                          type: string
                          description: Endpoint that was executed for this request
                          example: fal-ai/flux/dev
                        started_at:
                          type: string
                          format: date-time
                          description: Time when request processing started
                          example: '2025-01-01T00:00:05Z'
                        sent_at:
                          type: string
                          format: date-time
                          description: Time when request was sent to the backend
                          example: '2025-01-01T00:00:01Z'
                        ended_at:
                          type:
                            - string
                            - 'null'
                          format: date-time
                          description: Time when request finished processing
                          example: '2025-01-01T00:00:08Z'
                        status_code:
                          type:
                            - integer
                            - 'null'
                          description: HTTP status code returned by the request
                          example: 200
                        duration:
                          type:
                            - number
                            - 'null'
                          description: Total request duration in seconds
                          example: 7.8
                        json_input:
                          description: Input payload for the request
                        json_output:
                          description: Output payload for the request
                      required:
                        - request_id
                        - endpoint_id
                        - started_at
                        - sent_at
                      description: Request item
                    description: List of requests matching the filter
                required:
                  - next_cursor
                  - has_more
                  - items
                description: Paginated list of requests for the specified endpoint
              example:
                items:
                  - request_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    endpoint_id: fal-ai/flux/dev
                    started_at: '2025-01-01T00:00:05Z'
                    sent_at: '2025-01-01T00:00:01Z'
                    ended_at: '2025-01-01T00:00:08Z'
                    status_code: 200
                    duration: 7.8
                    json_input:
                      prompt: cat astronaut
                    json_output:
                      status: ok
                next_cursor: Mg==
                has_more: true
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/models/requests/payloads.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Delete request payloads

> Deletes the IO payloads and associated CDN output files for a specific request.

**Important:**
- Only **output** CDN files are deleted (input files may be used by other requests)
- This action is irreversible
- Requires authentication with an admin API key

**What gets deleted:**
- Request input/output payload data
- CDN-hosted output files (images, videos, etc.)

**What is NOT deleted:**
- Input CDN files (may be referenced by other requests)

**Response:**
- Returns deletion status for each CDN file
- Each result includes the file link and any error that occurred

**Idempotency:**
- Optional Idempotency-Key header prevents duplicate deletions on retries
- Responses cached for 10 minutes per unique key

See [fal.ai docs](https://docs.fal.ai/model-apis/payloads) for more details about request payloads.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json delete /models/requests/{request_id}/payloads
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /models/requests/{request_id}/payloads:
    delete:
      tags:
        - Models
        - Requests
      summary: Delete request payloads
      description: >-
        Deletes the IO payloads and associated CDN output files for a specific
        request.


        **Important:**

        - Only **output** CDN files are deleted (input files may be used by
        other requests)

        - This action is irreversible

        - Requires authentication with an admin API key


        **What gets deleted:**

        - Request input/output payload data

        - CDN-hosted output files (images, videos, etc.)


        **What is NOT deleted:**

        - Input CDN files (may be referenced by other requests)


        **Response:**

        - Returns deletion status for each CDN file

        - Each result includes the file link and any error that occurred


        **Idempotency:**

        - Optional Idempotency-Key header prevents duplicate deletions on
        retries

        - Responses cached for 10 minutes per unique key


        See [fal.ai docs](https://docs.fal.ai/model-apis/payloads) for more
        details about request payloads.
      operationId: deleteRequestPayloads
      parameters:
        - schema:
            type: string
            format: uuid
            description: Unique identifier for the request (UUID format)
            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
          required: true
          description: Unique identifier for the request (UUID format)
          name: request_id
          in: path
        - schema:
            type: string
            description: Optional idempotency key for safe request retries
            example: 550e8400-e29b-41d4-a716-446655440000
          required: false
          description: Optional idempotency key for safe request retries
          name: Idempotency-Key
          in: header
      responses:
        '200':
          description: Request payloads deleted successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  cdn_delete_results:
                    type: array
                    items:
                      type: object
                      properties:
                        link:
                          type: string
                          description: CDN URL of the file that was targeted for deletion
                          example: https://v3.fal.media/files/example/output.png
                        exception:
                          type:
                            - string
                            - 'null'
                          description: >-
                            Error message if deletion failed for this file, null
                            if successful
                          example: null
                      required:
                        - link
                        - exception
                      description: Result of deleting a single CDN file
                    description: >-
                      Array of deletion results for each CDN file associated
                      with the request output
                required:
                  - cdn_delete_results
                description: >-
                  Response containing the results of deleting request payloads
                  and CDN output files
              example:
                cdn_delete_results:
                  - link: https://v3.fal.media/files/abc123/output.png
                    exception: null
                  - link: https://v3.fal.media/files/def456/output.mp4
                    exception: null
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/models/usage.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage

> 
Returns paginated usage records for your workspace with filters for endpoint,
user, date range, and auth method. Each item includes the billed unit
quantity and unit price used to compute cost.

**Key Features:**
- Usage data for all endpoints or filtered by specific endpoint(s)
- Flexible date range filtering
- User-specific usage tracking
- Detailed usage line items with unit quantity and price
- Paginated results for large datasets

**Common Use Cases:**
- Generate usage reports for all endpoints or specific models
- Track usage patterns
- Monitor endpoint usage across different auth methods
- Build usage dashboards and visualizations

See [fal.ai docs](https://docs.fal.ai/model-apis/faq) for more details.
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /models/usage
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /models/usage:
    get:
      tags:
        - Models
        - Usage
      summary: Usage
      description: >-

        Returns paginated usage records for your workspace with filters for
        endpoint,

        user, date range, and auth method. Each item includes the billed unit

        quantity and unit price used to compute cost.


        **Key Features:**

        - Usage data for all endpoints or filtered by specific endpoint(s)

        - Flexible date range filtering

        - User-specific usage tracking

        - Detailed usage line items with unit quantity and price

        - Paginated results for large datasets


        **Common Use Cases:**

        - Generate usage reports for all endpoints or specific models

        - Track usage patterns

        - Monitor endpoint usage across different auth methods

        - Build usage dashboards and visualizations


        See [fal.ai docs](https://docs.fal.ai/model-apis/faq) for more details.
            
      operationId: getUsage
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: >-
              Maximum number of items to return. Actual maximum depends on query
              type and expansion parameters.
            example: 50
          required: false
          description: >-
            Maximum number of items to return. Actual maximum depends on query
            type and expansion parameters.
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor from previous response. Encodes the page number.
            example: Mg==
          required: false
          description: Pagination cursor from previous response. Encodes the page number.
          name: cursor
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            type: string
            default: UTC
            description: >-
              Timezone for date aggregation and boundaries. All timestamps in
              responses are in UTC, but this controls how dates are bucketed.
            example: UTC
          required: false
          description: >-
            Timezone for date aggregation and boundaries. All timestamps in
            responses are in UTC, but this controls how dates are bucketed.
          name: timezone
          in: query
        - schema:
            type: string
            enum:
              - minute
              - hour
              - day
              - week
              - month
            description: >-
              Aggregation timeframe for timeseries data (auto-detected from date
              range if not specified). Auto-detection uses: minute (<2h), hour
              (<2d), day (<64d), week (<183d), month (>=183d).
            example: day
          required: false
          description: >-
            Aggregation timeframe for timeseries data (auto-detected from date
            range if not specified). Auto-detection uses: minute (<2h), hour
            (<2d), day (<64d), week (<183d), month (>=183d).
          name: timeframe
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'true'
            description: >-
              Whether to adjust start/end dates to align with timeframe
              boundaries and use exclusive end. Defaults to true. When true,
              dates are aligned to the start of the timeframe period (e.g.,
              start of day) and end is made exclusive (e.g., start of next day).
              When false, uses exact dates provided.
            example: 'true'
          required: false
          description: >-
            Whether to adjust start/end dates to align with timeframe boundaries
            and use exclusive end. Defaults to true. When true, dates are
            aligned to the start of the timeframe period (e.g., start of day)
            and end is made exclusive (e.g., start of next day). When false,
            uses exact dates provided.
          name: bound_to_timeframe
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
              Supports comma-separated values: ?endpoint_id=model1,model2 or
              array syntax: ?endpoint_id=model1&endpoint_id=model2
            example:
              - fal-ai/flux/dev
          required: false
          description: >-
            Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
            Supports comma-separated values: ?endpoint_id=model1,model2 or array
            syntax: ?endpoint_id=model1&endpoint_id=model2
          name: endpoint_id
          style: form
          explode: true
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            default:
              - time_series
            description: >-
              Data to include in the response. Use 'time_series' for
              time-bucketed data, 'summary' for aggregate statistics, and
              'auth_method' to include authentication method information
              (formatted with user key aliases). At least one of 'time_series'
              or 'summary' is required.
            example:
              - time_series
              - auth_method
          required: false
          description: >-
            Data to include in the response. Use 'time_series' for time-bucketed
            data, 'summary' for aggregate statistics, and 'auth_method' to
            include authentication method information (formatted with user key
            aliases). At least one of 'time_series' or 'summary' is required.
          name: expand
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Usage data retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  time_series:
                    type: array
                    items:
                      type: object
                      properties:
                        bucket:
                          type: string
                          description: >-
                            Time bucket timestamp in user's timezone with offset
                            (ISO8601 datetime)
                        results:
                          type: array
                          items:
                            type: object
                            properties:
                              endpoint_id:
                                type: string
                                description: >-
                                  Endpoint identifier that was used (e.g.,
                                  'fal-ai/flux/dev')
                              unit:
                                type: string
                                description: >-
                                  The billing unit (e.g., 'image', 'video', or a
                                  GPU/compute unit for some models)
                              quantity:
                                type: number
                                minimum: 0
                                description: >-
                                  Quantity of usage in the specified billing
                                  unit
                              unit_price:
                                type: number
                                minimum: 0
                                description: >-
                                  Unit price used to compute charges for this
                                  line item
                              cost:
                                type: number
                                minimum: 0
                                description: Computed cost (quantity × unit_price)
                              currency:
                                type: string
                                minLength: 3
                                maxLength: 3
                                description: >-
                                  Three-letter currency code (ISO 4217, e.g.,
                                  'USD')
                              auth_method:
                                type: string
                                description: >-
                                  Authentication method label (e.g., 'Key 1',
                                  'Key 2', 'User token'). Only populated when
                                  'auth_method' is included in expand parameter.
                            required:
                              - endpoint_id
                              - unit
                              - quantity
                              - unit_price
                              - cost
                              - currency
                            description: Usage line item with billing details
                          description: Usage records for this time bucket
                      required:
                        - bucket
                        - results
                      description: Time bucket with grouped usage records
                    description: >-
                      Time series usage data grouped by time bucket (when expand
                      includes 'time_series'). Each bucket contains all usage
                      records for that time period.
                  summary:
                    type: array
                    items:
                      type: object
                      properties:
                        endpoint_id:
                          type: string
                          description: >-
                            Endpoint identifier that was used (e.g.,
                            'fal-ai/flux/dev')
                        unit:
                          type: string
                          description: >-
                            The billing unit (e.g., 'image', 'video', or a
                            GPU/compute unit for some models)
                        quantity:
                          type: number
                          minimum: 0
                          description: Quantity of usage in the specified billing unit
                        unit_price:
                          type: number
                          minimum: 0
                          description: >-
                            Unit price used to compute charges for this line
                            item
                        cost:
                          type: number
                          minimum: 0
                          description: Computed cost (quantity × unit_price)
                        currency:
                          type: string
                          minLength: 3
                          maxLength: 3
                          description: Three-letter currency code (ISO 4217, e.g., 'USD')
                        auth_method:
                          type: string
                          description: >-
                            Authentication method label (e.g., 'Key 1', 'Key 2',
                            'User token'). Only populated when 'auth_method' is
                            included in expand parameter.
                      required:
                        - endpoint_id
                        - unit
                        - quantity
                        - unit_price
                        - cost
                        - currency
                      description: Aggregate usage statistics for the entire date range
                    description: Aggregate statistics (when expand includes 'summary')
                required:
                  - next_cursor
                  - has_more
                description: Response containing usage data with pagination support
              example:
                time_series:
                  - bucket: '2025-01-15T00:00:00-05:00'
                    results:
                      - endpoint_id: fal-ai/flux/dev
                        unit: image
                        quantity: 4
                        unit_price: 0.1
                        cost: 0.4
                        currency: USD
                        auth_method: Production Key
                next_cursor: null
                has_more: false
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
      security:
        - adminApiKey: []
components:
  securitySchemes:
    adminApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Admin API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_ADMIN_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/analytics.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics

> 
Time-bucketed metrics for your serverless app endpoints, including request counts,
success/error rates, and latency percentiles across all inbound traffic.
`prepare_duration` reflects queue/prepare time before execution;
`duration` is request execution time.

This endpoint shows all inbound requests to endpoints you own — not just
your own calls. This is ideal for monitoring your deployed apps, tracking
SLAs, and exporting data to tools like BigQuery or Grafana. You must own
all requested endpoints; returns 403 otherwise.

> **Note:** This endpoint returns analytics across **all callers** of your endpoints.
> If you only need analytics for requests **you made** to a model endpoint,
> use [`GET /v1/models/analytics`](/platform-apis/v1/models/analytics) instead.

**Metric Selection:**
You must specify which metrics to include using the `expand` query
parameter. Only requested metrics will be populated in the response,
allowing you to optimize query performance and data transfer.

**Available Metrics:**
- `request_count`: Total number of requests in the time bucket
- `success_count`: Number of successful requests (2xx responses)
- `user_error_count`: Number of user errors (4xx responses)
- `error_count`: Number of server errors (5xx responses)
- `p50_prepare_duration`: 50th percentile queue/prepare time
- `p75_prepare_duration`: 75th percentile queue/prepare time
- `p90_prepare_duration`: 90th percentile queue/prepare time
- `p50_duration`: 50th percentile request execution duration
- `p75_duration`: 75th percentile request execution duration
- `p90_duration`: 90th percentile request execution duration

**Key Features:**
- See all traffic to your apps across all callers
- Selective metric inclusion via expand parameter
- Performance metrics (latency percentiles, duration stats)
- Reliability metrics (success/error rates, request counts)
- Time-bucketed data for trend analysis
- Flexible date range and timeframe options

**Common Use Cases:**
- Monitor your serverless app performance and reliability
- Export analytics to your own observability tools
- Analyze latency trends across all callers
- Track error rates and SLA compliance
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /serverless/analytics
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/analytics:
    get:
      tags:
        - Serverless
        - Analytics
      summary: Analytics
      description: >-

        Time-bucketed metrics for your serverless app endpoints, including
        request counts,

        success/error rates, and latency percentiles across all inbound traffic.

        `prepare_duration` reflects queue/prepare time before execution;

        `duration` is request execution time.


        This endpoint shows all inbound requests to endpoints you own — not just

        your own calls. This is ideal for monitoring your deployed apps,
        tracking

        SLAs, and exporting data to tools like BigQuery or Grafana. You must own

        all requested endpoints; returns 403 otherwise.


        > **Note:** This endpoint returns analytics across **all callers** of
        your endpoints.

        > If you only need analytics for requests **you made** to a model
        endpoint,

        > use [`GET /v1/models/analytics`](/platform-apis/v1/models/analytics)
        instead.


        **Metric Selection:**

        You must specify which metrics to include using the `expand` query

        parameter. Only requested metrics will be populated in the response,

        allowing you to optimize query performance and data transfer.


        **Available Metrics:**

        - `request_count`: Total number of requests in the time bucket

        - `success_count`: Number of successful requests (2xx responses)

        - `user_error_count`: Number of user errors (4xx responses)

        - `error_count`: Number of server errors (5xx responses)

        - `p50_prepare_duration`: 50th percentile queue/prepare time

        - `p75_prepare_duration`: 75th percentile queue/prepare time

        - `p90_prepare_duration`: 90th percentile queue/prepare time

        - `p50_duration`: 50th percentile request execution duration

        - `p75_duration`: 75th percentile request execution duration

        - `p90_duration`: 90th percentile request execution duration


        **Key Features:**

        - See all traffic to your apps across all callers

        - Selective metric inclusion via expand parameter

        - Performance metrics (latency percentiles, duration stats)

        - Reliability metrics (success/error rates, request counts)

        - Time-bucketed data for trend analysis

        - Flexible date range and timeframe options


        **Common Use Cases:**

        - Monitor your serverless app performance and reliability

        - Export analytics to your own observability tools

        - Analyze latency trends across all callers

        - Track error rates and SLA compliance
            
      operationId: serverlessGetAnalytics
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: >-
              Maximum number of items to return. Actual maximum depends on query
              type and expansion parameters.
            example: 50
          required: false
          description: >-
            Maximum number of items to return. Actual maximum depends on query
            type and expansion parameters.
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor from previous response. Encodes the page number.
            example: Mg==
          required: false
          description: Pagination cursor from previous response. Encodes the page number.
          name: cursor
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            type: string
            default: UTC
            description: >-
              Timezone for date aggregation and boundaries. All timestamps in
              responses are in UTC, but this controls how dates are bucketed.
            example: UTC
          required: false
          description: >-
            Timezone for date aggregation and boundaries. All timestamps in
            responses are in UTC, but this controls how dates are bucketed.
          name: timezone
          in: query
        - schema:
            type: string
            enum:
              - minute
              - hour
              - day
              - week
              - month
            description: >-
              Aggregation timeframe for timeseries data (auto-detected from date
              range if not specified). Auto-detection uses: minute (<2h), hour
              (<2d), day (<64d), week (<183d), month (>=183d).
            example: day
          required: false
          description: >-
            Aggregation timeframe for timeseries data (auto-detected from date
            range if not specified). Auto-detection uses: minute (<2h), hour
            (<2d), day (<64d), week (<183d), month (>=183d).
          name: timeframe
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'true'
            description: >-
              Whether to adjust start/end dates to align with timeframe
              boundaries and use exclusive end. Defaults to true. When true,
              dates are aligned to the start of the timeframe period (e.g.,
              start of day) and end is made exclusive (e.g., start of next day).
              When false, uses exact dates provided.
            example: 'true'
          required: false
          description: >-
            Whether to adjust start/end dates to align with timeframe boundaries
            and use exclusive end. Defaults to true. When true, dates are
            aligned to the start of the timeframe period (e.g., start of day)
            and end is made exclusive (e.g., start of next day). When false,
            uses exact dates provided.
          name: bound_to_timeframe
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
              Supports comma-separated values: ?endpoint_id=model1,model2 or
              array syntax: ?endpoint_id=model1&endpoint_id=model2
            example:
              - fal-ai/flux/dev
          required: true
          description: >-
            Filter by specific endpoint ID(s). Accepts 1-50 endpoint IDs.
            Supports comma-separated values: ?endpoint_id=model1,model2 or array
            syntax: ?endpoint_id=model1&endpoint_id=model2
          name: endpoint_id
          style: form
          explode: true
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            default:
              - time_series
              - request_count
            description: >-
              Data and metrics to include in the response. Use 'time_series' for
              time-bucketed data, metric names for specific metrics in time
              series, and 'summary' for aggregate statistics. At least one of
              'time_series' or 'summary' and at least one metric are required.
            example:
              - request_count
              - success_count
          required: false
          description: >-
            Data and metrics to include in the response. Use 'time_series' for
            time-bucketed data, metric names for specific metrics in time
            series, and 'summary' for aggregate statistics. At least one of
            'time_series' or 'summary' and at least one metric are required.
          name: expand
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Analytics data retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  time_series:
                    type: array
                    items:
                      type: object
                      properties:
                        bucket:
                          type: string
                          description: >-
                            Time bucket timestamp in user's timezone with offset
                            (ISO8601 datetime)
                        results:
                          type: array
                          items:
                            type: object
                            properties:
                              endpoint_id:
                                type: string
                                description: Endpoint identifier for these statistics
                              request_count:
                                type: integer
                                minimum: 0
                                description: Total number of requests
                              success_count:
                                type: integer
                                minimum: 0
                                description: Number of successful requests (2xx responses)
                              user_error_count:
                                type: integer
                                minimum: 0
                                description: Number of user errors (4xx responses)
                              error_count:
                                type: integer
                                minimum: 0
                                description: Number of server errors (5xx responses)
                              p50_prepare_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  50th percentile queue/prepare time before
                                  execution in seconds
                              p75_prepare_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  75th percentile queue/prepare time before
                                  execution in seconds
                              p90_prepare_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  90th percentile queue/prepare time before
                                  execution in seconds
                              p50_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  50th percentile request execution duration in
                                  seconds
                              p75_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  75th percentile request execution duration in
                                  seconds
                              p90_duration:
                                type: number
                                minimum: 0
                                description: >-
                                  90th percentile request execution duration in
                                  seconds
                            required:
                              - endpoint_id
                            description: >-
                              Performance and reliability analytics. Only
                              requested metrics (via expand parameter) will be
                              present in the response. 'prepare_duration'
                              reflects queue/prepare time before execution;
                              'duration' is request execution time.
                          description: Analytics records for this time bucket
                      required:
                        - bucket
                        - results
                      description: Time bucket with grouped analytics records
                    description: >-
                      Time series analytics data grouped by time bucket (when
                      expand includes 'time_series'). Each bucket contains all
                      analytics records for that time period.
                  summary:
                    type: array
                    items:
                      type: object
                      properties:
                        endpoint_id:
                          type: string
                          description: Endpoint identifier for these statistics
                        request_count:
                          type: integer
                          minimum: 0
                          description: Total number of requests
                        success_count:
                          type: integer
                          minimum: 0
                          description: Number of successful requests (2xx responses)
                        user_error_count:
                          type: integer
                          minimum: 0
                          description: Number of user errors (4xx responses)
                        error_count:
                          type: integer
                          minimum: 0
                          description: Number of server errors (5xx responses)
                        p50_prepare_duration:
                          type: number
                          minimum: 0
                          description: >-
                            50th percentile queue/prepare time before execution
                            in seconds
                        p75_prepare_duration:
                          type: number
                          minimum: 0
                          description: >-
                            75th percentile queue/prepare time before execution
                            in seconds
                        p90_prepare_duration:
                          type: number
                          minimum: 0
                          description: >-
                            90th percentile queue/prepare time before execution
                            in seconds
                        p50_duration:
                          type: number
                          minimum: 0
                          description: >-
                            50th percentile request execution duration in
                            seconds
                        p75_duration:
                          type: number
                          minimum: 0
                          description: >-
                            75th percentile request execution duration in
                            seconds
                        p90_duration:
                          type: number
                          minimum: 0
                          description: >-
                            90th percentile request execution duration in
                            seconds
                      required:
                        - endpoint_id
                      description: >-
                        Aggregate performance statistics for the entire date
                        range
                    description: Aggregate statistics (when expand includes 'summary')
                required:
                  - next_cursor
                  - has_more
                description: >-
                  Response containing performance analytics with pagination
                  support
              example:
                time_series:
                  - bucket: '2025-01-15T12:00:00-05:00'
                    results:
                      - endpoint_id: your-username/your-app
                        request_count: 1500
                        success_count: 1450
                        p50_duration: 2.5
                        p90_duration: 4.8
                next_cursor: null
                has_more: false
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/apps/flush-queue.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flush Application Queue

> Flushes all pending requests from an application's queue.

**Authentication:** Required via API key

**Idempotency:**
- Optional `Idempotency-Key` header prevents duplicate flushes on retries
- Responses cached for 10 minutes per unique key

**Use Cases:**
- Clear stuck or outdated requests from the queue
- Reset queue state during development or testing
- Cancel all pending requests for an application

**Important:**
- This operation is irreversible
- All pending requests in the queue will be cancelled
- Requests already being processed will not be affected



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json delete /serverless/apps/{owner}/{name}/queue
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/apps/{owner}/{name}/queue:
    delete:
      tags:
        - Serverless
        - Apps
      summary: Flush Application Queue
      description: >-
        Flushes all pending requests from an application's queue.


        **Authentication:** Required via API key


        **Idempotency:**

        - Optional `Idempotency-Key` header prevents duplicate flushes on
        retries

        - Responses cached for 10 minutes per unique key


        **Use Cases:**

        - Clear stuck or outdated requests from the queue

        - Reset queue state during development or testing

        - Cancel all pending requests for an application


        **Important:**

        - This operation is irreversible

        - All pending requests in the queue will be cancelled

        - Requests already being processed will not be affected
      operationId: serverlessFlushAppQueue
      parameters:
        - schema:
            type: string
            description: Username of the app owner
            example: user_123
          required: true
          description: Username of the app owner
          name: owner
          in: path
        - schema:
            type: string
            description: Application name
            example: my-app
          required: true
          description: Application name
          name: name
          in: path
        - schema:
            type: string
            description: Optional idempotency key for safe request retries
            example: 550e8400-e29b-41d4-a716-446655440000
          required: false
          description: Optional idempotency key for safe request retries
          name: Idempotency-Key
          in: header
      responses:
        '204':
          description: Queue flushed successfully
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/apps/queue.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Queue Size

> Retrieves the current queue size for a specific application.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /serverless/apps/{owner}/{name}/queue
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/apps/{owner}/{name}/queue:
    get:
      tags:
        - Serverless
        - Apps
      summary: Queue Size
      description: Retrieves the current queue size for a specific application.
      operationId: serverlessGetAppQueueInfo
      parameters:
        - schema:
            type: string
            description: Username of the app owner
            example: user_123
          required: true
          description: Username of the app owner
          name: owner
          in: path
        - schema:
            type: string
            description: Application name
            example: my-app
          required: true
          description: Application name
          name: name
          in: path
      responses:
        '200':
          description: Successfully retrieved queue information
          content:
            application/json:
              schema:
                type: object
                properties:
                  queue_size:
                    type: integer
                    minimum: 0
                    description: Current number of requests in the queue
                    example: 5
                required:
                  - queue_size
                additionalProperties: false
                description: Status of the app queue
              example:
                queue_size: 5
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/files/file/download.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Download file

> Downloads a file by its path. Proxies the underlying storage response.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /serverless/files/file/{file}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/files/file/{file}:
    get:
      tags:
        - Serverless
        - Files
      summary: Download file
      description: Downloads a file by its path. Proxies the underlying storage response.
      operationId: serverlessDownloadFile
      parameters:
        - schema:
            type: string
            description: Path of the file to download
            example: datasets/images/cat.jpg
          required: true
          description: Path of the file to download
          name: file
          in: path
      responses:
        '200':
          description: File stream
          content:
            application/octet-stream:
              schema: {}
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/files/file/upload-from-url.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload file from URL

> Creates a new file at the target path by downloading it from the provided URL.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json post /serverless/files/file/url/{file}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/files/file/url/{file}:
    post:
      tags:
        - Serverless
        - Files
      summary: Upload file from URL
      description: >-
        Creates a new file at the target path by downloading it from the
        provided URL.
      operationId: serverlessUploadFromUrl
      parameters:
        - schema:
            type: string
            description: Target file path (including filename)
            example: datasets/images/cat.jpg
          required: true
          description: Target file path (including filename)
          name: file
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  format: uri
                  description: Publicly accessible URL for the file
              required:
                - url
              additionalProperties: false
              description: Upload a file from a URL into the target path
            example:
              url: https://example.com/cat.jpg
      responses:
        '200':
          description: Upload initiated
          content:
            application/json:
              schema:
                type: boolean
                description: Indicates whether the operation was successful
              example: true
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/files/file/upload-local.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload local file (multipart/form-data)

> Uploads a local file using multipart/form-data. The file field name must be `file_upload`.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json post /serverless/files/file/local/{target_path}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/files/file/local/{target_path}:
    post:
      tags:
        - Serverless
        - Files
      summary: Upload local file (multipart/form-data)
      description: >-
        Uploads a local file using multipart/form-data. The file field name must
        be `file_upload`.
      operationId: serverlessUploadLocalFile
      parameters:
        - schema:
            type: string
            description: Target path (including filename)
            example: datasets/images/cat.jpg
          required: true
          description: Target path (including filename)
          name: target_path
          in: path
        - schema:
            type:
              - boolean
              - 'null'
            default: false
            description: If true and the uploaded file is a ZIP, it will be extracted
            example: false
          required: false
          description: If true and the uploaded file is a ZIP, it will be extracted
          name: unzip
          in: query
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file_upload:
                  description: Binary file content
              additionalProperties: false
      responses:
        '200':
          description: Upload completed
          content:
            application/json:
              schema:
                type: boolean
                description: Indicates whether the operation was successful
              example: true
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/files/list.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List files (root)

> Lists files and folders in the root of your project storage.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /serverless/files/list
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/files/list:
    get:
      tags:
        - Serverless
        - Files
      summary: List files (root)
      description: Lists files and folders in the root of your project storage.
      operationId: serverlessListRoot
      responses:
        '200':
          description: Successfully listed files
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    path:
                      type: string
                      description: Full file or folder path
                      example: datasets/images/cat.jpg
                    name:
                      type: string
                      description: Base name of the file or folder
                      example: cat.jpg
                    created_time:
                      type: string
                      format: date-time
                      description: Creation timestamp (UTC ISO 8601)
                      example: '2024-11-08T00:00:00.000Z'
                    updated_time:
                      type: string
                      format: date-time
                      description: Last update timestamp (UTC ISO 8601)
                      example: '2024-11-09T00:00:00.000Z'
                    is_file:
                      type: boolean
                      description: True if this item is a file, false if it is a folder
                      example: true
                    size:
                      type: number
                      description: File size in bytes (0 for folders)
                      example: 1250023
                    checksum_sha256:
                      type: string
                      description: Optional SHA256 checksum
                      example: >-
                        b1946ac92492d2347c6235b4d2611184d5c3f1f0f44aa7b27d3b1d5b0f5a6a11
                    checksum_md5:
                      type: string
                      description: Optional MD5 checksum
                      example: 9e107d9d372bb6826bd81d3542a419d6
                  required:
                    - path
                    - name
                    - created_time
                    - updated_time
                    - is_file
                    - size
                  additionalProperties: false
                  description: File or folder specification
                description: Array of files and folders for the requested directory
              example:
                - path: datasets
                  name: datasets
                  created_time: '2024-11-08T00:00:00.000Z'
                  updated_time: '2024-11-09T00:00:00.000Z'
                  is_file: false
                  size: 0
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/files/list/directory.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List files (directory)

> Lists files and folders within the specified directory path.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /serverless/files/list/{dir}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/files/list/{dir}:
    get:
      tags:
        - Serverless
        - Files
      summary: List files (directory)
      description: Lists files and folders within the specified directory path.
      operationId: serverlessListDirectory
      parameters:
        - schema:
            type: string
            description: Directory path to list
            example: datasets/images
          required: true
          description: Directory path to list
          name: dir
          in: path
      responses:
        '200':
          description: Successfully listed files
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    path:
                      type: string
                      description: Full file or folder path
                      example: datasets/images/cat.jpg
                    name:
                      type: string
                      description: Base name of the file or folder
                      example: cat.jpg
                    created_time:
                      type: string
                      format: date-time
                      description: Creation timestamp (UTC ISO 8601)
                      example: '2024-11-08T00:00:00.000Z'
                    updated_time:
                      type: string
                      format: date-time
                      description: Last update timestamp (UTC ISO 8601)
                      example: '2024-11-09T00:00:00.000Z'
                    is_file:
                      type: boolean
                      description: True if this item is a file, false if it is a folder
                      example: true
                    size:
                      type: number
                      description: File size in bytes (0 for folders)
                      example: 1250023
                    checksum_sha256:
                      type: string
                      description: Optional SHA256 checksum
                      example: >-
                        b1946ac92492d2347c6235b4d2611184d5c3f1f0f44aa7b27d3b1d5b0f5a6a11
                    checksum_md5:
                      type: string
                      description: Optional MD5 checksum
                      example: 9e107d9d372bb6826bd81d3542a419d6
                  required:
                    - path
                    - name
                    - created_time
                    - updated_time
                    - is_file
                    - size
                  additionalProperties: false
                  description: File or folder specification
                description: Array of files and folders for the requested directory
              examples:
                success:
                  value:
                    - path: datasets/images/cat.jpg
                      name: cat.jpg
                      created_time: '2024-11-08T00:00:00.000Z'
                      updated_time: '2024-11-09T00:00:00.000Z'
                      is_file: true
                      size: 1250023
                      checksum_sha256: >-
                        b1946ac92492d2347c6235b4d2611184d5c3f1f0f44aa7b27d3b1d5b0f5a6a11
                  summary: Directory listing
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/logs/history.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Logs history (paginated)

> Returns paginated historical logs that match the provided filters.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json post /serverless/logs/history
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/logs/history:
    post:
      tags:
        - Serverless
        - Logs
      summary: Logs history (paginated)
      description: Returns paginated historical logs that match the provided filters.
      operationId: serverlessLogsHistory
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 1000
            description: Number of results per page
            example: 100
          required: false
          description: Number of results per page
          name: limit
          in: query
        - schema:
            type: string
            description: >-
              Pagination cursor from previous response (timestamp-based). Use as
              'until' parameter for next page.
            example: '2024-11-09T00:00:00.000Z'
          required: false
          description: >-
            Pagination cursor from previous response (timestamp-based). Use as
            'until' parameter for next page.
          name: cursor
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Filter by specific app ID(s) in '<owner>/<name>' format (e.g.
              'fal-ai/my-app'). Accepts 1-50 app IDs. Supports comma-separated
              values: ?app_id=fal-ai/foo,fal-ai/bar or array syntax:
              ?app_id=fal-ai/foo&app_id=fal-ai/bar
            example:
              - fal-ai/my-app
          required: false
          description: >-
            Filter by specific app ID(s) in '<owner>/<name>' format (e.g.
            'fal-ai/my-app'). Accepts 1-50 app IDs. Supports comma-separated
            values: ?app_id=fal-ai/foo,fal-ai/bar or array syntax:
            ?app_id=fal-ai/foo&app_id=fal-ai/bar
          name: app_id
          style: form
          explode: true
          in: query
        - schema:
            type: string
            description: Filter by revision
            example: rev_abc123
          required: false
          description: Filter by revision
          name: revision
          in: query
        - schema:
            type: string
            enum:
              - grpc-run
              - grpc-register
              - gateway
              - cron
            description: Filter by run source
            example: grpc-run
          required: false
          description: Filter by run source
          name: run_source
          in: query
        - schema:
            type:
              - boolean
              - 'null'
            default: false
            description: Include tracebacks
            example: false
          required: false
          description: Include tracebacks
          name: traceback
          in: query
        - schema:
            type: string
            description: Free-text search
            example: error
          required: false
          description: Free-text search
          name: search
          in: query
        - schema:
            type: string
            description: Minimum log level
            example: error
          required: false
          description: Minimum log level
          name: level
          in: query
        - schema:
            type: string
            description: Filter by job id
            example: job_123
          required: false
          description: Filter by job id
          name: job_id
          in: query
        - schema:
            type: string
            description: Filter by request id
            example: req_abc123
          required: false
          description: Filter by request id
          name: request_id
          in: query
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                properties:
                  key:
                    type: string
                    description: Label key to filter
                  value:
                    anyOf:
                      - type: string
                      - type: array
                        items:
                          type: string
                    description: Filter value
                  condition_type:
                    type: string
                    enum:
                      - equals
                      - in
                      - not_equals
                      - not_in
                    description: Condition type for label filtering
                required:
                  - key
                  - value
                additionalProperties: false
                description: Filter for log labels
            examples:
              single:
                value:
                  - key: fal_job_id
                    value: job_123
                summary: Filter by a single label
      responses:
        '200':
          description: Logs history retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        timestamp:
                          type: string
                          description: ISO timestamp of the log line
                        level:
                          type: string
                          description: Log level
                        message:
                          type: string
                          description: Log message
                        app:
                          type: string
                          description: App identifier
                        revision:
                          type: string
                          description: Revision identifier
                        labels:
                          type: object
                          additionalProperties:
                            type: string
                          description: Additional labels
                      required:
                        - timestamp
                        - level
                        - message
                        - app
                        - revision
                      additionalProperties: false
                      description: A single log entry
                    description: Array of log entries matching the query
                required:
                  - next_cursor
                  - has_more
                  - items
                description: Paginated logs response
              examples:
                success:
                  value:
                    items:
                      - timestamp: '2024-11-09T10:30:45.123Z'
                        level: info
                        message: Application started
                        app: my-app
                        revision: rev_abc123
                        labels:
                          fal_job_id: job_123
                    next_cursor: '2024-11-09T10:30:44.000Z'
                    has_more: true
                  summary: Paginated logs response
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/logs/stream.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Logs stream (SSE)

> Streams live logs that match the provided filters using Server-Sent Events.



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json post /serverless/logs/stream
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/logs/stream:
    post:
      tags:
        - Serverless
        - Logs
      summary: Logs stream (SSE)
      description: >-
        Streams live logs that match the provided filters using Server-Sent
        Events.
      operationId: serverlessLogsStream
      parameters:
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Filter by specific app ID(s) in '<owner>/<name>' format (e.g.
              'fal-ai/my-app'). Accepts 1-50 app IDs. Supports comma-separated
              values: ?app_id=fal-ai/foo,fal-ai/bar or array syntax:
              ?app_id=fal-ai/foo&app_id=fal-ai/bar
            example:
              - fal-ai/my-app
          required: false
          description: >-
            Filter by specific app ID(s) in '<owner>/<name>' format (e.g.
            'fal-ai/my-app'). Accepts 1-50 app IDs. Supports comma-separated
            values: ?app_id=fal-ai/foo,fal-ai/bar or array syntax:
            ?app_id=fal-ai/foo&app_id=fal-ai/bar
          name: app_id
          style: form
          explode: true
          in: query
        - schema:
            type: string
            description: Filter by revision
            example: rev_abc123
          required: false
          description: Filter by revision
          name: revision
          in: query
        - schema:
            type: string
            enum:
              - grpc-run
              - grpc-register
              - gateway
              - cron
            description: Filter by run source
            example: grpc-run
          required: false
          description: Filter by run source
          name: run_source
          in: query
        - schema:
            type:
              - boolean
              - 'null'
            default: false
            description: Include tracebacks
            example: false
          required: false
          description: Include tracebacks
          name: traceback
          in: query
        - schema:
            type: string
            description: Free-text search
            example: error
          required: false
          description: Free-text search
          name: search
          in: query
        - schema:
            type: string
            description: Minimum log level
            example: error
          required: false
          description: Minimum log level
          name: level
          in: query
        - schema:
            type: string
            description: Filter by job id
            example: job_123
          required: false
          description: Filter by job id
          name: job_id
          in: query
        - schema:
            type: string
            description: Filter by request id
            example: req_abc123
          required: false
          description: Filter by request id
          name: request_id
          in: query
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                properties:
                  key:
                    type: string
                    description: Label key to filter
                  value:
                    anyOf:
                      - type: string
                      - type: array
                        items:
                          type: string
                    description: Filter value
                  condition_type:
                    type: string
                    enum:
                      - equals
                      - in
                      - not_equals
                      - not_in
                    description: Condition type for label filtering
                required:
                  - key
                  - value
                additionalProperties: false
                description: Filter for log labels
            examples:
              single:
                value:
                  - key: fal_job_id
                    value: job_123
                summary: Filter by a single label
      responses:
        '200':
          description: SSE stream started
          content:
            text/event-stream:
              schema: {}
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/metrics.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Metrics

> 
Returns Prometheus-compatible metrics in text format for integration into your
observability stack

**Authentication:** Required - Uses API key authentication

**Format:** Returns text/plain in Prometheus exposition format

**Common Use Cases:**
- Export app stats to your observability provider (grafana, datadog etc)
- Track runner health and performance
- Set up alerts and monitoring

See [Prometheus documentation](https://prometheus.io/docs/instrumenting/exposition_formats/) for format details.
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /serverless/metrics
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/metrics:
    get:
      tags:
        - Serverless
        - Metrics
        - Observability
      summary: Metrics
      description: >-

        Returns Prometheus-compatible metrics in text format for integration
        into your

        observability stack


        **Authentication:** Required - Uses API key authentication


        **Format:** Returns text/plain in Prometheus exposition format


        **Common Use Cases:**

        - Export app stats to your observability provider (grafana, datadog etc)

        - Track runner health and performance

        - Set up alerts and monitoring


        See [Prometheus
        documentation](https://prometheus.io/docs/instrumenting/exposition_formats/)
        for format details.
            
      operationId: serverlessGetMetrics
      responses:
        '200':
          description: Prometheus-compatible metrics retrieved successfully
          content:
            text/plain:
              schema:
                type: string
                description: Prometheus-compatible metrics in text format
                example: |-
                  # HELP fal_app_queue_size Current size of the fal app queue
                  # TYPE fal_app_queue_size gauge
                  fal_requests_total{application="my/app"} 10
              example: >-
                # HELP fal_app_runners Number of fal app runners

                # TYPE fal_app_runners gauge

                fal_app_runners{application="my/app",machine_type="NVIDIA
                B200",state="running"} 21

                # HELP fal_app_queue_size Current size of the fal app queue

                # TYPE fal_app_queue_size gauge

                fal_app_queue_size{application="my/app"} 7

                # HELP fal_app_concurrent_requests Current number of concurrent
                requests being processed

                # TYPE fal_app_concurrent_requests gauge

                fal_app_concurrent_requests{application="my/app"} 3

                # HELP fal_app_requests_completed Number of requests completed
                in the last minute

                # TYPE fal_app_requests_completed gauge

                fal_app_requests_completed{application="my/app",method="POST",status="200"}
                18

                # HELP fal_app_requests_received Number of requests received in
                the last minute

                # TYPE fal_app_requests_received gauge

                fal_app_requests_received{application="my/app",method="POST"} 24

                # HELP fal_app_request_latency Number of requests completed,
                bucketed by latency in seconds

                # TYPE fal_app_request_latency gauge

                fal_app_request_latency{application="my/app",le="1.0"} 5

                fal_app_request_latency{application="my/app",le="+Inf"} 24
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/serverless/requests/by-endpoint.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List requests by endpoint

> Lists requests for endpoints owned by the authenticated user.

**Authentication:** Requires API key.

**Filters:**
- Time range via start / end
- Status (success, error, user_error)
- Request ID
- Pagination via cursor/limit (limit defaults to 50, max 100)

**Sorting:**
- By end time (default) or duration

**Expansions:**
- Include payloads by adding expand=payloads



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /serverless/requests/by-endpoint
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /serverless/requests/by-endpoint:
    get:
      tags:
        - Serverless
        - Requests
      summary: List requests by endpoint
      description: |-
        Lists requests for endpoints owned by the authenticated user.

        **Authentication:** Requires API key.

        **Filters:**
        - Time range via start / end
        - Status (success, error, user_error)
        - Request ID
        - Pagination via cursor/limit (limit defaults to 50, max 100)

        **Sorting:**
        - By end time (default) or duration

        **Expansions:**
        - Include payloads by adding expand=payloads
      operationId: serverlessListRequestsByEndpoint
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
            description: Number of items to return per page (max 100)
            example: 20
          required: false
          description: Number of items to return per page (max 100)
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor encoding the page number
            example: Mg==
          required: false
          description: Pagination cursor encoding the page number
          name: cursor
          in: query
        - schema:
            type: string
            description: Endpoint identifier to filter requests by
            example: fal-ai/flux/dev
          required: true
          description: Endpoint identifier to filter requests by
          name: endpoint_id
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
              '2025-01-01'). Defaults to 24 hours ago.
            example: '2025-01-01T00:00:00Z'
          required: false
          description: >-
            Start date in ISO8601 format (e.g., '2025-01-01T00:00:00Z' or
            '2025-01-01'). Defaults to 24 hours ago.
          name: start
          in: query
        - schema:
            anyOf:
              - type: string
                format: date-time
              - type: string
                pattern: ^\d{4}-\d{2}-\d{2}$
            description: >-
              End date in ISO8601 format, exclusive (e.g.,
              '2025-02-01T00:00:00Z' or '2025-02-01'). Data up to but not
              including this timestamp is returned. Defaults to current time.
            example: '2025-02-01T00:00:00Z'
          required: false
          description: >-
            End date in ISO8601 format, exclusive (e.g., '2025-02-01T00:00:00Z'
            or '2025-02-01'). Data up to but not including this timestamp is
            returned. Defaults to current time.
          name: end
          in: query
        - schema:
            type: string
            enum:
              - success
              - error
              - user_error
            description: Filter by request status
            example: success
          required: false
          description: Filter by request status
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filter by specific request ID
            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
          required: false
          description: Filter by specific request ID
          name: request_id
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Fields to expand in the response. Use payloads to include input
              and output payloads.
            example:
              - payloads
          required: false
          description: >-
            Fields to expand in the response. Use payloads to include input and
            output payloads.
          name: expand
          style: form
          explode: true
          in: query
        - schema:
            type: string
            enum:
              - ended_at
              - duration
            default: ended_at
            description: Sort results by end time or duration
            example: ended_at
          required: false
          description: Sort results by end time or duration
          name: sort_by
          in: query
      responses:
        '200':
          description: Requests listed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                  has_more:
                    type: boolean
                    description: >-
                      Boolean indicating if more results are available
                      (convenience field derived from next_cursor)
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        request_id:
                          type: string
                          format: uuid
                          description: Unique identifier for the request
                          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        endpoint_id:
                          type: string
                          description: Endpoint that was executed for this request
                          example: fal-ai/flux/dev
                        started_at:
                          type: string
                          format: date-time
                          description: Time when request processing started
                          example: '2025-01-01T00:00:05Z'
                        sent_at:
                          type: string
                          format: date-time
                          description: Time when request was sent to the backend
                          example: '2025-01-01T00:00:01Z'
                        ended_at:
                          type:
                            - string
                            - 'null'
                          format: date-time
                          description: Time when request finished processing
                          example: '2025-01-01T00:00:08Z'
                        status_code:
                          type:
                            - integer
                            - 'null'
                          description: HTTP status code returned by the request
                          example: 200
                        duration:
                          type:
                            - number
                            - 'null'
                          description: Total request duration in seconds
                          example: 7.8
                        json_input:
                          description: Input payload for the request
                        json_output:
                          description: Output payload for the request
                        runner_id:
                          type: string
                          format: uuid
                          description: Unique identifier for the runner execution instance
                          example: f1e2d3c4-b5a6-7890-dcba-0987654321fe
                      required:
                        - request_id
                        - endpoint_id
                        - started_at
                        - sent_at
                        - runner_id
                      description: Serverless request item
                    description: List of requests matching the filter
                required:
                  - next_cursor
                  - has_more
                  - items
                description: >-
                  Paginated list of serverless requests for the specified
                  endpoint
              example:
                items:
                  - request_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    endpoint_id: fal-ai/flux/dev
                    runner_id: f1e2d3c4-b5a6-7890-dcba-0987654321fe
                    started_at: '2025-01-01T00:00:05Z'
                    sent_at: '2025-01-01T00:00:01Z'
                    ended_at: '2025-01-01T00:00:08Z'
                    status_code: 200
                    duration: 7.8
                    json_input:
                      prompt: cat astronaut
                    json_output:
                      status: ok
                next_cursor: Mg==
                has_more: true
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/workflows.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List user workflows

> 
List workflows for the authenticated user with optional search and filtering.

**Features:**
- Paginated results with cursor-based pagination
- Search by workflow name or title
- Filter by model endpoints used in the workflow

**Authentication:** Required. Returns only workflows owned by the authenticated user.

**Common Use Cases:**
- Display user's workflow library
- Search for specific workflows
- Find workflows using particular models
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /workflows
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /workflows:
    get:
      tags:
        - Workflows
      summary: List user workflows
      description: >-

        List workflows for the authenticated user with optional search and
        filtering.


        **Features:**

        - Paginated results with cursor-based pagination

        - Search by workflow name or title

        - Filter by model endpoints used in the workflow


        **Authentication:** Required. Returns only workflows owned by the
        authenticated user.


        **Common Use Cases:**

        - Display user's workflow library

        - Search for specific workflows

        - Find workflows using particular models
            
      operationId: listWorkflows
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: >-
              Maximum number of items to return. Actual maximum depends on query
              type and expansion parameters.
            example: 50
          required: false
          description: >-
            Maximum number of items to return. Actual maximum depends on query
            type and expansion parameters.
          name: limit
          in: query
        - schema:
            type: string
            description: Pagination cursor from previous response. Encodes the page number.
            example: Mg==
          required: false
          description: Pagination cursor from previous response. Encodes the page number.
          name: cursor
          in: query
        - schema:
            type: string
            description: Search by workflow name or title
            example: image generation
          required: false
          description: Search by workflow name or title
          name: search
          in: query
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
            description: >-
              Filter by model endpoint IDs used in the workflow. Can be a single
              value or comma-separated values.
            example:
              - fal-ai/flux/dev
          required: false
          description: >-
            Filter by model endpoint IDs used in the workflow. Can be a single
            value or comma-separated values.
          name: used_endpoint_ids
          style: form
          explode: true
          in: query
      responses:
        '200':
          description: Successfully retrieved workflows
          content:
            application/json:
              schema:
                type: object
                properties:
                  workflows:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          description: >-
                            Unique workflow name/slug within the user's
                            namespace
                          example: my-image-workflow
                        title:
                          type: string
                          description: Human-readable workflow title
                          example: My Image Generation Workflow
                        user_nickname:
                          type: string
                          description: Display name/username of the owner
                          example: johndoe
                        created_at:
                          type: string
                          description: ISO8601 timestamp of workflow creation
                          example: '2024-01-15T10:30:00Z'
                        thumbnail_url:
                          type: string
                          description: URL to the workflow thumbnail image
                          example: https://fal.ai/workflows/thumb_abc123.png
                        description:
                          type: string
                          description: Brief description of what the workflow does
                          example: Generate high-quality images using FLUX model
                        tags:
                          type: array
                          items:
                            type: string
                            example: image-generation
                          description: Tags associated with the workflow
                          example:
                            - image-generation
                            - ai
                            - flux
                        endpoint_ids:
                          type: array
                          items:
                            type: string
                            example: fal-ai/flux/dev
                          description: List of model endpoint IDs used in this workflow
                          example:
                            - fal-ai/flux/dev
                            - fal-ai/face-swap
                      required:
                        - name
                        - title
                        - user_nickname
                        - created_at
                        - tags
                        - endpoint_ids
                      description: Workflow information
                    description: Array of workflow items
                    example:
                      - name: my-image-workflow
                        title: My Image Generation Workflow
                        user_nickname: johndoe
                        created_at: '2024-01-15T10:30:00Z'
                        thumbnail_url: https://fal.ai/workflows/thumb_abc123.png
                        description: Generate high-quality images using FLUX model
                        tags:
                          - image-generation
                          - ai
                          - flux
                        endpoint_ids:
                          - fal-ai/flux/dev
                          - fal-ai/face-swap
                  next_cursor:
                    type:
                      - string
                      - 'null'
                    description: Cursor for the next page of results, null if no more pages
                    example: eyJvZmZzZXQiOjEwfQ==
                  has_more:
                    type: boolean
                    description: Whether more results are available
                    example: true
                  total:
                    type: integer
                    description: Total number of workflows matching the query
                    example: 42
                required:
                  - workflows
                  - next_cursor
                  - has_more
                description: Response containing workflow data with pagination support
              example:
                workflows:
                  - name: my-image-workflow
                    title: My Image Generation Workflow
                    user_nickname: johndoe
                    created_at: '2025-01-15T12:00:00Z'
                    thumbnail_url: https://fal.media/files/example.jpg
                    description: A workflow for generating images
                    tags:
                      - image
                      - generation
                    endpoint_ids:
                      - fal-ai/flux/dev
                next_cursor: null
                has_more: false
                total: 1
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````

# https://fal.ai/docs/platform-apis/v1/workflows/get.md

> ## Documentation Index
> Fetch the complete documentation index at: https://fal.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Get workflow details

> 
Get detailed information about a specific workflow, including its full contents/definition.

**Authentication:** Required.

**Common Use Cases:**
- Load a workflow for editing
- View workflow configuration
- Export workflow definition
    



## OpenAPI

````yaml /api-reference/platform-apis/openapi/v1.json get /workflows/{username}/{workflow_name}
openapi: 3.1.0
info:
  title: Platform APIs
  version: v1
  description: fal REST API for programmatic access to platform resources.
servers:
  - url: https://api.fal.ai/v1
    description: Production server
security: []
paths:
  /workflows/{username}/{workflow_name}:
    get:
      tags:
        - Workflows
      summary: Get workflow details
      description: >-

        Get detailed information about a specific workflow, including its full
        contents/definition.


        **Authentication:** Required.


        **Common Use Cases:**

        - Load a workflow for editing

        - View workflow configuration

        - Export workflow definition
            
      operationId: getWorkflow
      parameters:
        - schema:
            type: string
            description: The username of the workflow owner
            example: johndoe
          required: true
          description: The username of the workflow owner
          name: username
          in: path
        - schema:
            type: string
            description: The workflow name/slug
            example: my-image-workflow
          required: true
          description: The workflow name/slug
          name: workflow_name
          in: path
      responses:
        '200':
          description: Successfully retrieved workflow details
          content:
            application/json:
              schema:
                type: object
                properties:
                  workflow:
                    type: object
                    properties:
                      name:
                        type: string
                        description: Unique workflow name/slug within the user's namespace
                        example: my-image-workflow
                      title:
                        type: string
                        description: Human-readable workflow title
                        example: My Image Generation Workflow
                      user_nickname:
                        type: string
                        description: Display name/username of the owner
                        example: johndoe
                      created_at:
                        type: string
                        description: ISO8601 timestamp of workflow creation
                        example: '2024-01-15T10:30:00Z'
                      is_public:
                        type: boolean
                        description: Whether the workflow is publicly visible
                        example: true
                      contents:
                        type: object
                        additionalProperties: {}
                        description: The workflow definition/configuration object
                        example:
                          nodes:
                            node_a1b2c3:
                              id: node_a1b2c3
                              type: model
                              app: fal-ai/flux/dev
                              depends: []
                              input:
                                prompt: $input.prompt
                              metadata:
                                position:
                                  x: 300
                                  'y': 100
                            output:
                              id: output
                              type: output
                              depends:
                                - node_a1b2c3
                              fields:
                                image: $node_a1b2c3.images.0.url
                              metadata:
                                position:
                                  x: 600
                                  'y': 100
                    required:
                      - name
                      - title
                      - user_nickname
                      - created_at
                      - is_public
                      - contents
                    description: The workflow details
                    example:
                      name: my-image-workflow
                      title: My Image Generation Workflow
                      user_nickname: johndoe
                      created_at: '2024-01-15T10:30:00Z'
                      is_public: true
                      contents:
                        nodes:
                          node_a1b2c3:
                            id: node_a1b2c3
                            type: model
                            app: fal-ai/flux/dev
                            depends: []
                            input:
                              prompt: $input.prompt
                            metadata:
                              position:
                                x: 300
                                'y': 100
                          output:
                            id: output
                            type: output
                            depends:
                              - node_a1b2c3
                            fields:
                              image: $node_a1b2c3.images.0.url
                            metadata:
                              position:
                                x: 600
                                'y': 100
                required:
                  - workflow
                description: Response containing a single workflow's details
              example:
                workflow:
                  name: my-image-workflow
                  title: My Image Generation Workflow
                  user_nickname: johndoe
                  created_at: '2025-01-15T12:00:00Z'
                  is_public: false
                  contents:
                    nodes: []
                    edges: []
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: validation_error
                  message: Invalid request parameters
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Authentication required
        '403':
          description: Access denied
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: authorization_error
                  message: Access denied
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: not_found
                  message: Resource not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: rate_limited
                  message: Rate limit exceeded
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - authorization_error
                          - validation_error
                          - not_found
                          - rate_limited
                          - server_error
                          - not_implemented
                        description: The category of error that occurred
                      message:
                        type: string
                        description: Human-readable error message
                      docs_url:
                        type: string
                        format: uri
                        description: Link to relevant documentation
                      request_id:
                        type: string
                        description: Unique request identifier for debugging
                    required:
                      - type
                      - message
                    description: Error details
                required:
                  - error
                description: Standard error response format
              example:
                error:
                  type: server_error
                  message: An unexpected error occurred
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API key must be prefixed with "Key ", e.g. Authorization: Key
        YOUR_API_KEY

````