OpenAI Responses API
Status: Production Ready Last Updated: 2025-10-25 API Launch: March 2025 Dependencies: openai@5.19.1+ (Node.js) or fetch API (Cloudflare Workers)
What Is the Responses API?
The Responses API (/v1/responses) is OpenAI's unified interface for building agentic applications, launched in March 2025. It fundamentally changes how you interact with OpenAI models by providing stateful conversations and a structured loop for reasoning and acting.
Key Innovation: Preserved Reasoning State
Unlike Chat Completions where reasoning is discarded between turns, Responses keeps the notebook open. The model's step-by-step thought processes survive into the next turn, improving performance by approximately 5% on TAUBench and enabling better multi-turn interactions.
Why Use Responses Over Chat Completions?
| Feature | Chat Completions | Responses API | Benefit | |---------|-----------------|---------------|---------| | State Management | Manual (you track history) | Automatic (conversation IDs) | Simpler code, less error-prone | | Reasoning | Dropped between turns | Preserved across turns | Better multi-turn performance | | Tools | Client-side round trips | Server-side hosted | Lower latency, simpler code | | Output Format | Single message | Polymorphic (messages, reasoning, tool calls) | Richer debugging, better UX | | Cache Utilization | Baseline | 40-80% better | Lower costs, faster responses | | MCP Support | Manual integration | Built-in | Easy external tool connections |
Quick Start (5 Minutes)
1. Get API Key
# Sign up at https://platform.openai.com/
# Navigate to API Keys section
# Create new key and save securely
export OPENAI_API_KEY="sk-proj-..."
Why this matters:
- API key required for all requests
- Keep secure (never commit to git)
- Use environment variables
2. Install SDK (Node.js)
npm install openai
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const response = await openai.responses.create({
model: 'gpt-5',
input: 'What are the 5 Ds of dodgeball?',
});
console.log(response.output_text);
CRITICAL:
- Always use server-side (never expose API key in client code)
- Model defaults to
gpt-5(can usegpt-5-mini,gpt-4o, etc.) inputcan be string or array of messages
3. Or Use Direct API (Cloudflare Workers)
// No SDK needed - use fetch()
const response = await fetch('https://api.openai.com/v1/responses', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-5',
input: 'Hello, world!',
}),
});
const data = await response.json();
console.log(data.output_text);
Why fetch?
- No dependencies in edge environments
- Full control over request/response
- Works in Cloudflare Workers, Deno, Bun
Responses vs Chat Completions: Complete Comparison
When to Use Each
Use Responses API when:
- ✅ Building agentic applications (reasoning + actions)
- ✅ Need preserved reasoning state across turns
- ✅ Want built-in tools (Code Interpreter, File Search, Web Search)
- ✅ Using MCP servers for external integrations
- ✅ Implementing conversational AI with automatic state management
- ✅ Background processing for long-running tasks
- ✅ Need polymorphic outputs (messages, reasoning, tool calls)
Use Chat Completions when:
- ✅ Simple one-off text generation
- ✅ Fully stateless interactions (no conversation continuity needed)
- ✅ Legacy integrations (existing Chat Completions code)
- ✅ Very simple use cases without tools
Architecture Differences
Chat Completions Flow:
User Input → Model → Single Message → Done
(Reasoning discarded, state lost)
Responses API Flow:
User Input → Model (preserved reasoning) → Polymorphic Outputs
↓ (server-side tools)
Tool Call → Tool Result → Model → Final Response
(Reasoning preserved, state maintained)
Performance Benefits
Cache Utilization:
- Chat Completions: Baseline performance
- Responses API: 40-80% better cache utilization
- Result: Lower latency + reduced costs
Reasoning Performance:
- Chat Completions: Reasoning dropped between turns
- Responses API: Reasoning preserved across turns
- Result: 5% better on TAUBench (GPT-5 with Responses vs Chat Completions)
Stateful Conversations
Automatic State Management
The Responses API can automatically manage conversation state using conversation IDs.
Creating a Conversation
// Create conversation with initial message
const conversation = await openai.conversations.create({
metadata: { user_id: 'user_123' },
items: [
{
type: 'message',
role: 'user',
content: 'Hello!',
},
],
});
console.log(conversation.id); // "conv_abc123..."
Using Conversation ID
// First turn
const response1 = await openai.responses.create({
model: 'gpt-5',
conversation: 'conv_abc123',
input: 'What are the 5 Ds of dodgeball?',
});
console.log(response1.output_text);
// Second turn - model remembers previous context
const response2 = await openai.responses.create({
model: 'gpt-5',
conversation: 'conv_abc123',
input: 'Tell me more about the first one',
});
console.log(response2.output_text);
// Model automatically knows "first one" refers to first D from previous turn
Why this matters:
- No manual history tracking required
- Reasoning state preserved between turns
- Automatic context management
- Lower risk of context errors
Manual State Management (Alternative)
If you need full control, you can manually manage history:
let history = [
{ role: 'user', content: 'Tell me a joke' },
];
const response = await openai.responses.create({
model: 'gpt-5',
input: history,
store: true, // Optional: store for retrieval later
});
// Add response to history
history = [
...history,
...response.output.map(el => ({
role: el.role,
content: el.content,
})),
];
// Next turn
history.push({ role: 'user', content: 'Tell me another' });
const secondResponse = await openai.responses.create({
model: 'gpt-5',
input: history,
});
When to use manual management:
- Need custom history pruning logic
- Want to modify conversation history programmatically
- Implementing custom caching strategies
Built-in Tools (Server-Side)
The Responses API includes server-side hosted tools that eliminate costly backend round trips.
Available Tools
| Tool | Purpose | Use Case | |------|---------|----------| | Code Interpreter | Execute Python code | Data analysis, calculations, charts | | File Search | RAG without vector stores | Search uploaded files for answers | | Web Search | Real-time web information | Current events, fact-checking | | Image Generation | DALL-E integration | Create images from descriptions | | MCP | Connect external tools | Stripe, databases, custom APIs |
Code Interpreter
Execute Python code server-side for data analysis, calculations, and visualizations.
const response = await openai.responses.create({
model: 'gpt-5',
input: 'Calculate the mean, median, and mode of: 10, 20, 30, 40, 50',
tools: [{ type: 'code_interpreter' }],
});
console.log(response.output_text);
// Model writes and executes Python code, returns results
Advanced Example: Data Analysis
const response = await openai.responses.create({
model: 'gpt-5',
input: 'Analyze this sales data and create a bar chart showing monthly revenue: [data here]',
tools: [{ type: 'code_interpreter' }],
});
// Check output for code execution results
response.output.forEach(item => {
if (item.type === 'code_interpreter_call') {
console.log('Code executed:', item.