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żka | Format | Do czego | Szczegóły |
|---|---|---|---|
POST /v1/chat/completions | OpenAI Chat Completions | Czat, agenci, wywoływanie narzędzi | Główna ścieżka: pozostałe formaty brama tłumaczy na ten format. |
POST /v1/messages | Anthropic Messages | Claude Code i SDK Anthropic | Adres bazowy bez /v1; modele claude-* zastępowane zalecanym; pole max_tokens obowiązkowe. |
POST /v1/responses | OpenAI Responses | Codex CLI i nowe SDK OpenAI | Bezstanowo: historię przesyłaj w całości w każdym zapytaniu. |
POST /v1/completions | OpenAI Completions (legacy) | Autouzupełnianie i edycja kodu w edytorach | suffix przekazywany modelowi jako podpowiedź; w odpowiedzi logprobs: null. |
POST /v1/embeddings | OpenAI Embeddings | Reprezentacje wektorowe tekstu | Odpowiedź 501: w sieci nie ma modeli embeddingowych. |
Adresy informacyjne#
Odpowiadają bez klucza. Tabela modeli z kontekstem i statusem — w sekcji Modele.
| Metoda i ścieżka | Opis |
|---|---|
GET /v1/models | Lista 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/capabilities | Możliwości bramy: parametry, protokoły, pluginy, pola kosztów i limity (limits). |
GET /v1/plugins | Pluginy: id i nazwa. |
GET /v1/network-status | Stan modeli sieci: dostępność, opóźnienia, uptime. |
GET /v1/nodes | Podsumowanie puli węzłów: ile łącznie, aktywnych i w kwarantannie. |
GET /v1/web-search/engines | Czy 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) lubAuthorization: Bearer. - Modele
claude-*brama zastępuje zalecanym (MiniMaxAI/MiniMax-M2.7); w polumodelodpowiedzi pozostaje nazwa przesłana przez klienta. max_tokensjest 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 zdarzeniemevent: error. - Rozumowanie modelu nie trafia do odpowiedzi: bloków
thinkingnie ma. - Wbudowane narzędzie
web_searchwykonuje 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
claudecurl https://gate.joingonka.ai/v1/messages \
-H "x-api-key: $JOINGONKA_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "MiniMaxAI/MiniMax-M2.7",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "What is Gonka?"}]
}'OpenAI Responses#
- Brama nie przechowuje odpowiedzi: przesyłaj całą historię w
input. Polaprevious_response_idiconversation— błąd400z kodem. storejest przyjmowany i niczego nie zmienia.- Narzędzia:
functioniweb_search— to drugie wykonuje plugin wyszukiwania w sieci. Inne wbudowane narzędzia brama pomija i zapytanie wykonuje się bez nich; żądanie takiego narzędzia przeztool_choice— błąd400. - Części
input_imageiinput_file— błąd400: 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ą404z 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ź — wchoices[].text. Wiele promptów lub tokeny zamiast tekstu — błąd400.suffixprzekazywany modelowi jako podpowiedź w prompcie: sieć nie ma prawdziwego wypełniania środka.- W odpowiedzi
logprobs: null;best_ofjest ignorowany;echodział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.
| Prefiks | Klucz | Zapytania do modeli |
|---|---|---|
jg- | Zwykły klucz konta | tak |
gc- | Klucz podrzędny: własne limity, wydatki — z salda właściciela | tak |
gm- | Klucz zarządzający: tylko zarządzanie kluczami podrzędnymi | nie — 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
402zis_demo. - Kluczami zarządza się tylko w panelu:
/api/keysz 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)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gate.joingonka.ai/v1",
apiKey: process.env.JOINGONKA_API_KEY,
});
const response = await client.chat.completions.create({
model: "MiniMaxAI/MiniMax-M2.7",
messages: [{ role: "user", content: "What is Gonka?" }],
});
console.log(response.choices[0].message.content);curl https://gate.joingonka.ai/v1/chat/completions \
-H "Authorization: Bearer $JOINGONKA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MiniMaxAI/MiniMax-M2.7",
"messages": [{"role": "user", "content": "What is Gonka?"}]
}'import os
import anthropic
client = anthropic.Anthropic(
base_url="https://gate.joingonka.ai",
api_key=os.environ["JOINGONKA_API_KEY"],
)
message = client.messages.create(
model="MiniMaxAI/MiniMax-M2.7",
max_tokens=1024,
messages=[{"role": "user", "content": "What is Gonka?"}],
)
print(message.content[0].text)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)import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://gate.joingonka.ai/v1", apiKey: process.env.JOINGONKA_API_KEY });
const stream = await client.chat.completions.create({
model: "MiniMaxAI/MiniMax-M2.7",
messages: [{ role: "user", content: "What is Gonka?" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}curl -N https://gate.joingonka.ai/v1/chat/completions \
-H "Authorization: Bearer $JOINGONKA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MiniMaxAI/MiniMax-M2.7",
"messages": [{"role": "user", "content": "What is Gonka?"}],
"stream": true
}'import os
import anthropic
client = anthropic.Anthropic(base_url="https://gate.joingonka.ai", api_key=os.environ["JOINGONKA_API_KEY"])
with client.messages.stream(
model="MiniMaxAI/MiniMax-M2.7",
max_tokens=1024,
messages=[{"role": "user", "content": "What is Gonka?"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)Parametry zapytania#
Parametry POST /v1/chat/completions, które bramka gwarantuje sama — lista supported_parameters w odpowiedzi capabilities:
| Parametr | Opis |
|---|---|
temperature | Losowość odpowiedzi: im wyższa, tym bardziej zróżnicowana. |
top_p | Wybór tokenów według skumulowanego prawdopodobieństwa. |
top_k | Wybór spośród k najbardziej prawdopodobnych tokenów. |
min_p | Odcięcie mało prawdopodobnych tokenów względem najbardziej prawdopodobnego. |
frequency_penalty | Kara za częste powtórzenia. |
presence_penalty | Kara za tokeny, które już się pojawiły. |
repetition_penalty | Mnożnik przeciw powtórzeniom. |
stop | Ciągi, na których generacja się zatrzymuje. |
seed | Ziarno dla powtarzalności. |
max_tokens | Limit tokenów odpowiedzi; powyżej pułapu modelu — przycinane do pułapu. |
max_completion_tokens | Inna nazwa max_tokens: bramka przenosi do niej wartość. |
tools | Funkcje, które model może wywołać, w formacie OpenAI. |
tool_choice | Czy wywołać funkcję: do wyboru modelu, nigdy, obowiązkowo lub konkretną. |
response_format | Odpowiedź strukturalna: json_object lub json_schema. |
- Bez
temperaturebramka podstawia0.7. - Bez
max_tokensbramka 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 bezstream_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.
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:
id | Kiedy i co w środku |
|---|---|
joingonka-error | Awaria po otwarciu strumienia: pole error, potem przerwanie bez [DONE]. |
joingonka-stream-stalled | Sieć milczała dłużej niż dopuszczalna pauza: strumień zamyka się z finish_reason: stop. |
joingonka-stream-unfinished | Sieć przerwała generację: finish_reason: length — kontynuuj kolejnym zapytaniem. |
joingonka-citations | Źródła wyszukiwania w sieci w delta.annotations — przed zakończeniem. |
joingonka-meta | Koszt i czasy — tylko z nagłówkiem x-joingonka-meta: 1. |
Streaming w innych protokołach#
- Anthropic Messages: zdarzenia od
message_startdomessage_stop, w pauzachevent: 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:
toolsitool_choice. Stary formatfunctionsifunction_callteż 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: roladeveloperstaje sięsystem, puste i powtarzające się id wywołań otrzymują unikalne,argumentsjako obiekt zmienia się w ciąg JSON, brakującytypejest 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 nietool_calls: zwiększ limit odpowiedzi.
{
"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:
$refsą rozwijane na miejscu, sekcje$defsidefinitionssą usuwane; odwołanie rekursywne staje się schematem bez ograniczeń.patternz 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.anyOfioneOfze stałych są zwijane doenum; 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.
{
"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. Polereasoningbramka 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_effortireasoning.effortsą przekazywane do sieci. Jeśli model ma tylko dwa tryby, bramka doprowadza wartość do nich:noneiminimal— dolow, wyższe — do rozumowania domyślnego.- Jeśli noda odrzuciła wartość, bramka obniża ją (
maxixhigh→high,minimal→low, w przeciwnym razie usuwa pole) i powtarza zapytanie. - W
/v1/messagesrozumowanie nie jest przekazywane — blokówthinkingnie ma.
Pluginy#
Pluginy włącza się polem plugins — tablicą ciągów lub obiektów z opcjami. Lista — GET /v1/plugins.
| Plugin | Opis | Warunki |
|---|---|---|
response-healing | Naprawia obcięty JSON w odpowiedzi modelu. | Tylko bez streamingu i jeśli odpowiedź zaczyna się od { lub [. |
privacy-sanitization | Maskuje 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-parser | Wyciąga tekst z PDF. | Jeśli tekst wiadomości w całości to PDF w base64: data:application/pdf;base64,… lub bez prefiksu. |
web | Wyszukiwanie w sieci: wyniki są domieszane do zapytania, odpowiedź otrzymuje linki do źródeł. | Razem z privacy-sanitization — błąd 400. |
Wyszukiwanie w sieci#
- 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 — chunkiemjoingonka-citationsprzed 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_searchuruchamia 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}]
}{
"model": "MiniMaxAI/MiniMax-M2.7",
"messages": [{"role": "user", "content": "What is new in the Gonka network?"}],
"plugins": [{"id": "web", "mode": "agent", "max_searches": 3}]
}Koszt i pola techniczne#
Odpowiedź bez streamingu zawiera koszt zapytania w usage:
| Pole | Opis |
|---|---|
usage.cost_gnk | Koszt zapytania w GNK |
usage.platform_fee_gnk | Z tego — marża platformy, GNK |
usage.total_cost_gnk | Kwota do obciążenia w GNK |
usage.total_cost_usd | Kwota w dolarach według aktualnego kursu GNK |
- W streamingu
usagezawiera tylko tokeny; koszt — w chunkujoingonka-meta. - Z nagłówkiem
x-joingonka-meta: 1odpowiedźPOST /v1/chat/completionsotrzymuje blokx_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-Afterprzychodzi z429: tyle sekund trzeba poczekać przed ponowieniem.- Nagłówki
X-TitleiHTTP-Referer(jak w OpenRouter) pomagają bramie rozpoznać Twoją aplikację; ich treść nie jest zapisywana.
Ograniczenia#
- Obrazy: części
image_urlsą zastępowane tekstowym placeholderem — model nie widzi obrazka (vision: falsew 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/embeddingsodpowiada501— w sieci nie ma modeli embeddingowych. - Kody błędów, limity i timeouty — w sekcji Błędy i limity.