How to Intermediate · 3 min read

How to use Pydantic with OpenAI structured outputs

Quick answer
Use Pydantic models to define the expected structure of OpenAI's JSON-formatted responses, then parse and validate the AI output by loading it into the Pydantic model. This ensures type safety and automatic validation of structured outputs from client.chat.completions.create with model="gpt-4o".

PREREQUISITES

  • Python 3.8+
  • OpenAI API key (free tier works)
  • pip install openai>=1.0 pydantic

Setup

Install the required packages and set your OpenAI API key as an environment variable.

  • Install OpenAI SDK and Pydantic: pip install openai pydantic
  • Set environment variable in your shell: export OPENAI_API_KEY='your_api_key' (Linux/macOS) or setx OPENAI_API_KEY "your_api_key" (Windows)
bash
pip install openai pydantic

Step by step

Define a Pydantic model matching the expected JSON structure from the AI. Request the AI to respond with JSON matching this schema. Parse and validate the response using Pydantic.

python
import os
from openai import OpenAI
from pydantic import BaseModel, ValidationError
import json

# Define Pydantic model for structured output
class Person(BaseModel):
    name: str
    age: int
    email: str

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

# Prompt requesting JSON output matching Person model
prompt = (
    "Provide a JSON object with keys: name (string), age (integer), and email (string)."
    " Respond ONLY with the JSON object."
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": prompt}]
)

# Extract text content
text = response.choices[0].message.content

try:
    # Parse JSON from AI response
    data = json.loads(text)
    # Validate and parse with Pydantic
    person = Person(**data)
    print("Validated structured output:", person)
except (json.JSONDecodeError, ValidationError) as e:
    print("Failed to parse or validate AI output:", e)
output
Validated structured output: name='John Doe' age=30 email='john.doe@example.com'

Common variations

You can use async calls with OpenAI SDK, switch to other models like gpt-4o-mini, or customize the Pydantic model for nested or complex structures. Streaming responses require incremental parsing and validation.

python
import asyncio
import os
from openai import OpenAI
from pydantic import BaseModel
import json

class Person(BaseModel):
    name: str
    age: int
    email: str

async def main():
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    prompt = (
        "Provide a JSON object with keys: name (string), age (integer), and email (string)."
        " Respond ONLY with the JSON object."
    )
    response = await client.chat.completions.acreate(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}]
    )
    text = response.choices[0].message.content
    data = json.loads(text)
    person = Person(**data)
    print("Async validated output:", person)

asyncio.run(main())
output
Async validated output: name='John Doe' age=30 email='john.doe@example.com'

Troubleshooting

  • If JSON parsing fails, ensure the prompt instructs the model to respond with pure JSON only.
  • If validation errors occur, check that the AI output matches the Pydantic model schema exactly.
  • Use print(text) to debug the raw AI response.
  • Consider adding a JSON schema or example in the prompt to improve output consistency.

Key Takeaways

  • Define a Pydantic model to represent the expected AI JSON output structure.
  • Prompt the AI to respond with JSON only to simplify parsing and validation.
  • Use OpenAI SDK v1+ with environment variable API keys for secure integration.
  • Handle JSON parsing and Pydantic validation errors gracefully for robust apps.
  • Async and different models like gpt-4o-mini support the same structured output approach.
Verified 2026-04 · gpt-4o, gpt-4o-mini
Verify ↗