Skip to main content
A proxy handler for Vercel AI Gateway that supports both API key and OIDC authentication methods.

Features

  • Request/Response Hooks - Transform requests and responses with beforeRequest, afterResponse, and onError hooks
  • Streaming Support - Full SSE streaming with content aggregation using AI SDK V3 protocol
  • Framework Agnostic - Works with Next.js, Hono, Express, and other frameworks

Installation

npm install ai-gateway-proxy

Usage

Next.js App Router

Create a catch-all route handler at app/api/ai/[...segments]/route.ts:
import { createGatewayProxy } from "ai-gateway-proxy";

export const { GET, POST, PUT, DELETE, PATCH } = createGatewayProxy();

Custom Catch-All Parameter Name

If your route uses a different parameter name (e.g., app/api/ai/[...path]/route.ts):
import { createGatewayProxy } from "ai-gateway-proxy";

export const { GET, POST, PUT, DELETE, PATCH } = createGatewayProxy({
  segmentsParam: "path",
});

Hono

For frameworks without catch-all route support, use the extractPath option:
import { Hono } from "hono";
import { createGatewayProxy } from "ai-gateway-proxy";

const app = new Hono();

const proxy = createGatewayProxy({
  extractPath: (request) => {
    const url = new URL(request.url);
    // Remove the base path prefix to get the gateway path
    return url.pathname.replace(/^\/api\/ai\//, "");
  },
});

// Handle all routes under /api/ai/*
app.all("/api/ai/*", (c) => proxy(c.req.raw));

export default app;

Express / Node.js

import express from "express";
import { createGatewayProxy } from "ai-gateway-proxy";

const app = express();

const proxy = createGatewayProxy({
  extractPath: (request) => {
    const url = new URL(request.url);
    return url.pathname.replace(/^\/api\/ai\//, "");
  },
});

app.all("/api/ai/*", async (req, res) => {
  const response = await proxy(req);
  // Convert Web Response to Express response
  res.status(response.status);
  response.headers.forEach((value, key) => res.setHeader(key, value));
  const body = await response.arrayBuffer();
  res.send(Buffer.from(body));
});

Configuration

Custom Base URL

createGatewayProxy({
  baseUrl: "https://ai-gateway.vercel.sh/v1/ai",
});

Additional Headers

createGatewayProxy({
  headers: {
    "x-custom-header": "value",
  },
});

Request Transformation

Transform the request body before forwarding to the gateway:
createGatewayProxy({
  beforeRequest: ({ request }) => {
    return {
      ...request,
      maxOutputTokens: 1000,
    };
  },
});

Response Transformation

Transform the response after receiving from the gateway. For streaming responses, this is called when the stream completes with aggregated content:
createGatewayProxy({
  afterResponse: ({ request, response }) => {
    console.log("Usage:", response.usage);
    return response;
  },
});

Error Handling

Custom error handling with the onError hook:
createGatewayProxy({
  onError: ({ request, error, status }) => {
    console.error("Gateway error:", error);

    // Return modified error
    return error;

    // Or return a custom Response
    // return new Response("Custom error", { status: 500 });
  },
});

Authentication

The proxy automatically handles authentication using one of the following methods (in order of priority):

API Key

Set the AI_GATEWAY_API_KEY environment variable:
AI_GATEWAY_API_KEY=your-api-key

OIDC (Vercel)

When deployed on Vercel, the proxy automatically uses Vercel OIDC for authentication. No additional configuration is required.

API Reference

createGatewayProxy(options?)

Creates a proxy handler for the AI Gateway.

Options

OptionTypeDefaultDescription
baseUrlstring"https://ai-gateway.vercel.sh/v1/ai"The base URL of the AI Gateway
headersRecord<string, string>{}Additional headers to include in requests
segmentsParamstring"segments"The name of the catch-all parameter in the route
extractPath(request: Request) => string | Promise<string>-Custom function to extract the path from the request. When provided, segmentsParam is ignored
beforeRequest(ctx) => request-Transform request body before forwarding
afterResponse(ctx) => response-Transform response after receiving (aggregated for streaming)
onError(ctx) => error | Response-Custom error handling

Returns

A handler function with named exports for HTTP methods: GET, POST, PUT, DELETE, PATCH.

getGatewayAuthToken()

Retrieves the authentication token for the AI Gateway.
import { getGatewayAuthToken } from "ai-gateway-proxy";

const auth = await getGatewayAuthToken();
// { token: "...", authMethod: "api-key" | "oidc" }

StreamContentAggregator

Aggregates streaming content into a complete response. Used internally by the proxy for afterResponse hooks on streaming requests.
import { StreamContentAggregator } from "ai-gateway-proxy";

const aggregator = new StreamContentAggregator();
aggregator.process(streamPart);
const response = aggregator.getResponse();

createStreamTransformer(body, requestBody, afterResponse)

Creates a transform stream that passes through SSE events while aggregating content and calling the afterResponse hook on completion.

Types

import type {
  CreateGatewayProxyOptions,
  CreateGatewayProxyFn,
  CreateGatewayProxyResult,
  GatewayResponse,
  GatewayError,
} from "ai-gateway-proxy";