Быстрый старт

Подключайтесь к API как к OpenRouter — тот же формат запросов, base_url замените на наш.

Base URL и аутентификация

Все запросы — на https://gdevse.ru/api/v1. Ключ создаётся в разделе Ключи и передаётся заголовком:

Authorization: Bearer sk-vk-...

API доступен и из браузера: разрешены кросс-доменные запросы (CORS), а заголовки X-RateLimit-* читаемы из JS.

Как в OpenRouter, приложение может представиться заголовками X-Title и HTTP-Referer — запросы с атрибуцией видны в разделе «Расход → Приложения» и в логах.

Chat Completions

Основной эндпоинт — открытый стандарт OpenAI:

POST https://gdevse.ru/api/v1/chat/completions
{
  "model": "openai/gpt-4o-mini",
  "messages": [
    { "role": "user", "content": "Привет!" }
  ]
}

Тот же запрос через curl:

curl https://gdevse.ru/api/v1/chat/completions \
  -H "Authorization: Bearer $GDEVSE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{"role": "user", "content": "Привет!"}]
  }'

Как у OpenRouter — автоматический fallback: поле "models" задаёт запасные модели, которые пробуются по порядку, если основная недоступна (ошибка/лимит):

{
  "model": "openai/gpt-4o-mini",
  "models": ["openai/gpt-4o-mini", "google/gemini-3.5-flash"],
  "messages": [{"role": "user", "content": "Привет!"}]
}

Вызовы инструментов

Tool calling работает как в OpenAI/OpenRouter — передайте описание функций в поле tools (поддерживается не всеми моделями — смотрите флаг «инструменты» в карточке модели):

curl https://gdevse.ru/api/v1/chat/completions \
  -H "Authorization: Bearer $GDEVSE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "openai/gpt-4o-mini",
  "messages": [{"role": "user", "content": "Погода в Москве?"}],
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
      }
    }
  }]
}'

Если модели понадобятся данные, ответ придёт с finish_reason: "tool_calls" и аргументами вызова — верните результат ролью tool, как в стандартном протоколе.

Структурированный вывод

Чтобы ответ приходил валидным JSON, используйте response_format — режим json_object или строгую схему json_schema:

{
  "model": "openai/gpt-4o-mini",
  "messages": [{"role": "user", "content": "Извлеки имя и город из: «Иван из Казани»"}],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "person",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "name": {"type": "string"},
          "city": {"type": "string"}
        },
        "required": ["name", "city"],
        "additionalProperties": false
      }
    }
  }
}

Python (OpenAI SDK)

from openai import OpenAI

client = OpenAI(
    base_url="https://gdevse.ru/api/v1",
    api_key="sk-vk-...",  # ваш ключ из личного кабинета
)

resp = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Привет!"}],
)
print(resp.choices[0].message.content)

Node.js (OpenAI SDK)

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://gdevse.ru/api/v1",
  apiKey: "sk-vk-...", // ваш ключ из личного кабинета
});

const resp = await client.chat.completions.create({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "Привет!" }],
});
console.log(resp.choices[0].message.content);

// Стрим:
const stream = await client.chat.completions.create({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "Привет!" }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Стриминг

Добавьте "stream": true — ответ придёт потоком SSE (как у OpenRouter). В финальном чанке приходит usage с токенами и стоимостью.

curl https://gdevse.ru/api/v1/chat/completions \
  -H "Authorization: Bearer $GDEVSE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "stream": true,
    "messages": [{"role": "user", "content": "Привет!"}]
  }'

# data: {"choices":[{"delta":{"content":"Пр"}}]}
# data: {"choices":[{"delta":{"content":"ивет"}}]}
# data: {"usage":{"prompt_tokens":9,"completion_tokens":2},...}
# data: [DONE]

Модели

Список доступных моделей с ценами — GET https://gdevse.ru/api/v1/models — публичный, ключ не нужен (как у OpenRouter). Формат ответа совпадает с OpenRouter: цены — строки ₽ за токен, context_length, модальности. Одна модель: GET https://gdevse.ru/api/v1/models/{id} (например /api/v1/models/openai/gpt-4o-mini). Ещё и на странице Модели. В запросе ID модели подставляется в поле model.

Баланс и лимиты ключа

Информация по ключу и балансу доступна прямо из API — так же, как у OpenRouter. Тот же ключ в заголовке, без панели:

curl https://gdevse.ru/api/v1/key \
  -H "Authorization: Bearer $GDEVSE_KEY"

# {
#   "data": {
#     "name": "мой бот",
#     "usage": 0.3,            — расход, ₽
#     "limit": 5,              — дневной лимит ₽ (null = без лимита)
#     "rate_limit": {"requests": 10, "interval": "minute"},
#     "is_enabled": true
#   }
# }

curl https://gdevse.ru/api/v1/credits \
  -H "Authorization: Bearer $GDEVSE_KEY"

# {
#   "data": {
#     "total_credits": 120,            — всего пополнено, ₽
#     "usage": 0.3,                    — израсходовано, ₽
#     "total_credits_remaining": 119.7 — остаток, ₽
#   }
# }

Provisioning API — управление ключами

Создавайте и настраивайте API-ключи программно — как в OpenRouter. Учётные данные здесь другие: не ключ вывода sk-vk-…, а ключ управления aik-… — создайте его в разделе Ключи управления. Ключ вывода не может управлять аккаунтом.

# Список ключей — по 50 на страницу
curl https://gdevse.ru/api/v1/keys -H "Authorization: Bearer $GDEVSE_MNG"

# Следующая страница
curl "https://gdevse.ru/api/v1/keys?paging.page=2" -H "Authorization: Bearer $GDEVSE_MNG"

# Создать ключ (поле key в ответе — единственный раз, когда виден целиком)
curl https://gdevse.ru/api/v1/keys -X POST \
  -H "Authorization: Bearer $GDEVSE_MNG" \
  -H "Content-Type: application/json" \
  -d '{"name": "ci-bot", "limit": 5}'

# Изменить: переименовать, включить/выключить, лимит ₽/день
curl https://gdevse.ru/api/v1/keys/42 -X PATCH \
  -H "Authorization: Bearer $GDEVSE_MNG" \
  -H "Content-Type: application/json" \
  -d '{"name": "prod", "is_enabled": true, "limit": 10}'

# Отозвать
curl https://gdevse.ru/api/v1/keys/42 -X DELETE -H "Authorization: Bearer $GDEVSE_MNG"

limit — расход в ₽ за сутки (0 или без поля — без лимита). Поле hash в ответах — идентификатор ключа для запросов выше. Список отдаётся страницами по 50 ключей: вместе с data в ответе идут total, page, page_size и total_pages — по ним и идут до конца списка.

Anthropic-формат

Для клиентов SDK Claude работает POST https://gdevse.ru/api/v1/messages (заголовок x-api-key, тот же ключ).

Лимиты и коды ошибок

На каждый ключ можно задать лимит расхода ₽/день и RPM (запросов/мин) при создании — в личном кабинете. Списание идёт с баланса воркспейса, в котором создан ключ.

У каждой ошибки есть error.message — текст на английском. Поля error.code и error.type шлюз добавляет там, где отклоняет запрос сам. Ответ провайдера передаётся наружу без изменений — и статус, и тело.

Отклонение шлюза — с кодом:

HTTP/1.1 402 Payment Required
{
  "error": {
    "message": "insufficient balance for this request",
    "type": "billing_error",
    "code": "BILLING_REJECTED"
  }
}

Проверка ключа — только сообщение:

HTTP/1.1 401 Unauthorized
{
  "error": {
    "message": "invalid API key"
  }
}

Коды, которые задаёт шлюз:

400 — запрос отклонён шлюзом: MODEL_NOT_ALLOWED (модели нет в каталоге или она не разрешена ключу), PII_DETECTED, EXTENSION_REJECTED, GUARDRAIL_BLOCKED;

401 — ключ не передан или неверен;

402 — BILLING_REJECTED: баланса не хватает на запрос, пополните его в разделе «Кредиты»;

403 — ключ выключен, истёк или адрес не в списке разрешённых;

404 — MODEL_NOT_FOUND или NO_ENDPOINTS: обращения к модели, которой нет в каталоге;

429 — лимит RPM или расхода за час/день; в заголовках X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset и Retry-After. На лимитах конкретной модели там же код QUOTA_EXCEEDED;

502 — ни один провайдер модели не ответил, повторите позже;

503 — проверка баланса недоступна, запрос не пропущен; повторите позже.

В Anthropic-формате те же отклонения приходят в конверте {"type": "error", "error": {"type": "rate_limit_error", "message": "…"}}: кода нет, есть error.type.