The official TypeScript library for the OpenAI API
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The OpenAI SDK provides helper functions for integrating with Zod, a TypeScript-first schema validation library. These helpers enable automatic parsing and validation of API responses and function tool arguments using Zod schemas.
openai/helpers/zodimport { zodResponseFormat, zodFunction, zodTextFormat, zodResponsesFunction } from 'openai/helpers/zod';
import { z } from 'zod';The Zod helpers provide four main functions:
These helpers automatically:
Creates a JSON Schema response format from a Zod schema for use with chat completions. When used with .parse(), .stream(), or .runTools(), responses will include a .parsed property with the validated, typed result.
/**
* Creates a chat completion JSONSchema response format object from a Zod schema
* @param zodObject - The Zod schema defining the expected response structure
* @param name - A name for the schema
* @param props - Optional additional properties for the response format
* @returns An AutoParseableResponseFormat that enables automatic parsing
*/
function zodResponseFormat<ZodInput extends z.ZodType>(
zodObject: ZodInput,
name: string,
props?: Omit<ResponseFormatJSONSchema.JSONSchema, 'schema' | 'strict' | 'name'>
): AutoParseableResponseFormat<z.infer<ZodInput>>;Usage Example:
import { zodResponseFormat } from 'openai/helpers/zod';
import OpenAI from 'openai';
import { z } from 'zod';
const client = new OpenAI();
// Define your schema
const MathResponse = z.object({
steps: z.array(z.object({
explanation: z.string(),
output: z.string(),
})),
final_answer: z.string(),
});
// Use with chat completions
const completion = await client.chat.completions.parse({
model: 'gpt-4o-2024-08-06',
messages: [
{ role: 'system', content: 'You are a helpful math tutor.' },
{ role: 'user', content: 'solve 8x + 31 = 2' },
],
response_format: zodResponseFormat(MathResponse, 'math_response'),
});
// Access parsed, typed result
const message = completion.choices[0]?.message;
if (message?.parsed) {
console.log(message.parsed.steps);
console.log(`Answer: ${message.parsed.final_answer}`);
}Creates a text JSON Schema response format from a Zod schema for use with the Responses API. Similar to zodResponseFormat but designed for text-based structured outputs.
/**
* Creates a text JSON Schema response format from a Zod schema
* @param zodObject - The Zod schema defining the expected response structure
* @param name - A name for the schema
* @param props - Optional additional properties for the format
* @returns An AutoParseableTextFormat that enables automatic parsing
*/
function zodTextFormat<ZodInput extends z.ZodType>(
zodObject: ZodInput,
name: string,
props?: Omit<ResponseFormatTextJSONSchemaConfig, 'schema' | 'type' | 'strict' | 'name'>
): AutoParseableTextFormat<z.infer<ZodInput>>;Usage Example:
import { zodTextFormat } from 'openai/helpers/zod';
import OpenAI from 'openai';
import { z } from 'zod';
const client = new OpenAI();
const UserData = z.object({
name: z.string(),
email: z.string().email(),
age: z.number().min(0),
});
const response = await client.responses.create({
model: 'gpt-4o',
input: 'Generate user data for John Smith',
response_format: zodTextFormat(UserData, 'user_data'),
});Creates a function tool with automatic argument parsing and validation using Zod schemas. Can be used with .runTools() for automatic function execution, or with .parse()/.stream() for automatic argument parsing.
/**
* Creates a chat completion function tool with Zod schema validation
* @param options - Configuration object
* @param options.name - The name of the function
* @param options.parameters - Zod schema for function parameters
* @param options.function - Optional callback function to execute
* @param options.description - Optional description of the function
* @returns An AutoParseableTool with typed, validated arguments
*/
function zodFunction<Parameters extends z.ZodType>(options: {
name: string;
parameters: Parameters;
function?: (args: z.infer<Parameters>) => unknown | Promise<unknown>;
description?: string;
}): AutoParseableTool<{
arguments: Parameters;
name: string;
function: (args: z.infer<Parameters>) => unknown;
}>;Usage Example:
import { zodFunction } from 'openai/helpers/zod';
import OpenAI from 'openai';
import { z } from 'zod';
const client = new OpenAI();
// Define parameter schema
const WeatherParams = z.object({
location: z.string(),
unit: z.enum(['celsius', 'fahrenheit']).optional(),
});
// Create function tool
const getWeather = zodFunction({
name: 'get_weather',
parameters: WeatherParams,
description: 'Get the current weather for a location',
function: async (args) => {
// Args are typed and validated as { location: string, unit?: 'celsius' | 'fahrenheit' }
const { location, unit = 'celsius' } = args;
// ... fetch weather data ...
return { temperature: 72, conditions: 'sunny' };
},
});
// Use with runTools for automatic execution
const completion = await client.chat.completions.runTools({
model: 'gpt-4o',
messages: [
{ role: 'user', content: 'What is the weather in San Francisco?' },
],
tools: [getWeather],
});With Manual Parsing:
// Use with parse() for validation only (no automatic execution)
const completion = await client.chat.completions.parse({
model: 'gpt-4o',
messages: [
{ role: 'user', content: 'What is the weather in San Francisco?' },
],
tools: [
zodFunction({
name: 'get_weather',
parameters: WeatherParams,
}),
],
});
// Access parsed arguments
const toolCall = completion.choices[0]?.message.tool_calls?.[0];
if (toolCall?.function.parsed_arguments) {
// Type-safe access to validated arguments
const { location, unit } = toolCall.function.parsed_arguments;
console.log(`Getting weather for ${location}`);
}Creates a function tool for the Responses API with Zod schema validation. Similar to zodFunction but designed for use with client.responses.create().
/**
* Creates a Responses API function tool with Zod schema validation
* @param options - Configuration object
* @param options.name - The name of the function
* @param options.parameters - Zod schema for function parameters
* @param options.function - Optional callback function to execute
* @param options.description - Optional description of the function
* @returns An AutoParseableResponseTool with typed, validated arguments
*/
function zodResponsesFunction<Parameters extends z.ZodType>(options: {
name: string;
parameters: Parameters;
function?: (args: z.infer<Parameters>) => unknown | Promise<unknown>;
description?: string;
}): AutoParseableResponseTool<{
arguments: Parameters;
name: string;
function: (args: z.infer<Parameters>) => unknown;
}>;Usage Example:
import { zodResponsesFunction } from 'openai/helpers/zod';
import OpenAI from 'openai';
import { z } from 'zod';
const client = new OpenAI();
const SearchParams = z.object({
query: z.string(),
max_results: z.number().min(1).max(100),
});
const searchTool = zodResponsesFunction({
name: 'search_database',
parameters: SearchParams,
description: 'Search the database for relevant information',
function: async (args) => {
const { query, max_results } = args;
// ... perform search ...
return { results: [...] };
},
});
const response = await client.responses.create({
model: 'gpt-4o',
input: 'Find recent orders',
tools: [searchTool],
});import { zodResponseFormat } from 'openai/helpers/zod';
import { z } from 'zod';
const CalendarEvent = z.object({
title: z.string(),
date: z.string().datetime(),
attendees: z.array(z.object({
name: z.string(),
email: z.string().email(),
})),
location: z.object({
name: z.string(),
address: z.string().optional(),
}).optional(),
});
const completion = await client.chat.completions.parse({
model: 'gpt-4o-2024-08-06',
messages: [
{ role: 'user', content: 'Extract calendar events from: "Team meeting tomorrow at 3pm with John and Jane"' },
],
response_format: zodResponseFormat(CalendarEvent, 'calendar_event'),
});try {
const completion = await client.chat.completions.parse({
model: 'gpt-4o-2024-08-06',
messages: [...],
response_format: zodResponseFormat(MySchema, 'my_schema'),
});
const message = completion.choices[0]?.message;
if (message?.parsed) {
// Successfully parsed and validated
console.log(message.parsed);
} else if (message?.refusal) {
// Model refused to respond
console.log('Refusal:', message.refusal);
}
} catch (error) {
// Parsing or validation error
console.error('Error:', error);
}interface AutoParseableResponseFormat<T> extends ResponseFormatJSONSchema {
$brand: 'auto-parseable-response-format';
$parseRaw(content: string): T;
}interface AutoParseableTextFormat<T> extends ResponseFormatTextJSONSchemaConfig {
$brand: 'auto-parseable-text-format';
$parseRaw(content: string): T;
}interface AutoParseableTool<T> extends ChatCompletionTool {
$brand: 'auto-parseable-tool';
$parseRaw(args: string): T;
$callback?: (args: T) => unknown | Promise<unknown>;
}interface AutoParseableResponseTool<T> {
type: 'function';
name: string;
parameters: Record<string, unknown>;
strict: boolean;
description?: string;
$brand: 'auto-parseable-response-tool';
$parseRaw(args: string): T;
$callback?: (args: T) => unknown | Promise<unknown>;
}Install with Tessl CLI
npx tessl i tessl/npm-openai