# Express

> Set up the inference shell proxy in Express.js applications.

**URL:** https://inference.sh/docs/api/sdk/proxy/express
**Last updated:** 2026-10-11

---

Set up the inference shell proxy in Express.js applications.

---

## Installation

```bash
npm install @inferencesh/sdk express
```

---

## Basic Setup

```typescript
import express from "express";
import { createHandler, PROXY_ROUTE } from "@inferencesh/sdk/proxy/express";

const app = express();

// Parse JSON bodies
app.use(express.json());

// Mount the proxy
const proxy = createHandler({
  allowedEndpoints: ["my-team/*"],
  isAuthenticated: async (req) => Boolean(req.session?.user),
});
app.all(PROXY_ROUTE, proxy);

app.listen(3000, () => {
  console.log("Server running on port 3000");
});
```

The default route is `/api/inference/proxy`. The proxy forwards app runs and agent chats only; `allowedEndpoints` limits them to your apps and agents, and `isAuthenticated` gets the Express request. See [options](/docs/api/sdk/server-proxy#options).

> [!WARNING]
> Anyone who can reach the proxy route runs apps and agents on your API key. In production set `allowedEndpoints` and `isAuthenticated` (see [what the proxy forwards](/docs/api/sdk/server-proxy#what-the-proxy-forwards)), and create a **Run only** key in a workspace that holds nothing else.

---

## Environment Variable

Set your API key:

```bash
export INFERENCE_API_KEY="inf_your_key_here"
```

Or use a `.env` file with `dotenv`:

```bash
# .env
INFERENCE_API_KEY=inf_your_key_here
```

```typescript
import "dotenv/config";
import express from "express";
import * as inferenceProxy from "@inferencesh/sdk/proxy/express";

const app = express();
app.use(express.json());
app.all(PROXY_ROUTE, proxy);
```

---

## Client Configuration

```typescript
import { inference } from "@inferencesh/sdk";

const client = inference({
  proxyUrl: "http://localhost:3000/api/inference/proxy"
});

const result = await client.run({
  app: "infsh/flux",
  input: { prompt: "A sunset" }
});
```

---

## Custom Route

Mount at a different path:

```typescript
app.all("/my-custom-proxy/*", proxy);
```

Update client:

```typescript
const client = inference({
  proxyUrl: "/my-custom-proxy"
});
```

---

## Rate Limiting

```typescript
import rateLimit from "express-rate-limit";

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per window
});

app.all(PROXY_ROUTE, limiter, proxy);
```

---

## CORS Support

```typescript
import cors from "cors";

app.use(cors({
  origin: "https://myapp.com",
  methods: ["GET", "POST"],
  allowedHeaders: ["Content-Type", "x-inf-target-url"],
}));

app.all(inferenceProxy.route, inferenceProxy.handler);
```

---

## Streaming

The Express handler automatically supports streaming responses for real-time task updates.
