Per gli agenti AI: guida passo passo alla configurazione — /docs/agents.md, indice della documentazione — /llms.txt.
Riferimento API
Tutto sulle richieste al gateway: protocolli, indirizzi, chiavi e parametri. Di seguito — streaming, chiamata di strumenti, ragionamento, plugin e costo della richiesta nella risposta.
Protocolli e indirizzi#
Il gateway accetta i formati OpenAI e Anthropic. Il Base URL per gli SDK OpenAI è https://gate.joingonka.ai/v1, per gli SDK Anthropic è https://gate.joingonka.ai. Tutti i protocolli funzionano con la stessa chiave e lo stesso saldo: una richiesta in qualsiasi formato segue lo stesso percorso.
| Metodo e percorso | Formato | A cosa serve | Note |
|---|---|---|---|
POST /v1/chat/completions | OpenAI Chat Completions | Chat, agenti, chiamata di strumenti | Percorso principale: il gateway converte gli altri formati in questo. |
POST /v1/messages | Anthropic Messages | Claude Code e SDK Anthropic | Base URL senza /v1; i modelli claude-* vengono sostituiti con quello consigliato; il campo max_tokens è obbligatorio. |
POST /v1/responses | OpenAI Responses | Codex CLI e i nuovi SDK OpenAI | Senza stato: invia la cronologia completa in ogni richiesta. |
POST /v1/completions | OpenAI Completions (legacy) | Autocompletamento e correzione del codice negli editor | suffix viene passato al modello come suggerimento; nella risposta logprobs: null. |
POST /v1/embeddings | OpenAI Embeddings | Rappresentazioni vettoriali del testo | Risposta 501: nella rete non ci sono modelli di embedding. |
Indirizzi di riferimento#
Rispondono senza chiave. La tabella dei modelli con contesto e stato è nella sezione Modelli.
| Metodo e percorso | Descrizione |
|---|---|
GET /v1/models | Elenco dei modelli: contesto, prezzi, parametri supportati — campi nel formato OpenRouter. |
GET /v1/models/{model} | Scheda di un singolo modello; lo slash nell'id va inserito così com'è oppure come %2F. Modello nascosto o sconosciuto — 404 model_not_found. |
GET /v1/capabilities | Funzionalità del gateway: parametri, protocolli, plugin, campi di costo e limiti (limits). |
GET /v1/plugins | Plugin: id e nome. |
GET /v1/network-status | Stato dei modelli della rete: disponibilità, latenze, uptime. |
GET /v1/nodes | Riepilogo del pool di nodi: quanti in totale, attivi e in quarantena. |
GET /v1/web-search/engines | Se la ricerca web è attiva e in che stato sono i suoi motori. |
Anthropic Messages#
- Base URL —
https://gate.joingonka.ai: l'SDK aggiunge/v1/messagesda solo. - Chiave — nell'header
x-api-key(così la invia l'SDK Anthropic) oppureAuthorization: Bearer. - I modelli
claude-*vengono sostituiti dal gateway con quello consigliato (MiniMaxAI/MiniMax-M2.7); nel campomodeldella risposta resta il nome inviato dal client. max_tokensè obbligatorio, come nell'API Anthropic; se supera il tetto del modello viene tagliato.- Stream — eventi Anthropic; nelle pause il gateway invia
event: ping, un errore arriva come eventoevent: error. - Il ragionamento del modello non compare nella risposta: non ci sono blocchi
thinking. - Lo strumento integrato
web_searchviene eseguito dal plugin di ricerca web del gateway — vedi la sezione Plugin. - Non c'è il conteggio dei token (
/v1/messages/count_tokens) — risposta404.
Configurare Claude Code è più semplice con l'installer — connessione degli strumenti. Manualmente, tramite variabili d'ambiente; ANTHROPIC_MODEL fissa il modello della rete.
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#
- Il gateway non conserva le risposte: invia tutta la cronologia in
input. I campiprevious_response_ideconversation— errore400con codice. storeviene accettato senza alcun effetto.- Strumenti:
functioneweb_search— quest'ultimo viene eseguito dal plugin di ricerca web. Gli altri strumenti integrati vengono ignorati dal gateway e la richiesta va a buon fine senza di essi; richiedere uno di questi strumenti tramitetool_choice— errore400. - Le parti
input_imageeinput_file— errore400: i modelli della rete lavorano con il testo. - Gli indirizzi di stato (
GET /v1/responses/{id},DELETE /v1/responses/{id},GET /v1/responses/{id}/input_items,POST /v1/responses/{id}/cancel,POST /v1/responses/compact) rispondono404con codice — il gateway non conserva le risposte. - Codex CLI: imposta il tuo id di provider in
model_provider(non openai) — così Codex comprime la cronologia da solo, senza/v1/responses/compact.
Legacy Completions#
prompt— stringa o array con una sola stringa; la risposta è inchoices[].text. Più prompt o token al posto del testo — errore400.suffixviene passato al modello come suggerimento nel prompt: la rete non supporta davvero il riempimento centrale.- Nella risposta
logprobs: null;best_ofviene ignorato;echofunziona.
Chiavi e autorizzazione#
La chiave si passa nell'header Authorization: Bearer jg-… oppure x-api-key: jg-… — su tutti gli indirizzi. La chiave si crea dopo la registrazione nella pagina gate.joingonka.ai/keys.
| Prefisso | Chiave | Richieste ai modelli |
|---|---|---|
jg- | Chiave normale dell'account | sì |
gc- | Chiave figlia: limiti propri, spesa dal saldo del proprietario | sì |
gm- | Chiave di gestione: gestisce solo le chiavi figlie | no — 403 forbidden |
- A ogni chiave nell'area personale si può assegnare un limite di spesa giornaliero, mensile e totale; se lo superi —
402 child_key_limit_exceeded. - Il numero di richieste al minuto per chiave è limitato — i valori sono nella sezione Limiti.
- Senza chiave funziona solo la chat demo sul sito: una richiesta dal tuo codice senza chiave riceverà
402conis_demo. - Le chiavi si gestiscono solo nell'area personale:
/api/keyscon API key non è accessibile. Saldo e spesa per chiave — API dell'account.
La chiave è un segreto: non conservarla nel repository né nel codice frontend, trasmettila tramite variabili d'ambiente.
Esempi#
La stessa richiesta in quattro SDK. Il modello è quello consigliato (MiniMaxAI/MiniMax-M2.7), la chiave proviene dalla variabile d'ambiente 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)Risposta in streaming#
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)Parametri della richiesta#
I parametri di POST /v1/chat/completions che il gateway garantisce da sé — la lista supported_parameters nella risposta capabilities:
| Parametro | Descrizione |
|---|---|
temperature | Casualità della risposta: più è alto, più è varia. |
top_p | Selezione dei token per probabilità cumulata. |
top_k | Selezione tra i k token più probabili. |
min_p | Taglio dei token improbabili rispetto a quello più probabile. |
frequency_penalty | Penalità per le ripetizioni frequenti. |
presence_penalty | Penalità per i token già comparsi. |
repetition_penalty | Moltiplicatore contro le ripetizioni. |
stop | Stringhe su cui la generazione si ferma. |
seed | Seme per la riproducibilità. |
max_tokens | Limite di token della risposta; oltre il tetto del modello — viene tagliata al tetto. |
max_completion_tokens | Un altro nome di max_tokens: il gateway vi trasferisce il valore. |
tools | Funzioni che il modello può chiamare, nel formato OpenAI. |
tool_choice | Se chiamare una funzione: a scelta del modello, mai, obbligatoriamente o una specifica. |
response_format | Risposta strutturata: json_object o json_schema. |
- Senza
temperatureil gateway inserisce0.7. - Senza
max_tokensil gateway inserisce il default del modello: senza stream — più corto, in streaming — il tetto del modello. I numeri per modello sono nella sezione Limiti.
Trasmessi alla rete così come sono#
reasoning_effort, reasoning, enable_thinking, chat_template_kwargs, thinking_token_budget, min_tokens, logit_bias, n, parallel_tool_calls, extra_body. Il gateway non li verifica: un valore fuori dalla lista della rete — errore 400 con tipo api_error.
Non trasmessi alla rete#
Gli altri campi il gateway li accetta e non li trasmette alla rete — per esempio user, metadata, store, logprobs, top_logprobs, thinking, stream_options, web_search_options. usage in streaming arriva sempre.
Streaming#
stream: true— risposta come eventi SSE; l'ultimo evento —data: [DONE].- Prima della conclusione arriva un chunk con
usage— sempre, anche senzastream_options. - Nelle pause il gateway invia ogni 15 s un commento
: keep-alive— i client SSE lo saltano. - Finché lo stream non è aperto, il rifiuto arriva come normale codice di risposta; dopo l'apertura — come chunk
joingonka-error. - In
delta.tool_calls— una chiamata per chunk: le chiamate unite dalla rete il gateway le separa.
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]Chunk di servizio del gateway#
Si riconoscono dal campo id:
id | Quando e cosa contiene |
|---|---|
joingonka-error | Errore dopo l'apertura dello stream: campo error, poi interruzione senza [DONE]. |
joingonka-stream-stalled | La rete è rimasta in silenzio oltre la pausa consentita: lo stream si chiude con finish_reason: stop. |
joingonka-stream-unfinished | La rete ha interrotto la generazione: finish_reason: length — continua con la richiesta successiva. |
joingonka-citations | Le fonti della ricerca web in delta.annotations — prima della conclusione. |
joingonka-meta | Costo e tempistiche — solo con l'header x-joingonka-meta: 1. |
Stream in altri protocolli#
- Anthropic Messages: eventi da
message_startamessage_stop, nelle pauseevent: ping, errore —event: error. - OpenAI Responses: eventi
response.*, errore —response.failed. - Legacy Completions: in caso di errore —
data: {"error": …}, poi[DONE].
Chiamata degli strumenti#
- Formato OpenAI:
toolsetool_choice. Anche il vecchio formatofunctionsefunction_callè accettato — la risposta arriverà nello stesso. - In streaming — una chiamata per chunk: i client che leggono solo il primo elemento non perdono le chiamate.
- La cronologia su cui la rete risponderebbe con errore
400il gateway la corregge: il ruolodeveloperdiventasystem, gli id di chiamata vuoti e duplicati ricevono id univoci,argumentscome oggetto diventa una stringa JSON, iltypemancante viene aggiunto, la chiamata senza nome viene rimossa insieme al risultato. - La chiamata che il modello ha scritto come markup nel testo il gateway la sposta in
tool_calls; le chiamate false nella risposta a una richiesta senza strumenti le rimuove. - La generazione si è interrotta a metà degli argomenti — arriverà
finish_reason: length, nontool_calls: aumenta il limite della risposta.
{
"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"]
}
}
}]
}Limitazioni di JSON-Schema#
Gli schemi degli strumenti e response_format la rete li compila in una grammatica; le espressioni regolari — con il motore RE2. Il gateway porta lo schema alla forma che la rete accetta:
- I
$refvengono espansi sul posto, le sezioni$defsedefinitionsvengono rimosse; un riferimento ricorsivo diventa uno schema senza vincoli. - I
patterncon costrutti assenti in RE2 (lookahead e lookbehind, backreference, gruppi atomici, quantificatori possessivi) vengono rimossi; le ripetizioni superiori a 1000 vengono ridotte a 1000. anyOfeoneOfdi costanti vengono compattati inenum; se i rami non compattabili sono più di 16, l'unione viene rimossa.
Lo schema può diventare più permissivo dell'originale — verifica gli argomenti della chiamata dalla tua parte.
Risposta strutturata#
response_format: {"type": "json_object"} — risposta come JSON valido, {"type": "json_schema", "json_schema": {"name": …, "schema": …}} — secondo il tuo schema con le limitazioni sopra. Il JSON troncato senza stream viene corretto dal 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"]
}
}
}
}Ragionamento#
- Il ragionamento del modello arriva separato dalla risposta:
message.reasoning_content, in streaming —delta.reasoning_content. Il camporeasoningil gateway lo rinomina in questo formato. - Il ragionamento consuma
max_tokens: con un limite piccolo la risposta si interrompe (finish_reason: length) ancora prima del testo. - Se il testo della risposta manca ma il ragionamento c'è, il gateway lo sposta in
content— tranne le risposte con chiamata di strumento. reasoning_effortereasoning.effortvengono trasmessi alla rete. Se il modello ha solo due modalità, il gateway adegua il valore:noneeminimal— alow, quelli più alti — al ragionamento predefinito.- Se il nodo rifiuta il valore, il gateway lo abbassa (
maxexhigh→high,minimal→low, altrimenti rimuove il campo) e ripete la richiesta. - In
/v1/messagesil ragionamento non viene trasmesso — non ci sono blocchithinking.
Plugin#
I plugin si attivano con il campo plugins — come array di stringhe o di oggetti con opzioni. La lista — GET /v1/plugins.
| Plugin | Descrizione | Condizioni |
|---|---|---|
response-healing | Corregge il JSON troncato nella risposta del modello. | Solo senza stream e se la risposta inizia con { o [. |
privacy-sanitization | Maschera nei messaggi di testo email, IPv4, numeri di carta, JWT, chiavi hex di 64 caratteri e chiavi del tipo sk-…, gw_…, gm-…, Bearer …. | La modalità è il campo privacy_mode: redact (predefinita) o tokenize. |
file-parser | Estrae il testo da un PDF. | Se il testo del messaggio è interamente un PDF in base64: data:application/pdf;base64,… o senza prefisso. |
web | Ricerca web: i risultati vengono mescolati nella richiesta, la risposta riceve i link alle fonti. | Insieme a privacy-sanitization — errore 400. |
Ricerca web#
- Opzioni:
max_results— da 1 a 10, predefinito 5;engine— suggerimento del motore;search_prompt— testo personalizzato prima dei risultati;enabled: false— disattiva la ricerca. - Le fonti — in
message.annotations[].url_citation; in streaming — come chunkjoingonka-citationsprima della conclusione. mode: "agent"— il modello decide da sé se cercare e cosa;max_searches— da 1 a 5, predefinito 3.- Pagamento: in modalità normale — solo token (i risultati di ricerca rientrano nei token di input); in modalità agente — i token di tutti i passaggi più 1000 nGNK per ogni ricerca eseguita (
x_joingonka.web_search_surcharge_ngonka). - In Anthropic Messages e OpenAI Responses lo strumento integrato
web_searchesegue lo stesso plugin in modalità agente.
{
"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}]
}Costo e campi di servizio#
La risposta non in streaming riporta il costo della richiesta in usage:
| Campo | Descrizione |
|---|---|
usage.cost_gnk | Costo della richiesta in GNK |
usage.platform_fee_gnk | Di cui — maggiorazione della piattaforma, GNK |
usage.total_cost_gnk | Totale da addebitare in GNK |
usage.total_cost_usd | Totale in dollari al cambio GNK corrente |
- Nello streaming
usagecontiene solo token; il costo è nel chunkjoingonka-meta. - Con l'header
x-joingonka-meta: 1la rispostaPOST /v1/chat/completionsriceve il bloccox_joingonka: costo (cost_ngonka), saldo dopo l'addebito (balance_ngonka, solo senza streaming) e tempi (ttft_ms). Gli altri protocolli non restituiscono questo blocco. x-request-id— identificatore della richiesta: allegalo alla richiesta di assistenza.Retry-Afterarriva con429: quanti secondi attendere prima di riprovare.- Gli header
X-TitleeHTTP-Referer(come su OpenRouter) aiutano il gateway a riconoscere la tua applicazione; il loro testo non viene salvato.
Limiti#
- Immagini: le parti
image_urlvengono sostituite da un segnaposto testuale — il modello non vede l'immagine (vision: falsenelle capacità). - Dal browser l'API è accessibile solo dai domini JoinGonka (controllo
Origin): chiamala dal tuo server, non mettere la chiave nel frontend. - Embedding:
POST /v1/embeddingsrisponde501— nella rete non ci sono modelli di embedding. - Codici di errore, limiti e timeout — nella sezione Errori e limiti.