Для ШІ-агентів: покрокова інструкція з налаштування — /docs/agents.md, індекс документації — /llms.txt.

Довідник API

Усе про запити до шлюзу: протоколи, адреси, ключі та параметри. Нижче — стримінг, виклик інструментів, міркування, плагіни та вартість запиту у відповіді.

Протоколи та адреси#

Шлюз приймає формати OpenAI та Anthropic. Базова адреса для SDK OpenAI — https://gate.joingonka.ai/v1, для SDK Anthropic — https://gate.joingonka.ai. Усі протоколи працюють на одному ключі й одному балансі: запит у будь-якому форматі йде одним і тим самим шляхом.

Метод і шляхФорматДля чогоОсобливості
POST /v1/chat/completionsOpenAI Chat CompletionsЧат, агенти, виклик інструментівОсновний шлях: інші формати шлюз перекладає в нього.
POST /v1/messagesAnthropic MessagesClaude Code та SDK AnthropicБазова адреса без /v1; моделі claude-* замінюються рекомендованою; поле max_tokens обов'язкове.
POST /v1/responsesOpenAI ResponsesCodex CLI та нові SDK OpenAIБез стану: історію надсилайте повністю в кожному запиті.
POST /v1/completionsOpenAI Completions (legacy)Автодоповнення та правка коду в редакторахsuffix передається моделі підказкою; у відповіді logprobs: null.
POST /v1/embeddingsOpenAI EmbeddingsВекторні представлення текстуВідповідь 501: у мережі немає ембеддингових моделей.

Довідкові адреси#

Відповідають без ключа. Таблиця моделей із контекстом і статусом — у розділі Моделі.

Метод і шляхОпис
GET /v1/modelsСписок моделей: контекст, ціни, підтримувані параметри — поля у форматі OpenRouter.
GET /v1/models/{model}Картка однієї моделі; слеш в id — як є або %2F. Прихована або невідома модель — 404 model_not_found.
GET /v1/capabilitiesМожливості шлюзу: параметри, протоколи, плагіни, поля вартості та ліміти (limits).
GET /v1/pluginsПлагіни: id і назва.
GET /v1/network-statusСтан моделей мережі: доступність, затримки, аптайм.
GET /v1/nodesЗведення пулу нод: скільки всього, активних і в карантині.
GET /v1/web-search/enginesЧи увімкнено веб-пошук і в якому стані його движки.

Anthropic Messages#

  • Базова адреса — https://gate.joingonka.ai: SDK сам додасть /v1/messages.
  • Ключ — у заголовку x-api-key (так надсилає SDK Anthropic) або Authorization: Bearer.
  • Моделі claude-* шлюз замінює рекомендованою (MiniMaxAI/MiniMax-M2.7); у полі model відповіді залишається ім'я, яке надіслав клієнт.
  • max_tokens обов'язковий, як в API Anthropic; більше за стелю моделі — обрізається.
  • Стрім — події Anthropic; у паузах шлюз надсилає event: ping, збій приходить подією event: error.
  • Роздуми моделі у відповідь не потрапляють: блоків thinking немає.
  • Вбудований інструмент web_search виконує плагін веб-пошуку шлюзу — див. розділ Плагіни.
  • Підрахунку токенів (/v1/messages/count_tokens) немає — відповідь 404.

Claude Code простіше налаштувати інсталятором — підключення інструментів. Вручну — змінними середовища; ANTHROPIC_MODEL закріплює модель мережі.

export ANTHROPIC_BASE_URL=https://gate.joingonka.ai
export ANTHROPIC_AUTH_TOKEN=$JOINGONKA_API_KEY
export ANTHROPIC_MODEL=MiniMaxAI/MiniMax-M2.7
claude

OpenAI Responses#

  • Шлюз не зберігає відповіді: надсилайте всю історію в input. Поля previous_response_id і conversation — помилка 400 з кодом.
  • store приймається і нічого не змінює.
  • Інструменти: function і web_search — його виконує плагін веб-пошуку. Інші вбудовані інструменти шлюз пропускає, і запит виконується без них; вимагати такий інструмент через tool_choice — помилка 400.
  • Частини input_image і input_file — помилка 400: моделі мережі працюють із текстом.
  • Адреси стану (GET /v1/responses/{id}, DELETE /v1/responses/{id}, GET /v1/responses/{id}/input_items, POST /v1/responses/{id}/cancel, POST /v1/responses/compact) відповідають 404 з кодом — відповідей шлюз не зберігає.
  • Codex CLI: задайте свій id провайдера в model_provider (не openai) — тоді Codex стискає історію сам, без /v1/responses/compact.

Legacy Completions#

  • prompt — рядок або масив з одного рядка; відповідь — у choices[].text. Кілька промптів або токени замість тексту — помилка 400.
  • suffix передається моделі підказкою в промпті: справжнього заповнення середини в мережі немає.
  • У відповіді logprobs: null; best_of ігнорується; echo працює.

Ключі та авторизація#

Ключ передається в заголовку Authorization: Bearer jg-… або x-api-key: jg-… — на всіх адресах. Ключ створюється після реєстрації на сторінці gate.joingonka.ai/keys.

ПрефіксКлючЗапити до моделей
jg-Звичайний ключ акаунтатак
gc-Дочірній ключ: свої ліміти, витрати — з балансу власникатак
gm-Керівний ключ: лише керування дочірнімині — 403 forbidden
  • Кожному ключу в кабінеті можна задати ліміт витрат на день, місяць і загалом; перевищення — 402 child_key_limit_exceeded.
  • Кількість запитів за хвилину на ключ обмежена — значення в розділі Ліміти.
  • Без ключа працює лише демо-чат на сайті: запит без ключа зі свого коду отримає 402 з is_demo.
  • Ключами керують лише в кабінеті: /api/keys з API-ключем недоступний. Баланс і витрати за ключем — API акаунта.

Ключ — це секрет: не зберігайте його в репозиторії та в коді фронтенду, передавайте через змінні середовища.

Приклади#

Один і той самий запит у чотирьох SDK. Модель — рекомендована (MiniMaxAI/MiniMax-M2.7), ключ — зі змінної середовища JOINGONKA_API_KEY.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://gate.joingonka.ai/v1",
    api_key=os.environ["JOINGONKA_API_KEY"],
)

response = client.chat.completions.create(
    model="MiniMaxAI/MiniMax-M2.7",
    messages=[{"role": "user", "content": "What is Gonka?"}],
)
print(response.choices[0].message.content)

Потокова відповідь#

import os
from openai import OpenAI

client = OpenAI(base_url="https://gate.joingonka.ai/v1", api_key=os.environ["JOINGONKA_API_KEY"])

stream = client.chat.completions.create(
    model="MiniMaxAI/MiniMax-M2.7",
    messages=[{"role": "user", "content": "What is Gonka?"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Параметри запиту#

Параметри POST /v1/chat/completions, які шлюз гарантує сам, — список supported_parameters у відповіді можливостей:

ПараметрОпис
temperatureВипадковість відповіді: чим вище, тим різноманітніше.
top_pВідбір токенів за сумарною ймовірністю.
top_kВідбір із k найімовірніших токенів.
min_pВідсікання малоймовірних токенів відносно найімовірнішого.
frequency_penaltyШтраф за часті повтори.
presence_penaltyШтраф за токени, що вже зустрічалися.
repetition_penaltyМножник проти повторів.
stopРядки, на яких генерація зупиняється.
seedЗерно для відтворюваності.
max_tokensЛіміт токенів відповіді; більше за стелю моделі — обрізається до стелі.
max_completion_tokensІнша назва max_tokens: шлюз переносить значення в нього.
toolsФункції, які модель може викликати, у форматі OpenAI.
tool_choiceЧи викликати функцію: на вибір моделі, ніколи, обов'язково або конкретну.
response_formatСтруктурована відповідь: json_object або json_schema.
  • Без temperature шлюз підставляє 0.7.
  • Без max_tokens шлюз підставляє усталене значення моделі: без стріму — коротше, у стрімі — стеля моделі. Числа за моделями — у розділі Ліміти.

Передаються в мережу як є#

reasoning_effort, reasoning, enable_thinking, chat_template_kwargs, thinking_token_budget, min_tokens, logit_bias, n, parallel_tool_calls, extra_body. Шлюз їх не перевіряє: значення поза списком мережі — помилка 400 з типом api_error.

Не передаються в мережу#

Решту полів шлюз приймає і не передає в мережу — наприклад, user, metadata, store, logprobs, top_logprobs, thinking, stream_options, web_search_options. usage у стрімі надходить завжди.

Стрімінг#

  • stream: true — відповідь подіями SSE; остання подія — data: [DONE].
  • Перед завершенням надходить чанк із usage — завжди, навіть без stream_options.
  • У паузах шлюз кожні 15 с надсилає коментар : keep-alive — SSE-клієнти його пропускають.
  • Поки потік не відкрито, відмова надходить звичайним кодом відповіді; після відкриття — чанком joingonka-error.
  • У delta.tool_calls — один виклик на чанк: склеєні мережею виклики шлюз розрізає.
SSE
data: {"object":"chat.completion.chunk","model":"MiniMaxAI/MiniMax-M2.7","choices":[{"index":0,"delta":{"content":"Hi"},"finish_reason":null}]}

data: {"object":"chat.completion.chunk","model":"MiniMaxAI/MiniMax-M2.7","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"object":"chat.completion.chunk","model":"MiniMaxAI/MiniMax-M2.7","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":2,"total_tokens":14}}

data: [DONE]

Службові чанки шлюзу#

Їх можна впізнати за полем id:

idКоли і що всередині
joingonka-errorЗбій після відкриття потоку: поле error, потім обрив без [DONE].
joingonka-stream-stalledМережа мовчала довше за допустиму паузу: потік закривається з finish_reason: stop.
joingonka-stream-unfinishedМережа обірвала генерацію: finish_reason: length — продовжте наступним запитом.
joingonka-citationsДжерела вебпошуку в delta.annotations — перед завершенням.
joingonka-metaВартість і тайминги — лише із заголовком x-joingonka-meta: 1.

Стрім в інших протоколах#

  • Anthropic Messages: події від message_start до message_stop, у паузах event: ping, збій — event: error.
  • OpenAI Responses: події response.*, збій — response.failed.
  • Legacy Completions: при збої — data: {"error": …}, потім [DONE].

Виклик інструментів#

  • Формат OpenAI: tools і tool_choice. Старий формат functions і function_call теж приймається — відповідь надійде в ньому ж.
  • У стрімі — один виклик на чанк: клієнти, які читають лише перший елемент, не втрачають виклики.
  • Історію, на якій мережа відповіла б помилкою 400, шлюз виправляє: роль developer стає system, порожні та повторювані id викликів отримують унікальні, arguments об'єктом перетворюється на рядок JSON, пропущений type доповнюється, виклик без імені прибирається разом із результатом.
  • Виклик, який модель написала розміткою в тексті, шлюз переносить у tool_calls; хибні виклики у відповіді на запит без інструментів прибирає.
  • Генерація обірвалася посеред аргументів — надійде finish_reason: length, а не tool_calls: збільште ліміт відповіді.
JSON
{
  "model": "MiniMaxAI/MiniMax-M2.7",
  "messages": [{"role": "user", "content": "What is the weather in Paris?"}],
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Current weather for a city",
      "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
      }
    }
  }]
}

Обмеження JSON-Schema#

Схеми інструментів і response_format мережа компілює в граматику; регулярні вирази — рушієм RE2. Шлюз приводить схему до форми, яку мережа прийме:

  • $ref розкриваються на місці, розділи $defs і definitions видаляються; рекурсивне посилання стає схемою без обмежень.
  • pattern з конструкціями, яких немає в RE2 (погляд уперед і назад, зворотні посилання, атомарні групи, наджертовні квантифікатори), знімається; повтори більше за 1000 скорочуються до 1000.
  • anyOf і oneOf з констант згортаються в enum; якщо незгортуваних гілок більше за 16, об'єднання знімається.

Схема може стати м'якшою за вихідну — перевіряйте аргументи виклику на своїй стороні.

Структурована відповідь#

response_format: {"type": "json_object"} — відповідь валідним JSON, {"type": "json_schema", "json_schema": {"name": …, "schema": …}} — за вашою схемою з обмеженнями вище. Обрізаний JSON без стріму виправляє плагін response-healing.

JSON
{
  "model": "MiniMaxAI/MiniMax-M2.7",
  "messages": [{"role": "user", "content": "Name three planets."}],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "planets",
      "schema": {
        "type": "object",
        "properties": {"planets": {"type": "array", "items": {"type": "string"}}},
        "required": ["planets"]
      }
    }
  }
}

Міркування#

  • Міркування моделі надходять окремо від відповіді: message.reasoning_content, у стрімі — delta.reasoning_content. Поле reasoning шлюз перейменовує в цей формат.
  • Міркування витрачають max_tokens: при малому ліміті відповідь обривається (finish_reason: length) ще до тексту.
  • Якщо тексту відповіді немає, а міркування є, шлюз переносить їх у content — крім відповідей із викликом інструмента.
  • reasoning_effort і reasoning.effort передаються в мережу. Якщо у моделі лише два режими, шлюз приводить значення до них: none і minimal — до low, вищі — до міркування за замовчуванням.
  • Якщо нода відкинула значення, шлюз знижує його (max і xhigh → high, minimal → low, інакше знімає поле) і повторює запит.
  • У /v1/messages міркування не передаються — блоків thinking немає.

Плагіни#

Плагіни вмикаються полем plugins — масивом рядків або об'єктів з опціями. Список — GET /v1/plugins.

ПлагінОписУмови
response-healingВиправляє обрізаний JSON у відповіді моделі.Лише без стріму і якщо відповідь починається з { або [.
privacy-sanitizationМаскує в текстових повідомленнях email, IPv4, номери карт, JWT, 64-символьні hex-ключі та ключі виду sk-…, gw_…, gm-…, Bearer ….Режим — поле privacy_mode: redact (за замовчуванням) або tokenize.
file-parserВитягує текст із PDF.Якщо текст повідомлення цілком — PDF у base64: data:application/pdf;base64,… або без префікса.
webВебпошук: результати підмішуються в запит, відповідь отримує посилання на джерела.Разом із privacy-sanitization — помилка 400.
  • Опції: max_results — від 1 до 10, за замовчуванням 5; engine — підказка рушія; search_prompt — свій текст перед результатами; enabled: false — вимкнути пошук.
  • Джерела — у message.annotations[].url_citation; у стрімі — чанком joingonka-citations перед завершенням.
  • mode: "agent" — модель сама вирішує, чи шукати і що; max_searches — від 1 до 5, за замовчуванням 3.
  • Оплата: у звичайному режимі — лише токени (результати пошуку входять у вхідні токени); у режимі агента — токени всіх кроків плюс 1000 nGNK за кожен виконаний пошук (x_joingonka.web_search_surcharge_ngonka).
  • В Anthropic Messages та OpenAI Responses вбудований інструмент web_search виконує той самий плагін у режимі агента.
{
  "model": "MiniMaxAI/MiniMax-M2.7",
  "messages": [{"role": "user", "content": "What is new in the Gonka network?"}],
  "plugins": [{"id": "web", "max_results": 5}]
}

Вартість і службові поля#

Відповідь без стріму містить вартість запиту в usage:

ПолеОпис
usage.cost_gnkВартість запиту в GNK
usage.platform_fee_gnkЗ неї — націнка платформи, GNK
usage.total_cost_gnkПідсумок до списання в GNK
usage.total_cost_usdПідсумок у доларах за поточним курсом GNK
  • У стрімі usage містить лише токени; вартість — у чанку joingonka-meta.
  • Із заголовком x-joingonka-meta: 1 відповідь POST /v1/chat/completions отримує блок x_joingonka: вартість (cost_ngonka), баланс після списання (balance_ngonka, лише без стріму) і таймінги (ttft_ms). Інші протоколи цей блок не віддають.
  • x-request-id — ідентифікатор запиту: додайте його до звернення в підтримку.
  • Retry-After надходить із 429: стільки секунд зачекати перед повторенням.
  • Заголовки X-Title і HTTP-Referer (як в OpenRouter) допомагають шлюзу розпізнати ваш застосунок; їхній текст не зберігається.

Обмеження#

  • Зображення: частини image_url замінюються текстовою заглушкою — модель картинку не бачить (vision: false у можливостях).
  • З браузера API доступний лише з доменів JoinGonka (перевірка Origin): викликайте його зі свого сервера, ключ у фронтенд не кладіть.
  • Ембединги: POST /v1/embeddings відповідає 501 — у мережі немає ембедингових моделей.
  • Коди помилок, ліміти й таймаути — у розділі Помилки та ліміти.