If your app uses the OpenAI Node SDK, the integration is one parameter on client construction — no new package, no wrapper function, no restructuring of how you call the API. Here's the exact code, the environment variable pattern, and notes for the frameworks most Node apps are actually built on.

The Core Change

// Before
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// After — same SDK, same calls, different baseURL
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: "https://proxy.preto.ai/v1/YOUR-KEY",
});

// Everything below this line is unchanged
const response = await client.chat.completions.create({
  model: "gpt-5-mini",
  messages: [{ role: "user", content: "Hello" }],
});

Your OpenAI API key stays exactly where it is — Preto forwards the request using your key, it doesn't intercept or replace your credentials.

Use an Environment Variable, Not a Hardcoded URL

// .env
OPENAI_BASE_URL=https://proxy.preto.ai/v1/YOUR-KEY

// your app
const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: process.env.OPENAI_BASE_URL, // undefined falls back to SDK default
});

This lets staging point at the proxy while production stays on the direct provider URL until you're confident, and the eventual cutover in production is a config change — no code deploy required.

Streaming Works Unchanged

const stream = await client.chat.completions.create({
  model: "gpt-5-mini",
  messages: [{ role: "user", content: "Hello" }],
  stream: true,
});

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

Preto pipes streamed tokens through as they arrive from the provider — your client starts receiving output as soon as it's generated, with negligible added latency to time-to-first-token.

Ready to grab your proxy URL?

Your unique proxy endpoint is waiting in your dashboard.

Copy the Code Snippet

One line. One import change. Your costs appear in Preto immediately.

Framework-Specific Notes

Express. Initialize the client once at app startup — a module-level singleton — rather than constructing a new client inside each route handler. The baseURL is set once at construction, so nothing else about your route logic needs to change.
Next.js (API routes and server actions). Since only the client construction changes, this works identically whether the OpenAI client lives in a route handler, a server action, or a shared lib file imported across both. If you're already centralizing the client in a single module (the common pattern), you're changing one file.
Serverless (Lambda, Vercel Functions). Initialize the client outside the handler function where your runtime supports connection reuse across invocations — the same best practice you'd already follow for any external client, unrelated to the proxy change itself.

Verifying It's Working

Trigger one real request through your app — whatever call it already makes normally. Two checks confirm success: the response your app receives is unchanged (Preto forwards the provider's response exactly as returned), and the request shows up in your Preto dashboard within about a minute. If both hold, you're done.

TypeScript Types Are Unaffected

Since baseURL is already a documented, typed constructor option on the OpenAI SDK client, there's no type augmentation or `any` casting required — your existing TypeScript setup works exactly as it did before the change.

Running a Python service alongside your Node app? The Python integration guide covers the equivalent setup. And once data starts flowing in, here's what to look at first.

Frequently Asked Questions

Do I need to change my OpenAI Node SDK code to use Preto?
No — only the baseURL parameter changes. Every other call and response handler in your codebase stays exactly as it is.
Should I hardcode the proxy URL or use an environment variable?
Use an environment variable. It lets you test staging against the proxy before touching production, and the eventual cutover becomes a config change rather than a code change.
Does this work with streaming responses?
Yes. Preto passes streamed responses through as they arrive — your client starts receiving tokens as soon as the provider generates them, with negligible added overhead to time-to-first-token.
Does this work in Next.js API routes and server actions?
Yes. Since the change is just the baseURL parameter on client construction, it works identically regardless of which Node.js server context the client is instantiated in.

Grab your proxy URL and connect in the next few minutes.

Your unique endpoint is ready in your dashboard — copy it, set the environment variable, and your first request will show up within a minute.

Copy the Code Snippet

Questions about your specific setup? Reply to your welcome email.

Gaurav Dagade
Gaurav Dagade

Founder of Preto.ai. 11 years engineering leadership. Previously Engineering Manager at Bynry. Building the cost intelligence layer for AI infrastructure.

LinkedIn · Twitter