> ## 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.

# Webhooks

> fal incoming webhooks: event paths, payloads, and response data.

The fal plugin handles incoming webhooks. fal has no account-wide subscription. Pass your Corsair HTTP handler URL as `webhookUrl` to `queue.submit` for each request, and fal POSTs the result there when the request finishes (see [Overview](https://docs.corsair.dev/plugins/fal/overview.md) for setup).

> [!NOTE]
>
> **New to Corsair?** See [webhooks](https://docs.corsair.dev/concepts/webhooks.md) and [hooks](https://docs.corsair.dev/concepts/hooks.md).

## Webhook map

* `requests`
  * `completed` (`requests.completed`)

## HTTP handler setup

```ts app/api/webhook/route.ts theme={null}
import { processWebhook } from "corsair";
import { corsair } from "@/server/corsair";

export async function POST(request: Request) {
    const headers = Object.fromEntries(request.headers);
    // The raw text: fal signs the exact bytes it sent, so don't parse it first.
    const body = await request.text();
    const result = await processWebhook(corsair, headers, body);
    // Answer non-2xx when processing failed (fal's signing keys didn't load),
    // so fal delivers again.
    return Response.json(result.response ?? { success: false }, {
        status: !result.plugin ? 404 : result.response?.success === false ? 500 : 200,
    });
}
```

## Events

## Requests

### Completed

`requests.completed`

A queued request finished: status OK with the model output, or ERROR with the error. Signed by fal (Ed25519).

**Payload**

| Name | Type | Required | Description |
| - | - | - | - |
| `request_id` | `string` | Yes | — |
| `gateway_request_id` | `string \| null` | No | The last attempt’s id; differs from request\_id when fal retried. |
| `status` | `OK \| ERROR` | Yes | OK: payload is the model output. ERROR: payload is the error body. |
| `payload` | `Record<string, any> \| null` | Yes | — |
| `error` | `string \| null` | No | — |
| `payload_error` | `string \| null` | No | Set when fal could not include the output; read it with queue.result. |

> [accordion] Response data full type
>
> ```ts theme={null}
> {
>   request_id: string,
>   gateway_request_id?: string | null,
>   status: OK | ERROR,
>   payload: Record<string, any> | null,
>   error?: string | null,
>   payload_error?: string | null
> }
> ```

**`webhookHooks` example**

```ts theme={null}
fal({
    webhookHooks: {
        requests: {
            completed: {
                before(ctx, args) {
                    return { ctx, args };
                },
                after(ctx, response) {
                },
            },
        },
    },
})
```

***


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