Skip to content

Architecture and migrationGuide

Azure OpenAI and Bedrock behind one gateway: ids and quotas

Azure OpenAI and Amazon Bedrock both speak an OpenAI-style API, and almost nothing else about them lines up. This guide maps names, credentials, quotas and processing locations across the two, then puts them behind one route.

By INFRO Editorial

Published

8 min read

Glowing amber request paths radiating from a central hub node to surrounding provider nodes on a dark ground, representing one gateway over two cloud providers

In short

Azure OpenAI addresses a deployment you named and meters it in tokens per minute you assign; Bedrock addresses a model or inference profile id and meters tokens per minute per model and Region. Put both behind one gateway by mapping a stable model name to each cloud's own id, reading each cloud's 429s on their own terms, and checking per model that the API you call is supported on that cloud.

Key takeaways

  • On Azure, model is a deployment name you chose. On Bedrock, it is a model id or an inference profile id AWS chose.
  • Both clouds meter tokens per minute, but Azure counts an estimate that includes max_tokens and Bedrock can burn output tokens at a model-specific rate.
  • Not every model supports Chat Completions on every cloud. On Bedrock, check the model card before mapping a model.
  • Where inference runs is a deployment choice on Azure and a model-id choice on Bedrock; a global option trades location for capacity.
  • Put both behind one stable name, and let failover move a request only before its first token.

Teams end up with both Azure OpenAI and Amazon Bedrock for ordinary reasons: a cloud commitment on each side, a model only one of them offers, a second source of capacity for a critical feature, or two business units that chose differently. Both clouds now expose an OpenAI-style API, which makes it tempting to treat them as interchangeable endpoints. They are not. The same request body means different things on each, is counted against different limits, and runs in places chosen by different controls.

This guide lines the two up concept by concept, then shows how to put them behind one stable name.

ConceptAzure OpenAIAmazon Bedrock
What `model` namesYour deployment nameA model id or an inference profile id
Base URL (OpenAI-style){resource}.openai.azure.com/openai/v1bedrock-runtime.{region}.amazonaws.com/openai/v1
Key headerapi-key, or Entra ID bearer tokenBearer Bedrock API key, or SigV4
Throughput unitTPM assigned per deployment; RPM derivedTPM per model per Region; RPM for some models
Where inference runsDeployment type: Global, Data Zone or StandardIn-Region, geo profile or global profile
Chat Completions supportPer model; check the model tablePer model; Claude on bedrock-runtime: no
The same six questions, answered by each cloud. Read from each provider's documentation on 2026-09-29.

What model means on each cloud

On Azure OpenAI, you create a deployment of a model and give it a name, and the API's model parameter carries that deployment name, not the model's name. Microsoft's v1 examples say so in the code comment: replace the value "with your model deployment name"1. Two deployments of the same model in one resource can have different names, quotas and deployment types.

On Bedrock, model carries an id AWS defines. For many newer models on the bedrock-runtime endpoint it has to be a cross-Region inference profile id, not the bare model id. GPT-5.6 Sol is an example: on bedrock-runtime it is called as us.openai.gpt-5.6-sol or global.openai.gpt-5.6-sol, and in-Region inference is not supported there2. The prefix is not decoration: it selects where the request may run.

So the first job of anything that sits in front of both clouds is a mapping from one name your application uses to each cloud's own id.

Two OpenAI-style endpoints, two different surfaces

Azure's v1 API takes the standard OpenAI client with a base URL of https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/, with no api-version parameter, and authenticates with an api-key header or a Microsoft Entra ID token1.

Bedrock serves OpenAI Chat Completions at https://bedrock-runtime.{region}.amazonaws.com/openai/v1, authenticated with SigV4 or an Amazon Bedrock API key sent as a bearer token3. It does not implement the OpenAI GET /models operation on that endpoint, so client.models.list() does not work there3.

The same client, two clouds
import os
from openai import OpenAI

azure = OpenAI(
    base_url="https://my-company-openai.openai.azure.com/openai/v1/",
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
)
bedrock = OpenAI(
    base_url="https://bedrock-runtime.us-east-1.amazonaws.com/openai/v1",
    api_key=os.environ["AWS_BEARER_TOKEN_BEDROCK"],
)

messages = [{"role": "user", "content": "Summarise this ticket in two lines."}]

azure.chat.completions.create(model="gpt56-sol-prod", messages=messages)          # your deployment name
bedrock.chat.completions.create(model="us.openai.gpt-5.6-sol", messages=messages)  # AWS's profile id

The important difference is which models answer on those endpoints. On Azure, the GPT-5.6 models list the Chat Completions API among their capabilities4. On Bedrock, API support is per model and per endpoint. AWS's compatibility table lists Chat Completions for OpenAI, DeepSeek, Mistral, Qwen and several other families, while the Anthropic Claude rows list Invoke, Converse and Messages without Chat Completions5. The Claude Sonnet 5 model card is explicit: on bedrock-runtime, Chat Completions is not supported6. A Chat Completions call for Claude on that endpoint is not a supported combination, however correct the id mapping is.

Credentials

Azure resource keys and Entra ID tokens are both documented for the v1 API1. Bedrock has two kinds of API key: short-term keys last up to 12 hours and are recommended for production, and long-term keys last until a configured expiry and are recommended "only for exploration"7. AWS also provides an IAM action, bedrock:CallWithBearerToken, with a condition key that can restrict which key type an identity may use7.

A long-lived credential stored in a gateway is therefore a trade-off on Bedrock, and it should be made knowingly: set an expiry, attach the narrowest Bedrock policy, and rotate before expiry rather than after a failure.

Quotas: both say TPM, neither means the same thing

Azure assigns quota "on a per-region, per-model, per-deployment-type basis in units of Tokens-per-Minute"; each deployment gets a share, and an RPM limit is set in proportion to it8. The TPM check uses an estimate made when the request arrives, and the estimate includes max_tokens, so an oversized max_tokens consumes limit even when the answer is short8. RPM is enforced over short windows, typically 1 or 10 seconds, so a burst can be throttled while the per-minute total is under the limit8. Throttled responses carry retry-after-ms8.

Bedrock's bedrock-runtime quotas are tokens per minute per model per Region, with separate quotas for on-demand and cross-Region inference, and they are shared by every API you call the model with, Chat Completions included9. Output tokens are converted into quota at a model-specific burndown rate9; for GPT-5.6 Sol, AWS states one output token consumes ten2.

Azure also distinguishes kinds of 429: exceeding your rate limit, transient system capacity, and a temporary reduction of a Standard deployment's effective limit when shared capacity is under pressure, visible when x-ratelimit-limit-tokens is below your configured TPM8.

A 429 came back. Which kind?

  • Azure: rate limit exceeded on the deploymentRaise its TPM, rebalance quota, or lower max_tokens (it counts toward the estimate).
  • Azure: service temporarily unable / high demandTransient capacity. Wait retry-after-ms or move to the other target.
  • Bedrock: tokens per minute for the modelCheck on-demand vs cross-Region quota and the output burndown rate.
  • Both clouds throttling at onceA demand problem, not an outage. Shed or queue low-priority work.
A 429 is a question, not an answer. The right response depends on which limit produced it.

Where inference runs

On Azure, location is a property of the deployment type. Global types may process data in any Azure region; Data Zone types keep processing inside the US, EU or APAC data zone; Standard and Regional Provisioned keep it within the chosen Azure geography, while data at rest stays in the designated geography for all of them10.

On Bedrock, location is a property of the model id. Geographic profiles route within a geography such as the US or EU; global profiles route to any supported commercial Region11. CloudTrail records the Region that processed each cross-Region request in additionalEventData.inferenceRegion11.

That symmetry matters when the two clouds back each other up: a failover from an Azure Data Zone deployment to a Bedrock global profile moves the request's processing location. Pair targets whose locations your policy accepts.

Connecting Azure OpenAI and Bedrock in INFRO

INFRO has a connection kind for each, and both call your own accounts with your own credentials; each cloud bills you directly (connect a provider).

  • Azure OpenAI asks for the resource name and an API key. INFRO calls https://{resource}.openai.azure.com/openai/v1 with the key in the api-key header. Each catalog model you route is mapped to your deployment name on the connection; an unmapped model is sent with its model name as the deployment name.
  • AWS Bedrock asks for a long-lived Bedrock API key and a Region, and calls the bedrock-runtime OpenAI-compatible endpoint in that Region. Bedrock ids are Region-specific, so nothing is guessed: a model is served through the connection only when you name it.

Because the Bedrock connection speaks Chat Completions, it reaches only models whose Bedrock model card lists Chat Completions on bedrock-runtime. For Claude, connect your Anthropic account directly today. And because it stores a long-lived key, apply the AWS guidance above: an expiring key, a narrow policy, and rotation with POST /provider_connections/{id}/credential, which takes effect on the next request (management API resources).

An Azure connection with a deployment map
curl https://api.infro.io/manage/v1/provider_connections \
  -H "Authorization: Bearer $INFRO_MANAGEMENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "azure-openai",
    "name": "Azure EU production",
    "environment": "production",
    "secret": "'"$AZURE_OPENAI_API_KEY"'",
    "config": {"resource": "my-company-openai"},
    "model_map": {"openai/gpt-5.6-sol": "gpt56-sol-prod"},
    "timeout_ms": 60000,
    "validate": true
  }'

Then one route gives the application a stable name over both:

one client

Application

Sends model: "chat-primary" to https://api.infro.io/v1 with an INFRO key.

INFRO

Route chat-primary (priority)

Target 1: Azure connection. Target 2: Bedrock connection. Failover before the first token.

your subscription

Azure OpenAI connection

Catalog id mapped to your deployment name; sent with the api-key header.

your AWS account

Bedrock connection

Model named by the exact id or inference profile Bedrock expects; sent as a bearer API key.
The application names a route. INFRO tries the Azure target first and moves to the Bedrock target only if Azure fails before the first token.
Route targets, priority strategy
{
  "slug": "chat-primary",
  "strategy": "priority",
  "max_retries": 0,
  "timeout_ms": 20000,
  "targets": [
    {"connection_id": "conn_azure_eu", "model": "openai/gpt-5.6-sol"},
    {"connection_id": "conn_bedrock_us", "model": "us.openai.gpt-5.6-sol"}
  ]
}

The second target names the exact profile id Bedrock expects. A target whose model is not an INFRO catalog id is sent as written and recorded as unpriced, so its usage.cost reads null rather than a guess (chat completions). Under a blocking budget, a request to an unpriced model is refused by default with 402 unpriced_model_under_budget (errors); decide that setting deliberately before the fallback is needed. Send a test request through each target and read its record before relying on the chain.

A provider 429 does not count against a connection's health, and it moves the request to the next target; if every target is throttled, the application receives 429 provider_rate_limited with the provider's Retry-After (connect a provider). Every attempt, with the connection that made it, is on the request's trace, which is how you find out that the Azure deployment's quota, not the model, is what failed.

Note what the route does not do: it does not make the two targets identical. They are the same model family on two clouds, with different quota behaviour, different feature support per API and different processing locations. Evaluate the fallback target as its own deployment, with the same prompts, before depending on it.

Checklist

  • One stable application-side name per workload, mapped to an Azure deployment name and a Bedrock id.
  • Every mapped Bedrock model checked on its model card for Chat Completions on bedrock-runtime.
  • max_tokens sized to real answers, so Azure's estimate and Bedrock's burndown do not waste quota.
  • Azure deployment type and Bedrock profile prefix chosen to match your location policy, for primary and fallback alike.
  • Bedrock key with an expiry, a narrow policy and a rotation date in the calendar.
  • 429s classified by cloud and cause in dashboards, not summed into one error rate.
  • Failover tested by disabling the primary connection and finding the Bedrock attempt on the trace.

From the team that builds it

Where this shows up in INFRO

INFRO is a control plane in front of the provider accounts you already hold. The capabilities below are the parts of it this article touches, each with the documentation that defines its behaviour.

INFRO is in private early access. Provider usage is billed to you by your providers; INFRO charges a software subscription and takes 0% of model spend. See plans.

Sources

Numbered in order of first citation. Each was opened and checked against the claim on the date shown.

  1. 1.Azure OpenAI in Microsoft Foundry Models v1 API (opens in a new tab) — Microsoft Learn. Accessed Sep 29, 2026.
  2. 2.GPT-5.6 Sol model card — Amazon Bedrock (opens in a new tab) — AWS. Accessed Sep 29, 2026.
  3. 3.Chat Completions API — Amazon Bedrock (opens in a new tab) — AWS. Accessed Sep 29, 2026.
  4. 4.Foundry Models sold by Azure (opens in a new tab) — Microsoft Learn. Accessed Sep 29, 2026.
  5. 5.API compatibility — Amazon Bedrock (opens in a new tab) — AWS. Accessed Sep 29, 2026.
  6. 6.Claude Sonnet 5 model card — Amazon Bedrock (opens in a new tab) — AWS. Accessed Sep 29, 2026.
  7. 7.API keys — Amazon Bedrock (opens in a new tab) — AWS. Accessed Sep 29, 2026.
  8. 8.Manage Azure OpenAI in Microsoft Foundry Models quota (opens in a new tab) — Microsoft Learn. Accessed Sep 29, 2026.
  9. 9.Quotas for the bedrock-runtime endpoint (opens in a new tab) — AWS. Accessed Sep 29, 2026.
  10. 10.Understanding deployment types in Microsoft Foundry Models (opens in a new tab) — Microsoft Learn. Accessed Sep 29, 2026.
  11. 11.Route model inference requests across AWS Regions with cross-Region inference (opens in a new tab) — AWS. Accessed Sep 29, 2026.

About this article

Written from Microsoft Learn and AWS documentation opened on 2026-09-29, the public INFRO documentation (providers, routes, fallbacks, management API) and the gateway's provider registry, which the authors build. No throughput or latency figures are measured; quota figures are quoted from the providers.

Last checked against its sources on . The next review is due by . No separate named reviewer is recorded for this article.

How articles are written, sourced and corrected is set out in the editorial standards.