my-router

Как пользоваться

OpenAI-совместимый шлюз. Клиенту нужен один base URL и ключ, выписанный в админке. Дальше модель выбирается строкой provider/name.

Старт

  1. В админке выпишите ключ клиента — он выглядит как sk-mr-… и показывается один раз.
  2. Base URL: https://router.kabak.top/v1
  3. Заголовок: Authorization: Bearer sk-mr-…

GET https://router.kabak.top/health не требует ключа и отвечает {"status":"ok"}.

Эндпоинты

МетодПуть
GET/healthживо ли приложение
GET/v1/modelsсписок моделей и алиасов, нужен ключ
POST/v1/chat/completionsчат, в том числе stream: true
POST/v1/embeddingsвекторы, обычно через OpenRouter

Тело чата — как у OpenAI Chat Completions: model, messages, опционально temperature, max_tokens, tools и остальное, что понимает апстрим.

Эмбеддинги — как у OpenAI Embeddings: model, input (строка или массив строк). Если model не передан, берётся алиас embed.

Модели

Формат: провайдер/модель. Для OpenRouter всё после первого / уходит апстриму как есть: openrouter/openai/text-embedding-3-small → провайдер openrouter, модель openai/text-embedding-3-small.

Чат

ЗапросПровайдерУ апстрима
openai/gpt-4oopenaigpt-4o
openai/gpt-4o-miniopenaigpt-4o-mini
openai/gpt-4.1openaigpt-4.1
openai/gpt-4.1-miniopenaigpt-4.1-mini
deepseek/deepseek-chatdeepseekdeepseek-chat
deepseek/deepseek-reasonerdeepseekdeepseek-reasoner
qwen/qwen-plusqwenqwen-plus
qwen/qwen-turboqwenqwen-turbo
qwen/qwen-maxqwenqwen-max
openrouter/openai/gpt-4o-miniopenrouteropenai/gpt-4o-mini
openrouter/anthropic/claude-3.5-sonnetopenrouteranthropic/claude-3.5-sonnet
openrouter/google/gemini-2.0-flash-001openroutergoogle/gemini-2.0-flash-001

Эмбеддинги

ЗапросПровайдерУ апстрима
openai/text-embedding-3-smallopenaitext-embedding-3-small
openai/text-embedding-3-largeopenaitext-embedding-3-large
openrouter/openai/text-embedding-3-smallopenrouteropenai/text-embedding-3-small
openrouter/openai/text-embedding-3-largeopenrouteropenai/text-embedding-3-large
openrouter/qwen/qwen3-embedding-8bopenrouterqwen/qwen3-embedding-8b

Каталог не жёсткий: любой id вида openrouter/… уйдёт в OpenRouter, даже если его нет в таблице.

Короткие алиасы. В чате без model берётся cheap; в эмбеддингах — embed.

АлиасМодель
cheapdeepseek/deepseek-chat
gptopenai/gpt-4o-mini
qwenqwen/qwen-plus
embedopenrouter/openai/text-embedding-3-small
defaultopenrouter/openai/gpt-4o-mini

В списке /v1/models будут только те провайдеры, для которых в админке есть рабочий ключ.

curl

curl https://router.kabak.top/v1/chat/completions \
  -H "Authorization: Bearer sk-mr-…" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "cheap",
    "messages": [{"role": "user", "content": "привет"}]
  }'

Python (OpenAI SDK)

from openai import OpenAI

client = OpenAI(
    base_url="https://router.kabak.top/v1",
    api_key="sk-mr-…",
)
resp = client.chat.completions.create(
    model="cheap",
    messages=[{"role": "user", "content": "привет"}],
)
print(resp.choices[0].message.content)

Эмбеддинги

Тот же ключ и https://router.kabak.top/v1. Эндпоинт POST /v1/embeddings, тело как у OpenAI: model, input (строка или массив), опционально dimensions и encoding_format. Расход пишется в админку (входные токены).

Через OpenRouter модель — openrouter/<id у OpenRouter>. Алиас embed = openrouter/openai/text-embedding-3-small.

curl https://router.kabak.top/v1/embeddings \
  -H "Authorization: Bearer sk-mr-…" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "embed",
    "input": "привет"
  }'
vec = client.embeddings.create(
    model="openrouter/openai/text-embedding-3-small",
    input=["привет", "как дела"],
)
print(len(vec.data[0].embedding))

Другие частые id: openrouter/openai/text-embedding-3-large, openrouter/qwen/qwen3-embedding-8b. Напрямую в OpenAI, минуя OpenRouter: openai/text-embedding-3-small.

Cursor

  1. Settings → Models
  2. OpenAI API Base URL: https://router.kabak.top/v1
  3. API Key: ключ sk-mr-…
  4. Override OpenAI Base URL: включить
  5. Модель: cheap, gpt или полный id вроде openrouter/anthropic/claude-3.5-sonnet

Стрим

Передайте "stream": true. Ответ — SSE, как у OpenAI, заканчивается data: [DONE].

stream = client.chat.completions.create(
    model="gpt",
    messages=[{"role": "user", "content": "привет"}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="", flush=True)