OpenAI SDK Patterns
Quick Guide: Use the officialopenainpm package (v6+) to interact with OpenAI's API directly. Useclient.responses.create()(Responses API) for new projects with built-in tools and server-side state, orclient.chat.completions.create()(Chat Completions) for stateless chat flows. UsezodResponseFormatandclient.chat.completions.parse()for structured outputs. Use.stream()orstream: truefor streaming. Supports GPT-5.x family, GPT-4o, o4-mini, embeddings, vision, audio, and batch processing.
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)
(You MUST use the Responses API (client.responses.create()) for new projects -- it provides better performance, built-in tools, and server-side conversation state)
(You MUST use zodResponseFormat() from openai/helpers/zod for structured outputs -- do NOT manually construct JSON schemas)
(You MUST handle errors using OpenAI.APIError and its subclasses -- never use bare catch blocks without error type checking)
(You MUST configure appropriate retries and timeouts for production use -- the SDK retries 2 times by default on 429/5xx errors)
(You MUST never hardcode API keys -- always use environment variables via process.env.OPENAI_API_KEY)
</critical_requirements>
Auto-detection: OpenAI, openai, client.chat.completions, client.responses.create, client.responses.parse, client.embeddings, client.audio, zodResponseFormat, zodTextFormat, zodFunction, zodResponsesFunction, runTools, GPT-5, GPT-4o, o4-mini, gpt-5-mini, text-embedding-3, whisper, tts, OPENAI_API_KEY, toFile
When to use:
- Building applications that call OpenAI models directly (GPT-5.x, GPT-4o, o4-mini, etc.)
- Implementing chat completions with streaming responses
- Using the Responses API for agentic workflows with built-in tools (web search, file search, code interpreter)
- Extracting structured data from LLM responses with Zod schema validation
- Implementing function calling / tool use with the Chat Completions or Responses API
- Creating embeddings for RAG pipelines or semantic search
- Processing images with vision models or audio with Whisper/TTS
- Running batch jobs for high-volume, cost-efficient processing
Key patterns covered:
- Client initialization and configuration (retries, timeouts, proxies)
- Chat Completions API (messages, streaming, function calling)
- Responses API (input, instructions, built-in tools, server-side state)
- Structured outputs with
zodResponseFormatandclient.chat.completions.parse() - Streaming with
for await...of,.stream()helper, and event handling - Embeddings API (
text-embedding-3-small,text-embedding-3-large) - Vision (image URLs, base64), Audio (Whisper transcription, TTS), Batch API
- Error handling, retries, timeouts, and production best practices
When NOT to use:
- Multi-provider applications where you need to switch between OpenAI, Anthropic, Google, etc. -- use a unified provider SDK instead
- React-specific chat UI hooks (
useChat,useCompletion) -- use a framework-integrated AI SDK - When you need a higher-level abstraction over multiple LLM providers
Examples Index
- [Core: Setup & Configuration](examples/core.md) -- Client init, production config, Azure, error handling, request overrides
- [Chat Completions](examples/chat.md) -- Basic chat, multi-turn, token tracking, output length control
- [Streaming](examples/streaming.md) --
stream: true,.stream()helper, Responses API streaming, abort - [Tool/Function Calling](examples/tools.md) -- Manual tools,
zodFunction,runToolsautomation, Responses API tools - [Structured Output](examples/structured-output.md) --
zodResponseFormat,zodTextFormat, refusal handling - [Embeddings, Vision & Audio](examples/embeddings-vision-audio.md) -- Semantic search, image analysis, transcription, TTS, batch processing
- [Quick API Reference](reference.md) -- Model IDs, method signatures, error types, streaming events
<philosophy>
Philosophy
The official OpenAI SDK provides direct, low-level access to OpenAI's full API surface. It is the thinnest possible wrapper over the REST API, auto-generated from OpenAI's OpenAPI specification using Stainless.
Core principles:
- Direct API access -- No abstractions or provider layers. You get the exact API that OpenAI documents, with full TypeScript types. Every API feature is available immediately when OpenAI releases it.
- Two API paradigms -- The Responses API (
client.responses.create()) is the newer, recommended API with built-in tools and server-side state. The Chat Completions API (client.chat.completions.create()) remains fully supported for stateless chat flows. - Built-in resilience -- The SDK handles retries (2 by default on 429/5xx), timeouts (10 min default), and auto-pagination out of the box.
- Streaming as a first-class pattern -- Use
stream: truefor SSE-based streaming,.stream()helper for event-based consumption, orfor await...offor simple iteration. - Type-safe structured outputs --
zodResponseFormat()andclient.chat.completions.parse()convert Zod schemas to JSON Schema and parse responses, giving you validated, typed objects.
When to use the OpenAI SDK directly:
- You only use OpenAI models and want the simplest, most direct integration
- You need access to OpenAI-specific features (Responses API, Batch, Realtime)
- You want minimal dependencies and zero abstraction overhead
- You need the latest API features on day one
When NOT to use:
- You need to switch between providers (OpenAI, Anthropic, Google) -- use a unified provider SDK
- You want React-specific chat UI hooks -- use a framework-integrated AI SDK
- You want a higher-level agent framework -- consider OpenAI Agents SDK (
@openai/agents)
</philosophy>
<patterns>
Core Patterns
Pattern 1: Client Setup
Initialize the OpenAI client. It auto-reads OPENAI_API_KEY from the environment.
// lib/openai.ts -- basic setup
import OpenAI from "openai";
const client = new OpenAI();
export { client };
// lib/openai.ts -- production configuration
const TIMEOUT_MS = 30_000;
const MAX_RETRIES = 3;
const client = new OpenAI({ timeout: TIMEOUT_MS, maxRetries: MAX_RETRIES });
Why good: Minimal setup, env var auto-detected, named constants for production settings
See: [examples/core.md](examples/core.md) for Azure OpenAI, per-request overrides, error handling patterns
Pattern 2: Chat Completions API
Stateless text generation. You manage conversation history.
const completion = await client.chat.completions.create({
model: "gpt-4o",
messages: [
{ role: "developer", content: "You are a helpful coding assistant." },
{ role: "user", content: "Explain TypeScript generics." },
],
});
console.log(completion.choices[0].message.content);
Why good: Clear message roles, developer message for system instructions, direct content access
// BAD: No developer message, no error handling
const res = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "do something" }],
});
Why bad: No system instruction means unpredictable behavior, vague prompt
See: [examples/chat.md](examples/chat.md) for multi-turn, token tracking, output length control
Pattern 3: Responses API (Recommended for New Projects)
Newer API with built-in tools, server-side state, and better performance with reasoning models.
const response = await client.responses.create({
model: "gpt-4o",
instructions: "You are a coding assistant.",
input: "What are TypeScript generics?",
});
console.log(response.output_text);
Why good: Clean