Один ключ вместо пяти SDK: как устроен OpenAI-совместимый API
23.09.2026 · 3 мин
Меняете base_url на gdevse.ru/api/v1 — и весь каталог моделей работает тем же клиентом: стриминг SSE, tool calling, fallback, лимиты ₽/день.
Что именно «совместимый»
Формат запросов OpenAI — де-факто стандарт: messages, role, choices,
usage. Шлюз Gdevse принимает его без изменений, поэтому подключение —
это одна строка в конфиге, а не переписывание клиента:
from openai import OpenAI
client = OpenAI(
base_url="https://gdevse.ru/api/v1",
api_key="sk-vk-…", # ключ из личного кабинета
)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gdevse.ru/api/v1",
apiKey: process.env.GDEVSE_KEY,
});
Дальше меняется только поле model. ID модели — <вендор>/<имя>, как в
OpenRouter: openai/gpt-4o-mini, deepseek/deepseek-v4.1-flash,
anthropic/claude-sonnet-4.5. Полный список с ценами отдаёт
GET /api/v1/models — публично, без ключа; там же цены в ₽ за токен и
context_length.
Токены приходят в ответе, рубли — в отдельном запросе
В стандартном OpenAI-ответе поле usage несёт разбивку по токенам, включая
кэш:
{
"usage": {
"prompt_tokens": 1024,
"completion_tokens": 180,
"prompt_tokens_details": { "cached_tokens": 768 }
}
}
При стриминге ("stream": true) финальный чанк перед [DONE] несёт тот же
usage. Это единственный надёжный способ учесть расход в потоковом
приложении: суммировать дельты по словам — не считается.
Баланс и лимиты — из того же ключа
curl https://gdevse.ru/api/v1/key -H "Authorization: Bearer $GDEVSE_KEY"
# data: { name, usage — ₽, limit — ₽/сутки, rate_limit, is_enabled }
curl https://gdevse.ru/api/v1/credits -H "Authorization: Bearer $GDEVSE_KEY"
# data: { total_credits, usage, total_credits_remaining }
limit на ключе — дневной расход в рублях. Это то, что стоит поставить
первым делом, если ключ попадает в публичное приложение: перебор защиты не
спасёт от счёта, а лимит в 5 ₽/сутки спасёт. Ошибки — в едином JSON-формате
OpenAI, так что обрабатывать их можно на уровне клиента:
{ "error": { "message": "insufficient balance for this request",
"type": "billing_error", "code": "BILLING_REJECTED" } }
Fallback: подписка на один вендор — это риск доступности
{
"model": "openai/gpt-4o-mini",
"models": ["openai/gpt-4o-mini", "google/gemini-flash-1.5"],
"messages": [{ "role": "user", "content": "Привет!" }]
}
Основная модель недоступна или упёрлась в лимит — запрос уходит по списку дальше, клиент не меняется. Полезная деталь для продакшена: ответ содержит, какая модель его реально сгенерировала, поэтому логировать стоит её, а не запрошенную первую строку.
Остальное, что ожидают от «взрослого» API
- Tool calling — как в OpenAI: массив
toolsс описанием функций,finish_reason: "tool_calls"в ответе, результат возвращается рольюtool. Поддерживается не всеми моделями — флаг «инструменты» есть в карточке каждой модели в каталоге. - Структурированный вывод —
response_formatсjson_objectили строгой схемойjson_schema. - Anthropic-формат —
POST /api/v1/messagesс заголовкомx-api-keyдля клиентов SDK Claude. - Атрибуция — заголовки
X-TitleиHTTP-Referer: запросы с ними видны отдельным приложением в разделе «Расход → Приложения». - Лимиты в заголовках —
X-RateLimit-*читаемы из браузера, CORS разрешён, так что счётчик запросов можно строить прямо в JS. - Provisioning — ключи создаются и отзываются программно управлением по
отдельному ключу
aik-…:POST /api/v1/keysс{"name": "ci-bot", "limit": 5}. Ключ выводаsk-vk-…управлять аккаунтом не может.
С чего начать, чтобы не сжечь баланс
- Отдельный ключ на каждое приложение, а не один на всё — иначе расход не разобрать.
limitв рублях в сутки на каждый ключ, даже тестовый.- Модель выбирать по странице сравнения, а не по названию: цена входа и выхода отличается в десятки раз при близком качестве на типовых задачах.
- Логируйте
usageиз ответа, а сверяйтесь с/api/v1/key— токены это вы, а рубли уже посчитаны на стороне шлюза.