Dla agentów AI: instrukcja konfiguracji krok po kroku — /docs/agents.md, indeks dokumentacji — /llms.txt.

Dokumentacja API

Wszystko o żądaniach do bramy: protokoły, adresy, klucze i parametry. Poniżej — streaming, wywoływanie narzędzi, rozumowanie, wtyczki i koszt żądania w odpowiedzi.

Protokoły i adresy#

Brama przyjmuje formaty OpenAI i Anthropic. Adres bazowy dla SDK OpenAI — https://gate.joingonka.ai/v1, dla SDK Anthropic — https://gate.joingonka.ai. Wszystkie protokoły działają na jednym kluczu i jednym saldzie: zapytanie w dowolnym formacie przechodzi tą samą ścieżką.

Metoda i ścieżkaFormatDo czegoSzczegóły
POST /v1/chat/completionsOpenAI Chat CompletionsCzat, agenci, wywoływanie narzędziGłówna ścieżka: pozostałe formaty brama tłumaczy na ten format.
POST /v1/messagesAnthropic MessagesClaude Code i SDK AnthropicAdres bazowy bez /v1; modele claude-* zastępowane zalecanym; pole max_tokens obowiązkowe.
POST /v1/responsesOpenAI ResponsesCodex CLI i nowe SDK OpenAIBezstanowo: historię przesyłaj w całości w każdym zapytaniu.
POST /v1/completionsOpenAI Completions (legacy)Autouzupełnianie i edycja kodu w edytorachsuffix przekazywany modelowi jako podpowiedź; w odpowiedzi logprobs: null.
POST /v1/embeddingsOpenAI EmbeddingsReprezentacje wektorowe tekstuOdpowiedź 501: w sieci nie ma modeli embeddingowych.

Adresy informacyjne#

Odpowiadają bez klucza. Tabela modeli z kontekstem i statusem — w sekcji Modele.

Metoda i ścieżkaOpis
GET /v1/modelsLista modeli: kontekst, ceny, obsługiwane parametry — pola w formacie OpenRouter.
GET /v1/models/{model}Karta jednego modelu; ukośnik w id — jak jest lub %2F. Model ukryty lub nieznany — 404 model_not_found.
GET /v1/capabilitiesMożliwości bramy: parametry, protokoły, pluginy, pola kosztów i limity (limits).
GET /v1/pluginsPluginy: id i nazwa.
GET /v1/network-statusStan modeli sieci: dostępność, opóźnienia, uptime.
GET /v1/nodesPodsumowanie puli węzłów: ile łącznie, aktywnych i w kwarantannie.
GET /v1/web-search/enginesCzy wyszukiwanie w sieci jest włączone i w jakim stanie są jego silniki.

Anthropic Messages#

  • Adres bazowy — https://gate.joingonka.ai: SDK sam doda /v1/messages.
  • Klucz — w nagłówku x-api-key (tak wysyła SDK Anthropic) lub Authorization: Bearer.
  • Modele claude-* brama zastępuje zalecanym (MiniMaxAI/MiniMax-M2.7); w polu model odpowiedzi pozostaje nazwa przesłana przez klienta.
  • max_tokens jest obowiązkowy, jak w API Anthropic; więcej niż limit modelu — zostaje obcięte.
  • Stream — zdarzenia Anthropic; w przerwach brama wysyła event: ping, błąd przychodzi zdarzeniem event: error.
  • Rozumowanie modelu nie trafia do odpowiedzi: bloków thinking nie ma.
  • Wbudowane narzędzie web_search wykonuje plugin wyszukiwania w sieci bramy — patrz sekcja Pluginy.
  • Zliczania tokenów (/v1/messages/count_tokens) nie ma — odpowiedź 404.

Claude Code najłatwiej skonfigurować instalatorem — podłączanie narzędzi. Ręcznie — zmiennymi środowiskowymi; ANTHROPIC_MODEL przypisuje model sieci.

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#

  • Brama nie przechowuje odpowiedzi: przesyłaj całą historię w input. Pola previous_response_id i conversation — błąd 400 z kodem.
  • store jest przyjmowany i niczego nie zmienia.
  • Narzędzia: function i web_search — to drugie wykonuje plugin wyszukiwania w sieci. Inne wbudowane narzędzia brama pomija i zapytanie wykonuje się bez nich; żądanie takiego narzędzia przez tool_choice — błąd 400.
  • Części input_image i input_file — błąd 400: modele sieci pracują z tekstem.
  • Adresy stanu (GET /v1/responses/{id}, DELETE /v1/responses/{id}, GET /v1/responses/{id}/input_items, POST /v1/responses/{id}/cancel, POST /v1/responses/compact) odpowiadają 404 z kodem — brama nie przechowuje odpowiedzi.
  • Codex CLI: ustaw własny id dostawcy w model_provider (nie openai) — wtedy Codex sam kompresuje historię, bez /v1/responses/compact.

Legacy Completions#

  • prompt — ciąg znaków lub tablica z jednym ciągiem; odpowiedź — w choices[].text. Wiele promptów lub tokeny zamiast tekstu — błąd 400.
  • suffix przekazywany modelowi jako podpowiedź w prompcie: sieć nie ma prawdziwego wypełniania środka.
  • W odpowiedzi logprobs: null; best_of jest ignorowany; echo działa.

Klucze i autoryzacja#

Klucz przekazywany jest w nagłówku Authorization: Bearer jg-… lub x-api-key: jg-… — na wszystkich adresach. Klucz tworzy się po rejestracji na stronie gate.joingonka.ai/keys.

PrefiksKluczZapytania do modeli
jg-Zwykły klucz kontatak
gc-Klucz podrzędny: własne limity, wydatki — z salda właścicielatak
gm-Klucz zarządzający: tylko zarządzanie kluczami podrzędnyminie — 403 forbidden
  • Każdemu kluczowi w panelu można ustawić limit wydatków na dzień, miesiąc i łącznie; przekroczenie — 402 child_key_limit_exceeded.
  • Liczba zapytań na minutę na klucz jest ograniczona — wartości w sekcji Limity.
  • Bez klucza działa tylko czat demonstracyjny na stronie: zapytanie bez klucza z własnego kodu otrzyma 402 z is_demo.
  • Kluczami zarządza się tylko w panelu: /api/keys z kluczem API jest niedostępny. Saldo i wydatki według klucza — Konto API.

Klucz to sekret: nie przechowuj go w repozytorium ani w kodzie frontendu — przekazuj przez zmienne środowiskowe.

Przykłady#

To samo zapytanie w czterech SDK. Model — zalecany (MiniMaxAI/MiniMax-M2.7), klucz — ze zmiennej środowiskowej 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)

Odpowiedź strumieniowa#

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)

Parametry zapytania#

Parametry POST /v1/chat/completions, które bramka gwarantuje sama — lista supported_parameters w odpowiedzi capabilities:

ParametrOpis
temperatureLosowość odpowiedzi: im wyższa, tym bardziej zróżnicowana.
top_pWybór tokenów według skumulowanego prawdopodobieństwa.
top_kWybór spośród k najbardziej prawdopodobnych tokenów.
min_pOdcięcie mało prawdopodobnych tokenów względem najbardziej prawdopodobnego.
frequency_penaltyKara za częste powtórzenia.
presence_penaltyKara za tokeny, które już się pojawiły.
repetition_penaltyMnożnik przeciw powtórzeniom.
stopCiągi, na których generacja się zatrzymuje.
seedZiarno dla powtarzalności.
max_tokensLimit tokenów odpowiedzi; powyżej pułapu modelu — przycinane do pułapu.
max_completion_tokensInna nazwa max_tokens: bramka przenosi do niej wartość.
toolsFunkcje, które model może wywołać, w formacie OpenAI.
tool_choiceCzy wywołać funkcję: do wyboru modelu, nigdy, obowiązkowo lub konkretną.
response_formatOdpowiedź strukturalna: json_object lub json_schema.
  • Bez temperature bramka podstawia 0.7.
  • Bez max_tokens bramka podstawia domyślną wartość modelu: bez streamingu — krótszą, w streamingu — pułap modelu. Liczby dla poszczególnych modeli — w sekcji Limity.

Przekazywane do sieci bez zmian#

reasoning_effort, reasoning, enable_thinking, chat_template_kwargs, thinking_token_budget, min_tokens, logit_bias, n, parallel_tool_calls, extra_body. Bramka ich nie sprawdza: wartość spoza listy sieci — błąd 400 z typem api_error.

Nieprzekazywane do sieci#

Pozostałe pola bramka przyjmuje i nie przekazuje do sieci — na przykład user, metadata, store, logprobs, top_logprobs, thinking, stream_options, web_search_options. usage w streamingu przychodzi zawsze.

Streaming#

  • stream: true — odpowiedź zdarzeniami SSE; ostatnie zdarzenie — data: [DONE].
  • Przed zakończeniem przychodzi chunk z usage — zawsze, nawet bez stream_options.
  • W pauzach bramka co 15 s wysyła komentarz : keep-alive — klienci SSE go pomijają.
  • Dopóki strumień nie jest otwarty, odmowa przychodzi zwykłym kodem odpowiedzi; po otwarciu — chunkiem joingonka-error.
  • W delta.tool_calls — jedno wywołanie na chunk: wywołania sklejone przez sieć bramka rozdziela.
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]

Chunki serwisowe bramki#

Można je rozpoznać po polu id:

idKiedy i co w środku
joingonka-errorAwaria po otwarciu strumienia: pole error, potem przerwanie bez [DONE].
joingonka-stream-stalledSieć milczała dłużej niż dopuszczalna pauza: strumień zamyka się z finish_reason: stop.
joingonka-stream-unfinishedSieć przerwała generację: finish_reason: length — kontynuuj kolejnym zapytaniem.
joingonka-citationsŹródła wyszukiwania w sieci w delta.annotations — przed zakończeniem.
joingonka-metaKoszt i czasy — tylko z nagłówkiem x-joingonka-meta: 1.

Streaming w innych protokołach#

  • Anthropic Messages: zdarzenia od message_start do message_stop, w pauzach event: ping, awaria — event: error.
  • OpenAI Responses: zdarzenia response.*, awaria — response.failed.
  • Legacy Completions: przy awarii — data: {"error": …}, potem [DONE].

Wywoływanie narzędzi#

  • Format OpenAI: tools i tool_choice. Stary format functions i function_call też jest akceptowany — odpowiedź przyjdzie w nim samym.
  • W streamingu — jedno wywołanie na chunk: klienci, którzy czytają tylko pierwszy element, nie tracą wywołań.
  • Historię, na której sieć zwróciłaby błąd 400, bramka naprawia: rola developer staje się system, puste i powtarzające się id wywołań otrzymują unikalne, arguments jako obiekt zmienia się w ciąg JSON, brakujący type jest uzupełniany, wywołanie bez nazwy jest usuwane razem z wynikiem.
  • Wywołanie, które model napisał znacznikami w tekście, bramka przenosi do tool_calls; fałszywe wywołania w odpowiedzi na zapytanie bez narzędzi usuwa.
  • Generacja urwała się w środku argumentów — przyjdzie finish_reason: length, a nie tool_calls: zwiększ limit odpowiedzi.
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"]
      }
    }
  }]
}

Ograniczenia JSON-Schema#

Schematy narzędzi i response_format sieć kompiluje do gramatyki; wyrażenia regularne — silnikiem RE2. Bramka doprowadza schemat do formy, którą sieć przyjmie:

  • $ref są rozwijane na miejscu, sekcje $defs i definitions są usuwane; odwołanie rekursywne staje się schematem bez ograniczeń.
  • pattern z konstrukcjami, których nie ma w RE2 (lookahead i lookbehind, backreference, grupy atomowe, kwantyfikatory possessywne), jest usuwany; powtórzenia większe niż 1000 są skracane do 1000.
  • anyOf i oneOf ze stałych są zwijane do enum; jeśli nierozwijalnych gałęzi jest więcej niż 16, unia jest usuwana.

Schemat może stać się łagodniejszy niż pierwotny — sprawdzaj argumenty wywołania po swojej stronie.

Odpowiedź strukturalna#

response_format: {"type": "json_object"} — odpowiedź poprawnym JSON-em, {"type": "json_schema", "json_schema": {"name": …, "schema": …}} — według twojego schematu z ograniczeniami powyżej. Obcięty JSON bez streamingu naprawia plugin 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"]
      }
    }
  }
}

Rozumowanie#

  • Rozumowanie modelu przychodzi oddzielnie od odpowiedzi: message.reasoning_content, w streamingu — delta.reasoning_content. Pole reasoning bramka przemianowuje na ten format.
  • Rozumowanie zużywa max_tokens: przy małym limicie odpowiedź urywa się (finish_reason: length) jeszcze przed tekstem.
  • Jeśli tekstu odpowiedzi nie ma, a rozumowanie jest, bramka przenosi je do content — poza odpowiedziami z wywołaniem narzędzia.
  • reasoning_effort i reasoning.effort są przekazywane do sieci. Jeśli model ma tylko dwa tryby, bramka doprowadza wartość do nich: none i minimal — do low, wyższe — do rozumowania domyślnego.
  • Jeśli noda odrzuciła wartość, bramka obniża ją (max i xhigh → high, minimal → low, w przeciwnym razie usuwa pole) i powtarza zapytanie.
  • W /v1/messages rozumowanie nie jest przekazywane — bloków thinking nie ma.

Pluginy#

Pluginy włącza się polem plugins — tablicą ciągów lub obiektów z opcjami. Lista — GET /v1/plugins.

PluginOpisWarunki
response-healingNaprawia obcięty JSON w odpowiedzi modelu.Tylko bez streamingu i jeśli odpowiedź zaczyna się od { lub [.
privacy-sanitizationMaskuje w wiadomościach tekstowych email, IPv4, numery kart, JWT, 64-znakowe klucze hex i klucze postaci sk-…, gw_…, gm-…, Bearer ….Tryb — pole privacy_mode: redact (domyślnie) lub tokenize.
file-parserWyciąga tekst z PDF.Jeśli tekst wiadomości w całości to PDF w base64: data:application/pdf;base64,… lub bez prefiksu.
webWyszukiwanie w sieci: wyniki są domieszane do zapytania, odpowiedź otrzymuje linki do źródeł.Razem z privacy-sanitization — błąd 400.
  • Opcje: max_results — od 1 do 10, domyślnie 5; engine — podpowiedź silnika; search_prompt — własny tekst przed wynikami; enabled: false — wyłączyć wyszukiwanie.
  • Źródła — w message.annotations[].url_citation; w streamingu — chunkiem joingonka-citations przed zakończeniem.
  • mode: "agent" — model sam decyduje, czy szukać i czego; max_searches — od 1 do 5, domyślnie 3.
  • Rozliczenia: w trybie zwykłym — tylko tokeny (wyniki wyszukiwania wliczają się do tokenów wejściowych); w trybie agenta — tokeny wszystkich kroków plus 1000 nGNK za każde wykonane wyszukiwanie (x_joingonka.web_search_surcharge_ngonka).
  • W Anthropic Messages i OpenAI Responses wbudowane narzędzie web_search uruchamia ten sam plugin w trybie agenta.
{
  "model": "MiniMaxAI/MiniMax-M2.7",
  "messages": [{"role": "user", "content": "What is new in the Gonka network?"}],
  "plugins": [{"id": "web", "max_results": 5}]
}

Koszt i pola techniczne#

Odpowiedź bez streamingu zawiera koszt zapytania w usage:

PoleOpis
usage.cost_gnkKoszt zapytania w GNK
usage.platform_fee_gnkZ tego — marża platformy, GNK
usage.total_cost_gnkKwota do obciążenia w GNK
usage.total_cost_usdKwota w dolarach według aktualnego kursu GNK
  • W streamingu usage zawiera tylko tokeny; koszt — w chunku joingonka-meta.
  • Z nagłówkiem x-joingonka-meta: 1 odpowiedź POST /v1/chat/completions otrzymuje blok x_joingonka: koszt (cost_ngonka), saldo po obciążeniu (balance_ngonka, tylko bez streamingu) i czasy (ttft_ms). Inne protokoły nie zwracają tego bloku.
  • x-request-id — identyfikator zapytania: dołącz go do zgłoszenia w support.
  • Retry-After przychodzi z 429: tyle sekund trzeba poczekać przed ponowieniem.
  • Nagłówki X-Title i HTTP-Referer (jak w OpenRouter) pomagają bramie rozpoznać Twoją aplikację; ich treść nie jest zapisywana.

Ograniczenia#

  • Obrazy: części image_url są zastępowane tekstowym placeholderem — model nie widzi obrazka (vision: false w możliwościach).
  • Z przeglądarki API jest dostępne tylko z domen JoinGonka (weryfikacja Origin): wywołuj je ze swojego serwera, nie umieszczaj klucza we froncie.
  • Embeddingi: POST /v1/embeddings odpowiada 501 — w sieci nie ma modeli embeddingowych.
  • Kody błędów, limity i timeouty — w sekcji Błędy i limity.