Skip to Content
APIProvider Routing

Provider Routing

A model is often served by several providers, and provider.type pins a request to one of them. Which providers exist and why you would pin one are covered in Provider routing; this page is the per-protocol field contract.

Where the field goes

The field is not in the same place on every protocol:

Protocol / endpointRequest bodyRequest header
OpenAI Chat Completions · POST /v1/chat/completionsextra_body.provider.typeX-OfoxAI-Provider-Type
OpenAI Responses · POST /v1/responsesextra_body.provider.typeX-OfoxAI-Provider-Type
OpenAI Images · POST /v1/images/generationsextra_body.provider.typeX-OfoxAI-Provider-Type
Anthropic Messages · POST /anthropic/v1/messagesextra_body.provider.typeX-OfoxAI-Provider-Type
Gemini generateContent · POST /gemini/v1beta/…silently ignoredX-OfoxAI-Provider-Type
Video API · POST /v1/videostop-level provider.type

Among image models only openai/gpt-image-2 is currently served by more than one provider (azure_foundry and openai); the rest are single-provider, so naming a different one returns 400 provider_type_unavailable. Note also that Gemini image models are reachable through two protocols — on /v1/images/generations the body field works, on the Gemini native generateContent it is ignored.

Passing it in the request body

extra_body must be a literal key in the JSON body, with provider nested inside it:

Terminal
curl https://api.ofox.io/v1/chat/completions \ -H "Authorization: Bearer $OFOX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-sonnet-5", "messages": [{ "role": "user", "content": "..." }], "extra_body": { "provider": { "type": "bedrock" } } }'

With the official OpenAI SDKs, extra_body must be present as a literal key in the request body. The TypeScript SDK sends it as written in the params object. The Python SDK’s extra_body= argument merges its contents into the top level of the body, so the key must be nested one level deeper, or passed as a request header instead.

The Gemini native protocol ignores extra_body.provider in the body — the request succeeds and the constraint simply does not apply, with no error. On that protocol use the header below instead.

Passing it in a header

X-OfoxAI-Provider-Type works on every text protocol, including Gemini, and suits integrations that cannot modify the request body:

Terminal
curl https://api.ofox.io/gemini/v1beta/models/google/gemini-3.1-flash-lite:generateContent \ -H "Authorization: Bearer $OFOX_API_KEY" \ -H "X-OfoxAI-Provider-Type: vertex" \ -H "Content-Type: application/json" \ -d '{ "contents": [{ "parts": [{ "text": "..." }] }] }'

The header and the body field are equivalent where both are supported. The Video API has no header form — see Video API · Provider routing.

Errors

error.typeWhen it happens
invalid_provider_typeThe value is not a provider name — a typo, or a spelling that has been retired.
provider_type_unavailableThe provider exists but does not serve this model. The message also lists the providers that do.

Which providers you can name

The full list, and how to find which providers serve a given model, are in Provider routing.

Last updated on