Skip to main content
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 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 Pages Router

If you are using the Pages Router instead of App Router, create pages/api/fal/proxy/[...path].ts:
import { handler } from "@fal-ai/server-proxy/nextjs";

export default handler;
The client configuration is the same as the App Router setup:
import { fal } from "@fal-ai/client";

fal.config({
  proxyUrl: "/api/fal/proxy"
});

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.

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
Express.js
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:
import { fal } from "@fal-ai/client";

fal.config({
  proxyUrl: "/api/fal/proxy"
});
The proxy URL should be relative to your application root. The client automatically constructs the full URL based on the current origin.