Skip to content

OpenAI

Install

To use OpenAI models or OpenAI-compatible APIs, you need to either install pydantic-ai, or install pydantic-ai-slim with the openai optional group:

pip install "pydantic-ai-slim[openai]"
uv add "pydantic-ai-slim[openai]"

Configuration

To use OpenAIChatModel with the OpenAI API, go to platform.openai.com and follow your nose until you find the place to generate an API key.

Environment variable

Once you have the API key, you can set it as an environment variable:

export OPENAI_API_KEY='your-api-key'

You can then use OpenAIChatModel by name:

Learn about Gateway
from pydantic_ai import Agent

agent = Agent('gateway/openai:gpt-5')
...
from pydantic_ai import Agent

agent = Agent('openai:gpt-5')
...

Or initialise the model directly with just the model name:

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel

model = OpenAIChatModel('gpt-5')
agent = Agent(model)
...

By default, the OpenAIChatModel uses the OpenAIProvider with the base_url set to https://api.openai.com/v1.

Configure the provider

If you want to pass parameters in code to the provider, you can programmatically instantiate the OpenAIProvider and pass it to the model:

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

model = OpenAIChatModel('gpt-5', provider=OpenAIProvider(api_key='your-api-key'))
agent = Agent(model)
...

Custom OpenAI Client

OpenAIProvider also accepts a custom AsyncOpenAI client via the openai_client parameter, so you can customise the organization, project, base_url etc. as defined in the OpenAI API docs.

custom_openai_client.py
from openai import AsyncOpenAI

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

client = AsyncOpenAI(max_retries=3)
model = OpenAIChatModel('gpt-5', provider=OpenAIProvider(openai_client=client))
agent = Agent(model)
...

You could also use the AsyncAzureOpenAI client to use the Azure OpenAI API. Note that the AsyncAzureOpenAI is a subclass of AsyncOpenAI.

from openai import AsyncAzureOpenAI

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

client = AsyncAzureOpenAI(
    azure_endpoint='...',
    api_version='2024-07-01-preview',
    api_key='your-api-key',
)

model = OpenAIChatModel(
    'gpt-5',
    provider=OpenAIProvider(openai_client=client),
)
agent = Agent(model)
...

OpenAI Responses API

Pydantic AI also supports OpenAI's Responses API through the

You can use OpenAIResponsesModel by name:

Learn about Gateway
from pydantic_ai import Agent

agent = Agent('gateway/openai-responses:gpt-5')
...
from pydantic_ai import Agent

agent = Agent('openai-responses:gpt-5')
...

Or initialise the model directly with just the model name:

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIResponsesModel

model = OpenAIResponsesModel('gpt-5')
agent = Agent(model)
...

You can learn more about the differences between the Responses API and Chat Completions API in the OpenAI API docs.

Built-in tools

The Responses API has built-in tools that you can use instead of building your own:

  • Web search: allow models to search the web for the latest information before generating a response.
  • Code interpreter: allow models to write and run Python code in a sandboxed environment before generating a response.
  • Image generation: allow models to generate images based on a text prompt.
  • File search: allow models to search your files for relevant information before generating a response.
  • Computer use: allow models to use a computer to perform tasks on your behalf.

Web search, Code interpreter, Image generation, and File search are natively supported through the Built-in tools feature.

Computer use can be enabled by passing an openai.types.responses.ComputerToolParam in the openai_builtin_tools setting on OpenAIResponsesModelSettings. It doesn't currently generate BuiltinToolCallPart or BuiltinToolReturnPart parts in the message history, or streamed events; please submit an issue if you need native support for this built-in tool.

computer_use_tool.py
from openai.types.responses import ComputerToolParam

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIResponsesModel, OpenAIResponsesModelSettings

model_settings = OpenAIResponsesModelSettings(
    openai_builtin_tools=[
        ComputerToolParam(
            type='computer_use',
        )
    ],
)
model = OpenAIResponsesModel('gpt-5')
agent = Agent(model=model, model_settings=model_settings)

result = agent.run_sync('Open a new browser tab')
print(result.output)

Referencing earlier responses

The Responses API supports referencing earlier model responses in a new request using a previous_response_id parameter, to ensure the full conversation state including reasoning items are kept in context. This is available through the openai_previous_response_id field in OpenAIResponsesModelSettings.

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIResponsesModel, OpenAIResponsesModelSettings

model = OpenAIResponsesModel('gpt-5')
agent = Agent(model=model)

result = agent.run_sync('The secret is 1234')
model_settings = OpenAIResponsesModelSettings(
    openai_previous_response_id=result.all_messages()[-1].provider_response_id
)
result = agent.run_sync('What is the secret code?', model_settings=model_settings)
print(result.output)
#> 1234

By passing the provider_response_id from an earlier run, you can allow the model to build on its own prior reasoning without needing to resend the full message history.

Automatically referencing earlier responses

When the openai_previous_response_id field is set to 'auto', Pydantic AI will automatically select the most recent provider_response_id from message history and omit messages that came before it, letting the OpenAI API leverage server-side history instead for improved efficiency.

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIResponsesModel, OpenAIResponsesModelSettings

model = OpenAIResponsesModel('gpt-5')
agent = Agent(model=model)

result1 = agent.run_sync('Tell me a joke.')
print(result1.output)
#> Did you hear about the toothpaste scandal? They called it Colgate.

# When set to 'auto', the most recent provider_response_id
# and messages after it are sent as request.
model_settings = OpenAIResponsesModelSettings(openai_previous_response_id='auto')
result2 = agent.run_sync(
    'Explain?',
    message_history=result1.new_messages(),
    model_settings=model_settings
)
print(result2.output)
#> This is an excellent joke invented by Samuel Colvin, it needs no explanation.

OpenAI-compatible Models

Many providers and models are compatible with the OpenAI API, and can be used with OpenAIChatModel in Pydantic AI. Before getting started, check the installation and configuration instructions above.

To use another OpenAI-compatible API, you can make use of the base_url and api_key arguments from OpenAIProvider:

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

model = OpenAIChatModel(
    'model_name',
    provider=OpenAIProvider(
        base_url='https://<openai-compatible-api-endpoint>', api_key='your-api-key'
    ),
)
agent = Agent(model)
...

Various providers also have their own provider classes so that you don't need to specify the base URL yourself and you can use the standard <PROVIDER>_API_KEY environment variable to set the API key. When a provider has its own provider class, you can use the Agent("<provider>:<model>") shorthand, e.g. Agent("deepseek:deepseek-chat") or Agent("moonshotai:kimi-k2-0711-preview"), instead of building the OpenAIChatModel explicitly. Similarly, you can pass the provider name as a string to the provider argument on OpenAIChatModel instead of building instantiating the provider class explicitly.

Model Profile

Sometimes, the provider or model you're using will have slightly different requirements than OpenAI's API or models, like having different restrictions on JSON schemas for tool definitions, or not supporting tool definitions to be marked as strict.

When using an alternative provider class provided by Pydantic AI, an appropriate model profile is typically selected automatically based on the model name. If the model you're using is not working correctly out of the box, you can tweak various aspects of how model requests are constructed by providing your own ModelProfile (for behaviors shared among all model classes) or OpenAIModelProfile (for behaviors specific to OpenAIChatModel):

from pydantic_ai import Agent, InlineDefsJsonSchemaTransformer
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.profiles.openai import OpenAIModelProfile
from pydantic_ai.providers.openai import OpenAIProvider

model = OpenAIChatModel(
    'model_name',
    provider=OpenAIProvider(
        base_url='https://<openai-compatible-api-endpoint>.com', api_key='your-api-key'
    ),
    profile=OpenAIModelProfile(
        json_schema_transformer=InlineDefsJsonSchemaTransformer,  # Supported by any model class on a plain ModelProfile
        openai_supports_strict_tool_definition=False  # Supported by OpenAIModel only, requires OpenAIModelProfile
    )
)
agent = Agent(model)

Supported Providers

The following providers offer OpenAI-compatible APIs and have dedicated documentation pages: