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.
Quick fix (TL;DR)
?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.
openai.BadRequestError: Error code: 400 - {'error': {'code': '400', 'message': 'The api-version query parameter is required.'}}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..."}}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-version | Status | Notable features | When to use |
|---|---|---|---|
2024-10-21 | GA — recommended default | gpt-4o, JSON mode, tool_choice, o1 | Most production workloads |
2024-08-01-preview | Preview | Assistants v2, batch API | Only if you need preview features |
2024-06-01 | GA — older stable | JSON mode, tools | Legacy pinning; migrate to 2024-10-21 |
2024-02-01 | Deprecated | Basic chat + tools | Do not use |
2023-12-01-preview | Retired | — | Do not use |
2023-05-15 | Retired | — | Do not use |
Feature → minimum api-version matrix
| Feature | Minimum api-version | Notes |
|---|---|---|
| gpt-4o + gpt-4o-mini | 2024-06-01 | Base chat works |
JSON mode (response_format) | 2024-02-01 | Structured output type |
| Structured Outputs (schema) | 2024-08-01-preview | JSON schema enforcement |
| tool_choice | 2024-02-01 | Force a specific tool |
| Parallel tool calls | 2024-08-01-preview | Off by default; toggle |
| o1-series reasoning | 2024-09-01-preview | Reasoning tokens |
| o3-series reasoning | 2024-12-01-preview | Newer reasoning |
| Batch API | 2024-07-01-preview | JSONL batch submissions |
| DALL-E 3 with n>1 | Not supported | Always n=1 |
| stream_options | 2024-06-01 | Include 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
openaipackage 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
Pin api-version at the client level, once
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.
"""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()
api_version="..." literals across files. Consolidate to one place — makes bumps a one-file change and lets you A/B test versions.Add a startup probe that verifies feature support in the pinned version
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.
"""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"])
Set up a quarterly api-version review
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 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
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
Related errors & hubs
Get the weekly AI-error digest
New fixes, provider status recaps, and one deep tutorial — every Tuesday. 8,400+ engineers.