Chat Completions
POST /v1/chat/completions — OpenAI-совместимый эндпоинт. Формат тела и
ответа идентичны openai.chat.completions.create(...).
Тело запроса
| Поле | Тип | Обязательное | Комментарий |
|---|---|---|---|
model | string | да | slug из каталога, например gemini-3.5-flash |
messages | array | да, ≥1 элемент | role: system | user | assistant | tool | developer; content: строка, null или массив content-parts |
stream | boolean | нет, по умолчанию false | см. «Стриминг» ниже |
остальные поля (temperature, max_tokens, top_p, stop, …) | — | нет | пробрасываются апстриму как есть |
Неизвестный model → 404 model_not_found. Пустое тело/некорректная
структура messages → 400 invalid_request. Подробности — на странице
«Коды ошибок».
Передача параметров на Gemini-маршрутах
Для моделей, маршрутизируемых на Google Gemini, в нативный запрос
переносятся только temperature и max_tokens — остальные OpenAI-поля
(top_p, stop, presence_penalty и т.п.) Gemini не понимает и шлюз их
не транслирует. Для моделей на OpenAI-совместимом или Anthropic
апстриме пробрасываются все переданные поля.
Пример ответа (без стрима)
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "gemini-3.5-flash",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Привет! Чем могу помочь?" },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 8, "completion_tokens": 7, "total_tokens": 15 }
}Стриминг
С stream: true ответ приходит как Server-Sent Events — чанки в формате
chat.completion.chunk, поток завершается строкой data: [DONE]. Родной
stream=True у OpenAI SDK читает это без дополнительной настройки.
Python
from openai import OpenAI
client = OpenAI(
base_url="https://api.aigateway.andrewdev.ru/v1",
api_key="sk-tn-ВАШ_КЛЮЧ",
)
stream = client.chat.completions.create(
model="gemini-3.5-flash",
messages=[{"role": "user", "content": "Напиши хайку про рассвет"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)JavaScript
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.aigateway.andrewdev.ru/v1',
apiKey: 'sk-tn-ВАШ_КЛЮЧ',
});
const stream = await client.chat.completions.create({
model: 'gemini-3.5-flash',
messages: [{ role: 'user', content: 'Напиши хайку про рассвет' }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content;
if (delta) process.stdout.write(delta);
}Если соединение обрывает клиент — апстрим-запрос тоже прерывается
(токены после обрыва не тарифицируются). Если обрывается сам апстрим
посреди потока — в поток пишется финальное SSE-событие с ошибкой, а
списание считается по фактически переданным клиенту чанкам с флагом
usage_estimated.
Изображения в content parts
Как и в OpenAI Vision, вместо строки в content передаётся массив
частей: текст + image_url с data-URI:
response = client.chat.completions.create(
model="gemini-3.5-flash",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Что на картинке?"},
{
"type": "image_url",
"image_url": {"url": "data:image/png;base64,iVBORw0KGgo..."},
},
],
}
],
)Для моделей на Gemini- и Anthropic-маршрутах image_url транслируется в
нативный inline-формат провайдера; для OpenAI-совместимого апстрима
content parts пробрасываются как есть (апстрим должен сам поддерживать
vision).
Таймауты и размер тела
| Параметр | Значение |
|---|---|
| Установление соединения с апстримом | 10 с |
| Полный ответ (включая стрим) | 10 мин |
| Максимальный размер тела запроса | 20 МиБ |
Превышение таймаута или размера тела возвращает 502/400 в
стандартном формате ошибок — см. «Лимиты».