By Sagar Shankaran, Founder of CallSphere
Openai node.js sdk 4.x chat.completions.create example: A hands-on guide to the official OpenAI TypeScript SDK. Learn how to set up the client, create chat completions, implement function calling with tool definitions, and stream responses in a No…
Key takeaways
The official openai npm package provides a fully typed client for the OpenAI API. Unlike community wrappers, it is maintained by OpenAI and covers every endpoint — chat completions, embeddings, assistants, images, and audio — with complete TypeScript definitions.
This tutorial walks through the core patterns you need for building AI agent backends: client setup, chat completions, tool calling, and streaming.
Install the SDK and configure your client:
flowchart TD
USER(["User message"])
LLM["LLM call<br/>with tools schema"]
DECIDE{"Model wants<br/>to call a tool?"}
EXEC["Execute tool<br/>sandboxed runtime"]
RESULT["Append tool_result<br/>to messages"]
GUARD{"Output passes<br/>guardrails?"}
DONE(["Final reply"])
BLOCK(["Refuse and log"])
USER --> LLM --> DECIDE
DECIDE -->|Yes| EXEC --> RESULT --> LLM
DECIDE -->|No| GUARD
GUARD -->|Yes| DONE
GUARD -->|No| BLOCK
style LLM fill:#4f46e5,stroke:#4338ca,color:#fff
style EXEC fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
style GUARD fill:#f59e0b,stroke:#d97706,color:#1f2937
style DONE fill:#059669,stroke:#047857,color:#fff
style BLOCK fill:#dc2626,stroke:#b91c1c,color:#fff
npm install openai
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
The constructor accepts optional parameters for baseURL, timeout, maxRetries, and custom fetch implementations. For production, configure retries and timeouts explicitly:
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
maxRetries: 3,
timeout: 30_000, // 30 seconds
});
The chat completions endpoint is the foundation of every agent interaction. Here is a basic request with typed messages:
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
import OpenAI from "openai";
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
const messages: ChatCompletionMessageParam[] = [
{
role: "system",
content: "You are a helpful coding assistant specializing in TypeScript.",
},
{
role: "user",
content: "Explain the difference between interface and type in TypeScript.",
},
];
const completion = await client.chat.completions.create({
model: "gpt-4o",
messages,
temperature: 0.7,
max_tokens: 1024,
});
const reply = completion.choices[0].message.content;
console.log(reply);
The response is fully typed — completion.choices[0].message gives you a ChatCompletionMessage with role, content, tool_calls, and refusal fields.
Tool calling lets the model invoke functions you define. This is the mechanism that turns a chat model into an agent. You define tools as JSON Schema objects, the model decides when to call them, and your code executes the actual logic.
import type { ChatCompletionTool } from "openai/resources/chat/completions";
const tools: ChatCompletionTool[] = [
{
type: "function",
function: {
name: "get_weather",
description: "Get the current weather for a given city",
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "The city name, e.g., San Francisco",
},
units: {
type: "string",
enum: ["celsius", "fahrenheit"],
description: "Temperature unit preference",
},
},
required: ["city"],
},
},
},
];
Send the tools alongside messages and handle the model's tool call response:
const response = await client.chat.completions.create({
model: "gpt-4o",
messages,
tools,
tool_choice: "auto",
});
const message = response.choices[0].message;
if (message.tool_calls) {
for (const toolCall of message.tool_calls) {
const args = JSON.parse(toolCall.function.arguments);
let result: string;
if (toolCall.function.name === "get_weather") {
result = await fetchWeather(args.city, args.units);
} else {
result = JSON.stringify({ error: "Unknown tool" });
}
// Append the assistant's message and the tool result
messages.push(message);
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: result,
});
}
// Get the final response with tool results included
const finalResponse = await client.chat.completions.create({
model: "gpt-4o",
messages,
tools,
});
console.log(finalResponse.choices[0].message.content);
}
A real agent iterates until the model stops requesting tools:
async function runAgent(
client: OpenAI,
systemPrompt: string,
userMessage: string,
tools: ChatCompletionTool[],
maxIterations = 10
): Promise<string> {
const messages: ChatCompletionMessageParam[] = [
{ role: "system", content: systemPrompt },
{ role: "user", content: userMessage },
];
for (let i = 0; i < maxIterations; i++) {
const response = await client.chat.completions.create({
model: "gpt-4o",
messages,
tools,
});
const choice = response.choices[0];
messages.push(choice.message);
if (choice.finish_reason === "stop") {
return choice.message.content ?? "";
}
if (choice.message.tool_calls) {
for (const toolCall of choice.message.tool_calls) {
const result = await executeTool(toolCall);
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: JSON.stringify(result),
});
}
}
}
return "Agent reached maximum iterations.";
}
For real-time UIs, stream tokens as they arrive:
const stream = await client.chat.completions.create({
model: "gpt-4o",
messages,
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content;
if (delta) {
process.stdout.write(delta);
}
}
The stream is an async iterable. Each chunk contains a delta with partial content, tool call fragments, or finish reasons. The SDK handles reconnection and parsing automatically.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
The SDK automatically retries on 429 (rate limit) and 500-level errors using exponential backoff. Configure maxRetries in the constructor. For high-throughput applications, implement a token bucket or use the x-ratelimit-remaining-tokens response header to throttle proactively.
Yes. The tool_calls array can contain multiple entries when the model determines it needs several pieces of information simultaneously. Your agent loop should execute all of them (ideally in parallel with Promise.all) before sending the results back.
Setting tool_choice: "auto" lets the model decide whether to call a tool or respond directly. Setting tool_choice: "required" forces the model to call at least one tool. Use "required" when you know the user's request demands tool usage, such as data lookups or calculations.
#OpenAI #TypeScript #Nodejs #FunctionCalling #Streaming #ChatCompletions #AgenticAI #LearnAI #AIEngineering
This guide is written for engineers and operators evaluating openai node.js sdk 4.x chat.completions.create example in real production systems. The notes below give a plain-language reference for terms used throughout the article.
For teams that want to ship openai node.js sdk 4.x chat.completions.create example in voice and chat agents this quarter, CallSphere runs 37 agents and 90+ function tools across 6 verticals on a single dashboard. Start a 7-day free pilot, see live demo agents, or compare tiers on /pricing.

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
OpenAI's Frontier platform makes model-native orchestration the default. What that means for agent builders, voice/chat buyers, and the build-vs-buy decision.
GPT-Realtime-2 brings GPT-5-class reasoning into voice. What that means for tool-call reliability, structured output, and production agent design.
The 2026 desktop AI agent landscape — ServiceNow Project Arc, Anthropic Claude offerings, OpenAI agents, and Google Mariner. A buyer's map.
May 2026's biggest agent-architecture shift: planning, tool selection, and self-correction move inside the model. Framework code shrinks. Here is what changes.
A three-way comparison of Gemini Enterprise, Anthropic managed agents and OpenAI Frontier Platform after Cloud Next 2026 — strengths, gaps, buyer fit.
Anthropic's May 2026 push positions Claude as a vertical platform for financial services. The strategic positioning versus OpenAI and Google.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.
Try Live DemoBook a DemoCalculate Your ROI