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

# Overview

> Generative media platform with hundreds of image, video, audio and 3D models; queue or run models, follow requests, look up models and prices, track usage and upload input files.

Use **fal** through Corsair: one client, typed API calls, and incoming webhooks.

Every model on fal takes its own input fields. Look them up with `models.search({ endpointIds: ['<endpoint id>'], includeOpenApi: true })`, then pass them as `input`.

Video, audio and training runs usually take minutes. After submitting, `models.run` waits up to 10 seconds (at most 15). When it sees the run end within the wait, it answers a final `state`: SUCCEEDED with `output`, or FAILED with `error` (bad input or a model error), and there is nothing to follow. Any other answer carries the run's `response_url` and IN\_PROGRESS or IN\_QUEUE. IN\_QUEUE also covers a read that failed or ran out of time, so the run may already have started or even finished at fal. Follow every IN\_QUEUE or IN\_PROGRESS answer with `queue.status({ responseUrl })` until it says SUCCEEDED or FAILED, or pass `webhookUrl` and let fal post the result. On Corsair's cloud, `get_job` and the job card do the following for you.

**What you get:**

* 14 typed API operations
* 1 incoming webhook event types

## Setup

**1. Install**

```bash npm theme={null}
npm install corsair @corsair-dev/fal
```

```bash yarn theme={null}
yarn add corsair @corsair-dev/fal
```

```bash pnpm theme={null}
pnpm install corsair @corsair-dev/fal
```

```bash bun theme={null}
bun add corsair @corsair-dev/fal
```

**2. Add the plugin**

```ts corsair.ts theme={null}
import Database from 'better-sqlite3';
import { createCorsair } from 'corsair';
import { fal } from '@corsair-dev/fal';

export const corsair = createCorsair({
	plugins: [
		fal(),
	],
	database: new Database('corsair.db'),
	kek: process.env.CORSAIR_KEK!,
	multiTenancy: true,
	hub: {
		projectApiKey: process.env.CORSAIR_API_KEY!,
		signingSecret: process.env.CORSAIR_SIGNING_SECRET!,
	},
});
```

With `multiTenancy: true`, scope calls with `corsair.withTenant(id)`. See [Quick start](https://docs.corsair.dev/quick-start.md) for KEK + Hub keys, and [Multi-tenancy](https://docs.corsair.dev/concepts/multi-tenancy.md) for account isolation.

**3. Choose authentication**

> [tab] API Key (Recommended)
>
> No setup required yet. When you make your first request as a tenant, Corsair prompts for the API key.
>
> ```ts theme={null}
> fal()
> ```
>
> More: [API Key](https://docs.corsair.dev/concepts/api-key)

**4. Connect a tenant**

Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see [Connect / OAuth](https://docs.corsair.dev/management/connect).

```ts theme={null}
const { connectUrl } = await corsair.manage.connect.createLink({
	plugin: 'fal',
	tenantId: 'acme',
});
// redirect the user's browser to connectUrl
```

## Example API calls

**Find text-to-video models**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.fal.api.models.search({ category: 'text-to-video', limit: 5 });
```

**Generate an image**

```ts theme={null}
const tenant = corsair.withTenant('acme');
await tenant.fal.api.queue.submit({
	endpointId: 'fal-ai/flux/schnell',
	input: { prompt: 'A watercolor lighthouse on a cliff at dawn', image_size: 'square_hd' },
});
```

See the full list on the [API](https://docs.corsair.dev/plugins/fal/api.md) page.

## Webhooks

Pass `webhookUrl` to `queue.submit` and fal POSTs the result there when the request finishes. Hand `processWebhook` the raw body text (`await request.text()`), not parsed JSON. fal signs the exact bytes it sent; a parsed body is rebuilt as a best effort, which fails for outputs with whole-number floats or integers past 2^53. To hold deliveries to one fal account, store its fal user id (the `x-fal-webhook-user-id` header) as the account's `user_id`.

```ts theme={null}
fal({
    webhookHooks: {
        requests: {
            completed: {
                after: async (ctx, result) => {
                    if (result.data?.status === 'OK') console.log(result.data.request_id, result.data.payload);
                }
            },
        },
    },
})
```

Mount your framework handler once (see [Frameworks](https://docs.corsair.dev/frameworks/next.md)), then point the provider at that URL. Full event list: [Webhooks](https://docs.corsair.dev/plugins/fal/webhooks.md). Concepts: [Webhooks](https://docs.corsair.dev/concepts/webhooks.md), [Hooks](https://docs.corsair.dev/concepts/hooks.md).

## What's next

> [card] [API reference](https://docs.corsair.dev/plugins/fal/api.md)
>
> Every `fal.api.*` operation with input and output types.

> [card] [Webhooks](https://docs.corsair.dev/plugins/fal/webhooks.md)
>
> Event paths, payloads, and `webhookHooks` examples.

> [card] [Connect / OAuth](https://docs.corsair.dev/management/connect)
>
> createLink, Hub delivery, and tenant connect flows.

> [card] [Use with agents](https://docs.corsair.dev/mcp-adapters/mcp-adapters)
>
> Expose this plugin's operations as MCP tools.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.