# Remix

> Set up the inference shell proxy in Remix applications.

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

---

Set up the inference shell proxy in Remix applications.

---

## Installation

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

---

## Basic Setup

Create `app/routes/api.inference.proxy.ts`:

```typescript
import { createHandler } from "@inferencesh/sdk/proxy/remix";

const handler = createHandler({ allowedEndpoints: ["my-team/*"] });

// Handle both GET and POST requests
export const loader = handler;
export const action = handler;
```

The proxy forwards app runs and agent chats only; `allowedEndpoints` limits them to your apps and agents. 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

Add to your `.env`:

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

---

## Client Configuration

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

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

export async function generateImage(prompt: string) {
  const result = await client.run({
    app: "infsh/flux",
    input: { prompt }
  });
  
  return result.output;
}
```

---

## With Authentication

`isAuthenticated` gets the `Request`; `false` answers `401`:

```typescript
import { createHandler } from "@inferencesh/sdk/proxy/remix";
import { getSession } from "~/lib/session.server";

const handler = createHandler({
  allowedEndpoints: ["my-team/*"],
  isAuthenticated: async (request) => {
    const session = await getSession(request.headers.get("Cookie"));
    return Boolean(session.userId);
  },
});

export const loader = handler;
export const action = handler;
```

---

## Custom API Key Resolution

```typescript
import { createHandler } from "@inferencesh/sdk/proxy/remix";

const handler = createHandler({
  resolveApiKey: async () => {
    // Load from secrets manager
    return await getSecret("INFERENCE_API_KEY");
  }
});

export const loader = handler;
export const action = handler;
```

---

## Route Naming

Remix uses file-based routing with dots as path separators:

| File | URL |
|------|-----|
| `api.inference.proxy.ts` | `/api/inference/proxy` |
| `api_.inference.proxy.ts` | `/api/inference/proxy` (no layout) |

---

## Streaming

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