Guides
How to Integrate the OpenAI API With Next.js
This covers calling the OpenAI API from a Route Handler, streaming the response back to the client for a responsive UI, and the error handling and cost controls worth having from the start.
Prerequisites
- arrow_rightAn OpenAI API key
- arrow_rightA Next.js App Router project
- arrow_rightThe openai npm package installed
Step 1: Create a Route Handler
app/api/chat/route.ts
import OpenAI from 'openai';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export async function POST(request: Request) {
const { message } = await request.json();
const completion = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: message }],
});
return Response.json({ reply: completion.choices[0].message.content });
}Step 2: Stream the Response
const stream = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: message }],
stream: true,
});
const encoder = new TextEncoder();
const readable = new ReadableStream({
async start(controller) {
for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content ?? '';
controller.enqueue(encoder.encode(text));
}
controller.close();
},
});
return new Response(readable);Streaming shows the response as it's generated instead of waiting for the full completion, which meaningfully improves perceived speed for longer responses.
Step 3: Handle Errors and Rate Limits
Wrap the API call in a try/catch, handle rate limit (429) responses with a retry-with-backoff strategy, and set a reasonable timeout so a slow or hanging request doesn't leave the user waiting indefinitely.
Common Errors
- arrow_rightAPI key exposed in client-side code — the OpenAI API must only ever be called from server code (Route Handlers, server components), never directly from the browser
- arrow_rightNo error handling around the API call, so a transient failure crashes the request instead of degrading gracefully
- arrow_rightNo cost monitoring, leading to a surprise bill if usage spikes unexpectedly
Security & Cost Considerations
- arrow_rightKeep the API key server-side only, in an environment variable never exposed to the client
- arrow_rightSet per-user or per-session usage limits to control cost
- arrow_rightChoose the smallest model that reliably handles the task — cost scales directly with tokens processed
Frequently Asked Questions
Can I call the OpenAI API directly from a client component?add
No — this would expose your API key in the browser, where anyone could extract and misuse it. Always route the call through a server-side Route Handler.
How do I stream a response to a React component?add
The Route Handler returns a ReadableStream response, which the client reads incrementally (via fetch's response.body reader, or a library like the Vercel AI SDK that wraps this pattern) to update the UI as text arrives.
Which model should I default to?add
A smaller, faster model (like gpt-4o-mini) is often sufficient and considerably cheaper for most tasks; reserve larger models for genuinely complex reasoning tasks where the smaller model's output quality falls short.