Маршрутизация провайдеров
Модель часто обслуживают несколько провайдеров, и provider.type закрепляет запрос за одним из них. Какие провайдеры существуют и зачем закреплять — в разделе Маршрутизация провайдеров; эта страница описывает контракт поля по протоколам.
Где находится поле
Расположение поля различается в зависимости от протокола:
| Протокол / эндпоинт | Тело запроса | Заголовок |
|---|---|---|
OpenAI Chat Completions · POST /v1/chat/completions | extra_body.provider.type | X-OfoxAI-Provider-Type |
OpenAI Responses · POST /v1/responses | extra_body.provider.type | X-OfoxAI-Provider-Type |
OpenAI Images · POST /v1/images/generations | extra_body.provider.type | X-OfoxAI-Provider-Type |
Anthropic Messages · POST /anthropic/v1/messages | extra_body.provider.type | X-OfoxAI-Provider-Type |
Gemini generateContent · POST /gemini/v1beta/… | молча игнорируется | X-OfoxAI-Provider-Type |
Video API · POST /v1/videos | provider.type верхнего уровня | — |
Среди моделей генерации изображений сейчас несколькими провайдерами обслуживается только openai/gpt-image-2 (azure_foundry и openai); остальные — одним, поэтому указание другого возвращает 400 provider_type_unavailable. Также учтите: у Gemini-моделей изображений два входа по протоколам — в /v1/images/generations поле в теле работает, а в нативном generateContent Gemini игнорируется.
Передача в теле запроса
extra_body должен быть буквальным ключом JSON-тела, а provider вложен внутрь него:
cURL
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" }
}
}'В официальных SDK OpenAI extra_body должен присутствовать в теле запроса как буквальный ключ. TypeScript SDK отправляет его ровно так, как он записан в объекте параметров. Аргумент extra_body= в Python SDK сливает своё содержимое с верхним уровнем тела, поэтому ключ нужно вложить на уровень глубже либо передать через заголовок запроса.
Нативный протокол Gemini игнорирует extra_body.provider в теле — запрос выполняется, ограничение просто не применяется, ошибки нет. В этом протоколе используйте заголовок ниже.
Передача в заголовке
X-OfoxAI-Provider-Type работает во всех текстовых протоколах, включая Gemini, и подходит интеграциям, которые не могут менять тело запроса:
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": "..." }] }]
}'Там, где поддерживаются оба способа, заголовок и поле в теле равнозначны. В Video API формы заголовка нет — см. Video API · Маршрутизация провайдеров.
Ошибки
error.type | Когда возникает |
|---|---|
invalid_provider_type | Значение не является именем провайдера: опечатка или устаревшее написание. |
provider_type_unavailable | Провайдер существует, но эту модель не обслуживает. В сообщении также перечислены те, кто её обслуживает. |
Каких провайдеров можно указать
Полный список и способ узнать, какие провайдеры обслуживают конкретную модель, — в разделе Маршрутизация провайдеров.