
# OpenAI SDK (TypeScript)

## Install

```bash
npm install openai
```

## A non-streaming completion

```ts
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.lowrouter.ai/v1",
  apiKey: process.env.LOWROUTER_API_KEY,
});

const response = await client.chat.completions.create({
  model: "auto/mistralai/mistral-large-2512",
  messages: [
    { role: "user", content: "In one sentence, what is a vector database?" },
  ],
});

console.log(response.choices[0].message.content);
```

## A streaming completion

```ts
const stream = await client.chat.completions.create({
  model: "auto/mistralai/mistral-large-2512",
  stream: true,
  messages: [{ role: "user", content: "Count to 5 slowly" }],
});

for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) process.stdout.write(delta);
}
```

## Reading the eco metadata

The TypeScript types do not include LowRouter's extra fields. Cast or
narrow when you read them:

```ts
type LowRouterMeta = {
  provider: string;
  region: string;
  energy_wh: number;
  carbon_gco2e: number;
  carbon_intensity_gco2_per_kwh: number;
  estimation_methodology: string;
  routing_mode: string;
  routing_reason: string;
  fallback_occurred: boolean;
  providers_attempted: string[];
};

const r = await client.chat.completions.create({ /* ... */ });
const meta = (r as unknown as { lowrouter_metadata?: LowRouterMeta })
  .lowrouter_metadata;
if (meta) {
  console.log(
    `${meta.carbon_gco2e.toFixed(4)} gCO2e via ${meta.provider} (${meta.region})`,
  );
}
```

## Pinning a region

There is no separate route field. Pin a region by appending a
UN/LOCODE as the fourth segment of the model ID
(`{provider}/{creator}/{model}/{locode}`); omit it to use the default
region:

```ts
const response = await client.chat.completions.create({
  model: "vertex/anthropic/claude-opus-4.6/sg-sin",
  messages: [{ role: "user", content: "hi" }],
});
```

## Browser usage

The OpenAI SDK warns against running with an API key in the browser
because the key is then exposed to every page visitor. The same
applies to LowRouter: keep your `LOWROUTER_API_KEY` server-side and
proxy requests from a backend you control. If you need a signed,
short-lived token for a browser client, server-side endpoint that
mints one is the right shape.
