Any-to-any formats
Keep the SDK you have, call the model you want. The LLM Gateway accepts every major conversational API format and reaches every conversational provider from it: an OpenAI Agents SDK app on Responses can call Claude on Bedrock, Claude Code on Anthropic Messages can call GPT on Azure, and a Gemini SDK app can call OpenAI, all with no code change beyond the base URL and the model name.
Your client keeps its own format end to end: requests, streams, tool calls, usage and errors all come back exactly as your SDK expects them.
Combine a path with your regional base URL and authenticate with your Quilr key as usual.
How the gateway reaches a provider
After the gateway picks the provider and model (routing group, provider selector, Policy Engine route), it asks these questions in order. The first yes wins.
- Does the provider speak your format?Anthropic Messages to Anthropic, Responses to OpenAIyes:Native: forwarded as sentNothing is converted
- Does the same provider have an endpoint that speaks it?Responses to xAI, Messages to DeepSeek, Gemini to the Gemini APIyes:Endpoint switchSame credential, body unchanged
- Is there a built-in Chat Completions adapter?Chat Completions to Bedrock Converse, Vertex Gemini or Anthropicyes:AdapterSee Chat Completions adapters
- Can the request be converted without losing provider-held state?Responses to Claude on Bedrock, Messages to GPT on Azureyes:Translate both waysRequest out, response back
- None of the aboveError in your client's format
Conversion happens only when the native path cannot serve the request. A request that worked before this release takes exactly the same path it always did.
Format explorer
Pick what you send and where it goes, or click any cell in the matrix. Cells marked * depend on the model; pick the model family above the ladder.
- Does the provider speak this format natively?yes:Forward as sent
- Does the same provider have an endpoint that speaks it?yes:Switch endpoint
- Is there a built-in Chat Completions adapter for the provider?yes:Use the adapter
- Can the request be converted without losing provider-held state?yes:Translate both ways
POST /openai_responses/v1/responses→Bedrock InvokeModel (Claude)The gateway converts the request to the provider’s format and the response back to yours.
- Supported: Text, system prompt, history, tools and tool calls, streaming, images and inline files
- Supported: Billed on the provider’s own token usage
- Supported: Prompt-cache breakpoints are added automatically
- Parameters without an equivalent are dropped. See “Parameters when converting” on this page.
- Hosted tools and provider-only settings are dropped and the request still runs; stored state and provider file ids return an error. See “Limits and coming soon” on this page.
- None of the aboveError in your client’s format
| Provider you send | Chat Completions | Responses | Anthropic Messages | Gemini generateContent | Bedrock Converse | Bedrock InvokeModel |
|---|---|---|---|---|---|---|
| OpenAI and Azure OpenAI | ||||||
| OpenAI | ||||||
| OpenAI (Responses type) | ||||||
| Azure OpenAI | ||||||
| Azure OpenAI (Responses type) | ||||||
| Anthropic | ||||||
| Anthropic | ||||||
| Anthropic (OpenAI-compatible) | ||||||
| Anthropic on Azure AI Foundry | ||||||
| Anthropic on AWS Bedrock | ||||||
| Google Gemini API | ||||||
| Google Vertex AI | ||||||
| AWS | ||||||
| AWS Bedrock | ||||||
| More providers | ||||||
| xAI | ||||||
| xAI (Responses type) | ||||||
| Mistral | ||||||
| DeepSeek | ||||||
| Oracle OCI (Chat) | ||||||
| Oracle OCI (Responses) | ||||||
| Sarvam | ||||||
| Custom OpenAI-compatible | ||||||
Native first: why it matters
When the provider already speaks your format, the gateway forwards your request as sent and returns the provider's response as received. Nothing is rewritten, so:
- Every provider feature works, including ones the gateway does not know about yet: new parameters, beta headers, stored conversations, hosted tools.
- Prompt caching is untouched. The bytes the provider caches are the bytes you sent.
- Nothing is lost in a round trip, and there is no conversion latency.
Guardrails, logging, quotas and routing still run on native requests, as they always have.
Endpoint switch: same provider, the right endpoint
Many providers expose more than one API with the same credential. When your format is not the provider's main one but the provider has an endpoint that speaks it, the gateway sends your request there unchanged. Only the URL and envelope change.
An OpenAI or Azure OpenAI key also serves Responses requests directly, and a Responses-type key serves Chat Completions, so you no longer need a separate provider for each OpenAI API. The body is not converted, so every parameter you send reaches the provider; Parameters when converting does not apply.
What is kept when converting
This applies to every client format and provider on an adapter or translated pair. Parameter mapping is in Parameters when converting, and what comes back in Responses you get back.
Parameters when converting
When a request is translated, each parameter is mapped to the target API's field, or dropped when the target has no equivalent. A dropped parameter is removed and the request still runs. Columns are the API the request is sent to (the explorer's wire line shows it for each pair):
- Chat Completions targets: OpenAI, Azure OpenAI, Gemini API, xAI, Mistral, DeepSeek, custom OpenAI-compatible, Bedrock OpenAI models, Vertex AI Model Garden.
- Responses targets: OpenAI and Azure OpenAI Responses-type keys and Responses-only models, xAI Responses.
- Anthropic targets: Anthropic, Azure AI Foundry Anthropic, Claude on Bedrock InvokeModel.
- Gemini targets: Gemini models on Vertex AI.
- Converse targets: non-Claude models on AWS Bedrock (such as Nova).
Effort values are moved to the nearest value the target accepts. Streams sent to a Chat Completions target always ask for usage, so billing has it; a Chat Completions client gets the usage chunk only when it sets stream_options.include_usage. A Converse guardrailConfig sent to a non-Bedrock provider is dropped and the request still runs; QuilrAI guardrails on the app still apply (see Limits).
Per-model rules, applied only to translated requests:
- (a) Claude: combinations a Claude model rejects are dropped:
temperaturewithtop_p(top_pdropped),temperatureother than 1 ortop_kwith thinking, andtemperature,top_pandtop_kon models that deprecate them. - (b) OpenAI reasoning models: sampling parameters, penalties and
logprobsare dropped (unless reasoning is off),stopandlogit_biasare dropped on Chat Completions, and the effort is fitted to what the model accepts. - (b) xAI:
logit_biasis dropped on every model; reasoning models drop penalties andstop. Efforts: grok-4.3 takesnonetoxhigh, grok-4.5 and laterminimaltoxhigh, grok-4.20 and grok-build none. - Mistral:
seedis sent asrandom_seed;user,logit_bias,store,verbosityandsafety_identifierare dropped;developermessages becomesystem; tool call ids are rewritten to Mistral's 9-character format; inline PDF parts are sent as Mistral documents. Codestral, Ministral and Voxtral models drop reasoning effort andlogprobs.
Chat Completions adapters
The adapter step takes a Chat Completions request on /openai_compatible/v1/chat/completions straight to a provider's own chat API, without the translator:
On bedrock, a model that supports Bedrock's own OpenAI-compatible Chat Completions is called there natively; the Converse adapter serves the rest, application inference profiles, and requests that carry Converse options. Send the provider's own model name as model.
Where the adapters differ from the table above:
- Unknown parameters are rejected, not dropped. The adapters accept
max_tokens/max_completion_tokens,temperature,top_p,stop,tools,tool_choice,functions,parallel_tool_calls,response_format,stream_options,metadata,userandnof 1. Vertex AI also accepts penalties andseed; Bedrock also accepts Converse options (such asguardrailConfigandadditionalModelRequestFields), top level or inextra_body. Anything else, includingreasoning_effort,logprobsandlogit_bias, returnsunsupported_<provider>_openai_parameter(<provider>isbedrock,vertexoranthropic). response_format: Bedrock takesjson_schemaonly, Vertex AI takesjson_objectandjson_schema(the schema is reduced to what Gemini accepts), Anthropic takestextonly.parallel_tool_calls: falseis accepted but not enforced.useris sent asmetadata.user_idon Anthropic only.- Tool calls need an
idon everyassistant.tool_callsentry for Bedrock and Anthropic. - Cache markers (
cache_control) become ConversecachePointblocks on Bedrock and staycache_controlon Anthropic. - Bedrock reasoning comes back as
message.reasoning_content, and the original Converse content asmessage.bedrock_contentwhen it holds reasoning or citations, so the next turn can send it back. - Validation errors use the codes
unsupported_<provider>_openai_parameter,invalid_<provider>_openai_parameter,unsupported_<provider>_openai_content,invalid_<provider>_openai_messagesandinvalid_<provider>_openai_tools.
Responses you get back
On every adapter and translated pair, the response is rebuilt in your client's format, streamed or not:
Limits and coming soon
Some features live inside one provider, such as a stored conversation or a hosted tool the provider runs. They work on native pairs. When converting, settings and tools the target cannot carry are dropped and the request still runs: the model answers without that tool or setting, and nothing else changes in the response you get back. State the conversation depends on, such as a stored conversation or a provider file, returns an error instead. This is the single list for every format; the explorer's cell notes point here.
Other errors you may see on a converted pair:
Error bodies follow your client's format:
How to tell which path ran
x-quilr-served-modelon every response names the model that served it, andx-quilr-routethe Policy Engine route (ordefault).- Converted Responses ids start with
resp_qtx_. Native Responses ids keep the provider's own format. count_tokenson Anthropic Messages returns the headerx-quilr-token-count-source: estimatewhen the model sits behind a converted path and the count is a local estimate.- Error codes from the tables above name the reason a pair was refused.
Routing across formats
Conversion happens after the gateway picks a provider, so it works with every routing feature:
- Routing groups can mix API families. A Responses group can hold Claude on Bedrock next to GPT on Azure. The group needs at least one member of its own family; while any own-family member is usable, only those members take traffic, and the others are reached by conversion when they are not. See Routing and fallbacks.
- Policy Engine Route to and content routes use a newly reachable target only when no target of the request's own family is available. If no target can serve the request, normal routing applies. See Route to.
- A request that worked before keeps its target. Any-to-any never moves working traffic; it only adds targets that were unreachable before.
- Conversation pinning keeps a conversation on its first provider, whatever the format.
- Bedrock clients (Converse, InvokeModel) reach a non-Bedrock provider when a routing group picks it (Converse only), when you select it with
X-Provider-Name/X-Provider-Label, or when it is the only provider on the app with the model. Bedrock credentials always get the signed request unchanged.
Examples
OpenAI Agents SDK or Codex (Responses) to Claude on Bedrock
App provider: Anthropic on AWS Bedrock (anthropic_messages_bedrock) with a Claude model enabled.
from openai import OpenAI
client = OpenAI(
base_url="https://guardrails-usa-2.quilr.ai/openai_responses/v1",
api_key="sk-quilr-xxx",
)
response = client.responses.create(
model="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
instructions="You are a concise assistant.",
input="Summarize the release in two sentences.",
)
print(response.output_text)
Tools, streaming and multi-turn input work. Keep the conversation in input rather than previous_response_id, since the conversation is not stored on Bedrock. Hosted tools such as Codex's web search are dropped on this pair, so the model answers without them.
Claude Code (Anthropic Messages) to GPT on Azure OpenAI
App provider: Azure OpenAI with a GPT deployment enabled. Point Claude Code at the gateway and name the deployment as the model:
export ANTHROPIC_BASE_URL="https://guardrails-usa-2.quilr.ai/anthropic_messages"
export ANTHROPIC_API_KEY="sk-quilr-xxx"
export ANTHROPIC_MODEL="gpt-4.1"
claude
Claude Code's tool loop and streaming come back in Anthropic format. Anthropic server tools such as web search are dropped on this pair, so the model answers without them (see Limits).
Google GenAI SDK (Gemini) to OpenAI
App provider: OpenAI with gpt-4.1-mini enabled. Configure the Gemini client as in the integration guide, then send the OpenAI model name:
response = client.models.generate_content(
model="gpt-4.1-mini",
contents="Write a haiku about gateways.",
)
print(response.text)
boto3 Converse to Mistral
App provider: Mistral with ministral-8b-latest enabled, as the only provider on the app with that model.
import boto3
bedrock = boto3.client(
"bedrock-runtime",
endpoint_url="https://guardrails-usa-2.quilr.ai/bedrock-runtime",
aws_access_key_id="sk-quilr-xxx",
aws_secret_access_key="sk-quilr-xxx",
region_name="us-east-1",
)
response = bedrock.converse(
modelId="ministral-8b-latest",
messages=[{"role": "user", "content": [{"text": "Hello!"}]}],
)
print(response["output"]["message"]["content"][0]["text"])
Related
- Provider support - provider types, endpoints and credentials
- Routing and failover - routes, pinning, failover and groups that mix providers
- Integration guide - base URLs and SDK setup