Azure OpenAI api-version query parameter required or unsupported — pinning the right version (2026) — Fix Guide (2026) | AI Error Hub
Home Providers Azure OpenAI api-version required
Azure OpenAI SDK · API Version Severity: Medium HTTP 400

Azure OpenAI api-version required or unsupported

Every Azure OpenAI request needs an <code>api-version</code> query parameter — a small detail with a large impact when it drifts.

By Sana K. · Cloud AI Reliability Engineer Published 2026-07-26 Verified 2026-07-26

Quick fix (TL;DR)

Resolution: Azure OpenAI requires ?api-version=YYYY-MM-DD on every request URL. Missing → 400. Unsupported → 400. Preview versions are eventually retired → 400. Some features (JSON mode, tool_choice, o-series reasoning, DALL-E editing) require specific minimum versions. Fix by pinning to the current stable GA version (e.g. 2024-10-21), documenting the reason for the pin, and reviewing quarterly.

Real error messages you'll see

These are the exact strings returned by the Azure OpenAI service and its SDKs when this error occurs. Copy-paste-searching any of them should land on this page.

Missing api-version
openai.BadRequestError: Error code: 400 - {'error': {'code': '400', 'message': 'The api-version query parameter is required.'}}
Unsupported api-version
openai.BadRequestError: Error code: 400 - {'error': {'code': '400', 'message': "Resource not found: The api-version '2020-05-01' is not supported. "
"Supported versions are 2024-10-21, 2024-08-01-preview, 2024-07-01-preview..."}}
Feature not in this api-version
openai.BadRequestError: Error code: 400 - {'error': {'code': '400', 'message': 'The parameter tool_choice is not supported in api-version 2023-05-15.'}}

Reference

Which api-version to pin (as of Jul 2026)

api-versionStatusNotable featuresWhen to use
2024-10-21GA — recommended defaultgpt-4o, JSON mode, tool_choice, o1Most production workloads
2024-08-01-previewPreviewAssistants v2, batch APIOnly if you need preview features
2024-06-01GA — older stableJSON mode, toolsLegacy pinning; migrate to 2024-10-21
2024-02-01DeprecatedBasic chat + toolsDo not use
2023-12-01-previewRetiredDo not use
2023-05-15RetiredDo not use

Feature → minimum api-version matrix

FeatureMinimum api-versionNotes
gpt-4o + gpt-4o-mini2024-06-01Base chat works
JSON mode (response_format)2024-02-01Structured output type
Structured Outputs (schema)2024-08-01-previewJSON schema enforcement
tool_choice2024-02-01Force a specific tool
Parallel tool calls2024-08-01-previewOff by default; toggle
o1-series reasoning2024-09-01-previewReasoning tokens
o3-series reasoning2024-12-01-previewNewer reasoning
Batch API2024-07-01-previewJSONL batch submissions
DALL-E 3 with n>1Not supportedAlways n=1
stream_options2024-06-01Include usage in stream

Root causes, ranked by frequency

Based on developer reports across Azure OpenAI SDK forums, GitHub issues, and Microsoft Q&A during 2025–2026.

  • 30%
    Missing api-version query parameter. Copied a snippet from an openai.com example that does not include one. Azure requires it always.
  • 20%
    api-version pinned too old. Code was written against 2023-05-15 and never updated; version is now retired.
  • 16%
    Feature-version mismatch. Team upgraded to gpt-4o and structured outputs but the api-version does not support them — 400 with a clearer message.
  • 10%
    Preview version retired. Preview versions are retired more aggressively than GA; a version that worked last quarter now returns 400.
  • 8%
    Old openai package version. The Python openai package embeds a default api-version. Old packages default to old versions.
  • 6%
    Copy-paste of curl example with hardcoded version. Someone hardcoded a version in a script and never revised it.
  • 5%
    Different versions across environments. Dev on 2024-10-21, prod on 2024-06-01 — behavioural differences surface only in prod.
  • 5%
    Node.js SDK default lagging behind Python. Different language SDKs have different default versions.

Fixes — copy-paste solutions

Fix #1

Pin api-version at the client level, once

Every AOAI client instantiation must set api-version explicitly.

The SDK requires api_version in the constructor. Set it once, in a central client factory. Reference an environment variable so you can promote across dev/staging/prod without code changes.

client_factory.py
"""Central AOAI client factory. Import get_client() everywhere."""
import os
import logging
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

log = logging.getLogger(__name__)

# The current recommended GA version — reviewed quarterly
DEFAULT_API_VERSION = "2024-10-21"

def get_client() -> AzureOpenAI:
    api_version = os.getenv("AZURE_OPENAI_API_VERSION", DEFAULT_API_VERSION)
    log.info("Instantiating AOAI client with api_version=%s", api_version)

    if os.getenv("AZURE_OPENAI_API_KEY"):
        return AzureOpenAI(
            api_key=os.environ["AZURE_OPENAI_API_KEY"],
            azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
            api_version=api_version,
        )
    # Entra ID
    credential = DefaultAzureCredential()
    provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default")
    return AzureOpenAI(
        azure_ad_token_provider=provider,
        azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
        api_version=api_version,
    )

# Usage everywhere in your codebase
client = get_client()
Never scatter api_version="..." literals across files. Consolidate to one place — makes bumps a one-file change and lets you A/B test versions.
Fix #2

Add a startup probe that verifies feature support in the pinned version

Fail loudly at deploy time if the version does not support what you need.

When your app depends on JSON mode, structured outputs, or reasoning models, run a probe request at boot. If the api-version does not support the feature, crash immediately with a clear error — do not let production discover it.

startup_probe.py
"""Probe AOAI at startup to verify feature support in the pinned api-version."""
import logging
from openai import AzureOpenAI, BadRequestError

log = logging.getLogger(__name__)

def probe_json_mode(client: AzureOpenAI, deployment: str) -> bool:
    try:
        client.chat.completions.create(
            model=deployment,
            messages=[{"role": "user", "content": "Return {\"ok\": true} as JSON."}],
            response_format={"type": "json_object"},
            max_tokens=20,
        )
        return True
    except BadRequestError as e:
        log.error("JSON mode probe failed: %s", e)
        return False

def probe_tool_choice(client: AzureOpenAI, deployment: str) -> bool:
    tools = [{"type": "function", "function": {
        "name": "noop", "description": "no-op",
        "parameters": {"type": "object", "properties": {}}}}]
    try:
        client.chat.completions.create(
            model=deployment,
            messages=[{"role": "user", "content": "call noop"}],
            tools=tools,
            tool_choice={"type": "function", "function": {"name": "noop"}},
            max_tokens=20,
        )
        return True
    except BadRequestError as e:
        log.error("tool_choice probe failed: %s", e)
        return False

def startup_probes(client, deployment, required_features):
    checks = {
        "json_mode": probe_json_mode,
        "tool_choice": probe_tool_choice,
    }
    for feature in required_features:
        ok = checks[feature](client, deployment)
        if not ok:
            raise RuntimeError(
                f"Feature '{feature}' not supported by pinned api-version. "
                f"Upgrade AZURE_OPENAI_API_VERSION."
            )
        log.info("Feature check %s: OK", feature)

# In app startup
# startup_probes(client, deployment="gpt4o-prod",
#                required_features=["json_mode", "tool_choice"])
Costs one token per probe per feature per boot. Worth it — a version misalignment that surfaces at first user request is a P1 incident; one that surfaces at boot is a quick redeploy.
Fix #3

Set up a quarterly api-version review

Do not let the pin drift into deprecation.

Every quarter, review the pinned api-version, compare against the deprecation schedule, and plan any bump. This is a 30-minute meeting that prevents end-of-life 400s.

quarterly_review_checklist.md
# Quarterly Azure OpenAI api-version review

# 1) Current pinned version and where it is set
grep -r AZURE_OPENAI_API_VERSION infra/ config/ .env.*
grep -r api_version=\"20 src/    # find hardcoded versions in code

# 2) Check current status of the pinned version
# Azure OpenAI Reference docs -> API lifecycle table:
#   https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation

# 3) Is it approaching retirement (< 90 days)? If yes -> plan bump.
# 4) Are new features on newer versions that we would benefit from?
# 5) Any feature deprecations in newer versions that would break us?

# 6) Test bump in staging
export AZURE_OPENAI_API_VERSION=2024-11-01
pytest tests/aoai/  # covers all features you rely on
python startup_probe.py

# 7) Deploy to staging, run integration tests, monitor for 24h
# 8) Deploy to prod
# 9) Update the pinned version in docs and infra
# 10) Schedule next review 90 days out
Assign an owner. Reviews without owners are reviews that do not happen. 30 min every quarter costs less than one deprecation incident.

Prevention checklist

Ship these seven safeguards once and this error stops appearing in your logs.

  • Pin api-version in one central client factory — never inline across the codebase.
  • Reference an environment variable so you can promote versions across environments cleanly.
  • Add a startup probe for every feature your app depends on (JSON mode, tools, reasoning).
  • Log the api-version on every request in structured logs — makes drift instantly visible.
  • Set a calendar event for a quarterly api-version review with a named owner.
  • Sync openai / azure-identity package versions with the api-version — old packages can misdefault.
  • Test the next stable version in staging one month before you cut over — catches surprises.

Frequently asked questions

Azure hosts many customers with different rollout schedules. Pinning the api-version lets each customer opt-in to breaking changes on their own timeline. openai.com does the same thing implicitly via deprecations and cutovers, but on Azure it is explicit in the URL.
Preview versions include new features but may change or be retired with shorter notice. GA versions are stable for at least 12 months from GA date. Preview retirement is often 60-90 days; GA retirement is 6-12+ months.
Yes — the api-version is per URL. You can call chat/completions with 2024-10-21 and images/generations with 2024-08-01-preview from the same client. The SDK sets api-version at client-scope, but for advanced needs you can call REST with different versions.
Officially 60-90 days for preview versions and 6-12 months for GA. Notices are on the api-version deprecation page in Azure docs and in Service Health advisories. Subscribe to both.
Requests to the retired version return 400 with a message listing supported versions. This is a hard cut — no grace period. Bump the api-version and redeploy immediately. If you had the quarterly review process, you would not be here.

Get the weekly AI-error digest

New fixes, provider status recaps, and one deep tutorial — every Tuesday. 8,400+ engineers.