Skip to content

Microsoft Azure / Foundry

Pydantic AI supports Azure OpenAI and other model deployments in Microsoft Foundry (formerly Azure AI Foundry), as well as Claude through the Anthropic SDK.

APIModel selection
Chat Completionsazure:<deployment-name>
Responsesazure-responses:<deployment-name>
Anthropic MessagesAnthropicModel with a Foundry client

Use your Azure deployment name as the model name. The examples below assume a deployment named gpt-5.2.

Install

Install Pydantic AI with the OpenAI SDK used by this integration:

Terminal
pip install "pydantic-ai-slim[openai]"

Configuration

To use Microsoft Foundry as your provider, set AZURE_OPENAI_ENDPOINT to a URL whose path ends in /v1 (for example https://<resource>.openai.azure.com/openai/v1/ or https://<resource>.services.ai.azure.com/openai/v1/), set AZURE_OPENAI_API_KEY, and use AzureProvider by name:

from pydantic_ai import Agent

agent = Agent('azure:gpt-5.2')
...

Or initialise the model and provider directly:

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.azure import AzureProvider

model = OpenAIChatModel(
    'gpt-5.2',
    provider=AzureProvider(
        azure_endpoint='https://your-resource.openai.azure.com/openai/v1/',
        api_key='your-api-key',
    ),
)
agent = Agent(model)
...

This targets the Azure OpenAI v1 API, which Microsoft recommends for all new projects. It also pairs naturally with the Responses API — see Using Azure with the Responses API below.

AzureProvider also recognises Microsoft Foundry serverless model deployments at https://<model>.<region>.models.ai.azure.com and connects to them the same way.

Connecting to an existing api-version-based deployment

If your resource still uses the dated api-version API, pass api_version (or set the OPENAI_API_VERSION environment variable) and point azure_endpoint at the resource root instead:

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.azure import AzureProvider

model = OpenAIChatModel(
    'gpt-5.2',
    provider=AzureProvider(
        azure_endpoint='https://your-resource.openai.azure.com/',
        api_version='2024-12-01-preview',
        api_key='your-api-key',
    ),
)
agent = Agent(model)
...

Using Azure with the Responses API

Microsoft Foundry also supports the OpenAI Responses API through OpenAIResponsesModel. This is particularly recommended when working with document inputs (DocumentUrl and BinaryContent), as Azure’s Chat Completions API does not support these input types.

Use the azure-responses: prefix to select the Responses API by name (the azure: prefix uses the Chat Completions API):

from pydantic_ai import Agent

agent = Agent('azure-responses:gpt-5.2')
...

Or initialise the model and provider directly, for example to process a document:

Document processing with Azure using Responses API
from pydantic_ai import Agent, BinaryContent
from pydantic_ai.models.openai import OpenAIResponsesModel
from pydantic_ai.providers.azure import AzureProvider

pdf_bytes = b'%PDF-1.4 ...'  # Your PDF content

model = OpenAIResponsesModel(
    'gpt-5.2',
    provider=AzureProvider(
        azure_endpoint='https://your-resource.openai.azure.com/openai/v1/',
        api_key='your-api-key',
    ),
)
agent = Agent(model)
result = agent.run_sync([
    'Summarize this document',
    BinaryContent(data=pdf_bytes, media_type='application/pdf'),
])

Prompt caching

On GPT-5.6 and later, Azure’s v1 API honors OpenAI’s explicit prompt caching settings: openai_prompt_cache_options, openai_cache_instructions and CachePoint markers, with both the Chat Completions and Responses APIs. Cache writes and reads are reported as cache_write_tokens and cache_read_tokens in the response’s usage, as on OpenAI. See Monitoring cache efficiency.

With the v1 API, an azure_endpoint (or an AsyncAzureOpenAI client’s base_url) ending in /openai/v1/, the unified cache setting and the Caching capability turn these on, as on OpenAI: cache=True sends openai_prompt_cache_options={'mode': 'implicit', 'ttl': '30m'} and turns on openai_cache_instructions, so separate conversations share the cached instructions. AzureProvider follows Microsoft’s documentation, which lists '30m' as the only TTL, so any requested retention, including '12h', snaps to it. Setting openai_prompt_cache_options or openai_cache_instructions yourself takes precedence over the unified setting.

from pydantic_ai import Agent
from pydantic_ai.capabilities import Caching
from pydantic_ai.models.openai import OpenAIResponsesModel
from pydantic_ai.providers.azure import AzureProvider

model = OpenAIResponsesModel(
    'gpt-6.1-sol',
    provider=AzureProvider(
        azure_endpoint='https://your-resource.openai.azure.com/openai/v1/',
        api_key='your-api-key',
    ),
)
agent = Agent(model, instructions='...', capabilities=[Caching()])
...

On api-version-based deployments and Azure AI Foundry serverless endpoints, the unified setting sends nothing, since they haven’t been verified to accept these fields.

Pydantic AI recognizes these models by the deployment name you pass as the model name, so this applies to deployments whose names start with gpt-5.6 or a GPT-6 model name, such as gpt-6-sol or gpt-6.1-sol (case-insensitive). For a deployment with another name, such as prod-chat, CachePoint markers, openai_cache_instructions and the unified setting are ignored. Pass a profile that turns breakpoints and the unified setting on, with its '30m' retention tier: it’s merged over the one AzureProvider provides.

from pydantic_ai.models.openai import OpenAIResponsesModel
from pydantic_ai.profiles.openai import OpenAIModelProfile
from pydantic_ai.providers.azure import AzureProvider

model = OpenAIResponsesModel(
    'prod-chat',
    provider=AzureProvider(
        azure_endpoint='https://your-resource.openai.azure.com/openai/v1/',
        api_key='your-api-key',
    ),
    profile=OpenAIModelProfile(
        openai_supports_prompt_cache_breakpoints=True,
        supports_cache=True,
        supported_cache_retentions=('30m',),
    ),
)

This has been verified on the v1 API with gpt-5.6-luna, gpt-6-sol, gpt-6-luna, gpt-6.1-sol and gpt-6-astra. It hasn’t been verified with gpt-6.1-terra, which wasn’t available to test, or on api-version-based deployments.

Grok tool schemas

For deployments whose names start with grok (case-insensitive), AzureProvider inlines non-recursive tool-schema definitions while retaining OpenAI’s schema conversion, including nested additionalProperties: false where applicable. This applies with both OpenAIChatModel and OpenAIResponsesModel.

Native structured output using NativeOutput with nested models still sends $defs and $ref. Tool-schema inlining does not apply to these output schemas.

Custom profile with OpenAIProvider

The generic openai: prefix and OpenAIProvider select OpenAI profiles even when OPENAI_BASE_URL or base_url points to Azure. To keep that provider, explicitly pass the profile returned by AzureProvider.model_profile. This reuses the Azure Grok tool-schema conversion and preserves native structured-output schemas.

from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIResponsesModel
from pydantic_ai.providers.azure import AzureProvider
from pydantic_ai.providers.openai import OpenAIProvider

model_name = 'grok-4-1-fast-reasoning'
model = OpenAIResponsesModel(
    model_name,
    provider=OpenAIProvider(
        base_url='https://your-resource.services.ai.azure.com/openai/v1/',
        api_key='your-api-key',
    ),
    profile=AzureProvider.model_profile(model_name),
)
agent = Agent(model)

Claude on Microsoft Foundry

For Claude, install the anthropic optional group and pass an AsyncAnthropicFoundry client to AnthropicProvider. See Claude on Microsoft Foundry for the example and Entra ID authentication guidance.