Implementation:Openai Openai node Zod Helpers
| Knowledge Sources | |
|---|---|
| Domains | SDK, Structured_Output, Validation |
| Last Updated | 2026-02-15 12:00 GMT |
Overview
The Zod helpers module provides integration functions that convert Zod schemas into OpenAI-compatible JSON Schema formats for structured outputs, enabling automatic response parsing with zodResponseFormat, zodTextFormat, zodFunction, and zodResponsesFunction.
Description
This module bridges the Zod schema validation library with the OpenAI API's structured output capabilities. It supports both Zod v3 and Zod v4 schemas, auto-detecting the version via an isZodV4 check (looking for the _zod property). For Zod v3, schemas are converted using a vendored zodToJsonSchema with OpenAI strict mode settings. For Zod v4, the native z4.toJSONSchema is used targeting draft-7, then passed through toStrictJsonSchema for OpenAI compatibility.
zodResponseFormat creates an AutoParseableResponseFormat for use with client.chat.completions.parse(), .stream(), and .runTools(). It wraps a Zod schema as a json_schema response format with strict: true, and attaches a parser function that deserializes JSON content through the Zod schema. zodTextFormat serves a similar purpose for the Responses API text format.
zodFunction creates an AutoParseableTool for chat completions tool calling, converting Zod-defined parameters into a strict JSON Schema function definition with an optional callback. zodResponsesFunction does the same for the Responses API tool format, producing an AutoParseableResponseTool. Both functions attach a parser that validates tool call arguments through the Zod schema.
Usage
Use these helpers whenever you want type-safe, automatically validated structured outputs from OpenAI API calls. zodResponseFormat is the primary entry point for structured output with chat completions, while zodFunction enables schema-validated tool definitions. These functions eliminate manual JSON Schema authoring and provide end-to-end type safety from schema definition through response parsing.
Code Reference
Source Location
- Repository: openai-node
- File: src/helpers/zod.ts
Signature
export function zodResponseFormat<ZodInput extends z3.ZodType | z4.ZodType>(
zodObject: ZodInput,
name: string,
props?: Omit<ResponseFormatJSONSchema.JSONSchema, 'schema' | 'strict' | 'name'>,
): AutoParseableResponseFormat<InferZodType<ZodInput>>;
export function zodTextFormat<ZodInput extends z3.ZodType | z4.ZodType>(
zodObject: ZodInput,
name: string,
props?: Omit<ResponseFormatTextJSONSchemaConfig, 'schema' | 'type' | 'strict' | 'name'>,
): AutoParseableTextFormat<InferZodType<ZodInput>>;
export function zodFunction<Parameters extends z3.ZodType | z4.ZodType>(options: {
name: string;
parameters: Parameters;
function?: ((args: InferZodType<Parameters>) => unknown | Promise<unknown>) | undefined;
description?: string | undefined;
}): AutoParseableTool<{ arguments: Parameters; name: string; function: (args: InferZodType<Parameters>) => unknown }>;
export function zodResponsesFunction<Parameters extends z3.ZodType | z4.ZodType>(options: {
name: string;
parameters: Parameters;
function?: ((args: InferZodType<Parameters>) => unknown | Promise<unknown>) | undefined;
description?: string | undefined;
}): AutoParseableResponseTool<{ arguments: Parameters; name: string; function: (args: InferZodType<Parameters>) => unknown }>;
Import
import { zodResponseFormat, zodTextFormat, zodFunction, zodResponsesFunction } from 'openai/helpers/zod';
I/O Contract
Inputs (zodResponseFormat)
| Name | Type | Required | Description |
|---|---|---|---|
| zodObject | z4.ZodType | Yes | The Zod schema defining the expected response structure. |
| name | string |
Yes | The name for the JSON schema, used in the API request. |
| props | 'strict' | 'name'> | No | Additional JSON schema properties (e.g. description).
|
Inputs (zodFunction)
| Name | Type | Required | Description |
|---|---|---|---|
| name | string |
Yes | The function name for the tool definition. |
| parameters | z4.ZodType | Yes | The Zod schema defining the function's parameters. |
| function | (args: InferZodType<Parameters>) => unknown |
No | An optional callback invoked with parsed arguments during runTools().
|
| description | string |
No | A description of the function for the model. |
Outputs
| Name | Type | Description |
|---|---|---|
| zodResponseFormat return | AutoParseableResponseFormat<T> |
A response format object with type: "json_schema", strict: true, and an attached parser. Pass to response_format in chat completion requests.
|
| zodTextFormat return | AutoParseableTextFormat<T> |
A text format object for the Responses API with type: "json_schema", strict: true, and an attached parser.
|
| zodFunction return | AutoParseableTool<T> |
A tool definition with strict JSON Schema parameters and automatic argument parsing. |
| zodResponsesFunction return | AutoParseableResponseTool<T> |
A Responses API tool definition with strict JSON Schema parameters and automatic argument parsing. |
Usage Examples
import OpenAI from 'openai';
import { zodResponseFormat, zodFunction } from 'openai/helpers/zod';
import { z } from 'zod';
const client = new OpenAI();
// Structured output with zodResponseFormat
const MathAnswer = z.object({
steps: z.array(z.object({
explanation: z.string(),
answer: z.string(),
})),
final_answer: z.string(),
});
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(MathAnswer, 'math_answer'),
});
const message = completion.choices[0]?.message;
if (message?.parsed) {
console.log(message.parsed.final_answer);
}
// Tool calling with zodFunction
const getWeather = zodFunction({
name: 'get_weather',
parameters: z.object({
location: z.string().describe('City name'),
unit: z.enum(['celsius', 'fahrenheit']).optional(),
}),
description: 'Get the current weather for a location',
function: async ({ location, unit }) => {
return { temperature: 22, unit: unit ?? 'celsius', location };
},
});
const runner = client.chat.completions.runTools({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'What is the weather in Paris?' }],
tools: [getWeather],
});
const result = await runner.finalChatCompletion();