Heuristic:Openai Openai python Structured Output Strict Schema
| Knowledge Sources | |
|---|---|
| Domains | API_Client, Structured_Output |
| Last Updated | 2026-02-15 10:00 GMT |
Overview
When using Pydantic models for structured output or function tools, the SDK automatically converts schemas to strict mode by setting `additionalProperties: false` and making all properties required.
Description
The `to_strict_json_schema()` function in the SDK transforms Pydantic model schemas into the strict JSON Schema format required by OpenAI's Structured Outputs API. This transformation makes several mutations: it disallows additional properties on objects, makes all properties required (regardless of Python `Optional` declarations), resolves `$ref` references when mixed with other properties, flattens single-item `allOf` arrays, and removes `None` defaults. Understanding these transformations is critical when designing Pydantic models for use with function tools or structured output.
Usage
Apply this heuristic whenever you define Pydantic models for use with `client.chat.completions.create(response_format=...)`, `client.responses.create(text={"format": ...})`, or when defining function tools via `openai.pydantic_function_tool()`. Understanding the strict schema rules prevents unexpected validation errors.
The Insight (Rule of Thumb)
- Action: Define Pydantic models with explicit types; do not rely on default values being passed through.
- Value: All properties become required in the strict schema regardless of Python defaults. `None` defaults are removed.
- Trade-off: Strict mode limits flexibility but ensures the model always returns complete, well-structured data.
- Key rules:
- `additionalProperties` is automatically set to `False` for all object types
- All properties in an object are marked as `required`
- `$ref` references are resolved if mixed with other properties (e.g., a `description` alongside a `$ref`)
- Single-item `allOf` arrays are flattened to just the inner schema
- `None` default values are stripped from the schema
- Pydantic `TypeAdapter` is only supported with Pydantic v2+
Reasoning
OpenAI's Structured Outputs feature requires strict JSON schemas to guarantee that model outputs match the expected structure exactly. Without strict mode, the model might omit optional fields or include unexpected additional properties, leading to parsing failures downstream. The SDK's automatic conversion means developers can write natural Pydantic models and let the SDK handle the strict schema requirements.
Code evidence from `lib/_pydantic.py:16-24`:
def to_strict_json_schema(model):
if inspect.isclass(model) and is_basemodel_type(model):
schema = model_json_schema(model)
elif (not PYDANTIC_V1) and isinstance(model, pydantic.TypeAdapter):
schema = model.json_schema()
else:
raise TypeError(f"Non BaseModel types are only supported with Pydantic v2 - {model}")
return _ensure_strict_json_schema(schema, path=(), root=schema)
Strict enforcement from `lib/_pydantic.py:49-57`:
typ = json_schema.get("type")
if typ == "object" and "additionalProperties" not in json_schema:
json_schema["additionalProperties"] = False
properties = json_schema.get("properties")
if is_dict(properties):
json_schema["required"] = [prop for prop in properties.keys()]
Tool definition always uses strict mode from `lib/_tools.py:54-55`:
schema = to_strict_json_schema(model)