Pour les agents IA : guide de configuration étape par étape — /docs/agents.md, index de la documentation — /llms.txt.
Référence API
Tout sur les requêtes adressées à la passerelle : protocoles, adresses, clés et paramètres. Ci-dessous — streaming, appel d'outils, raisonnement, plugins et coût de la requête dans la réponse.
Protocoles et adresses#
La passerelle accepte les formats OpenAI et Anthropic. L'URL de base pour le SDK OpenAI est https://gate.joingonka.ai/v1, pour le SDK Anthropic — https://gate.joingonka.ai. Tous les protocoles fonctionnent avec une seule clé et un seul solde : une requête dans n'importe quel format emprunte le même chemin.
| Méthode et chemin | Format | Usage | Particularités |
|---|---|---|---|
POST /v1/chat/completions | OpenAI Chat Completions | Chat, agents, appels d'outils | Chemin principal : la passerelle y convertit tous les autres formats. |
POST /v1/messages | Anthropic Messages | Claude Code et SDK Anthropic | URL de base sans /v1 ; les modèles claude-* sont remplacés par le modèle recommandé ; le champ max_tokens est obligatoire. |
POST /v1/responses | OpenAI Responses | Codex CLI et les nouveaux SDK OpenAI | Sans état : envoyez tout l'historique à chaque requête. |
POST /v1/completions | OpenAI Completions (legacy) | Autocomplétion et correction de code dans les éditeurs | suffix est transmis au modèle comme indice ; la réponse contient logprobs: null. |
POST /v1/embeddings | OpenAI Embeddings | Représentations vectorielles du texte | Réponse 501 : le réseau ne propose pas de modèles d'embeddings. |
Adresses de référence#
Répondent sans clé. Le tableau des modèles avec contexte et statut se trouve dans la section Modèles.
| Méthode et chemin | Description |
|---|---|
GET /v1/models | Liste des modèles : contexte, prix, paramètres pris en charge — champs au format OpenRouter. |
GET /v1/models/{model} | Fiche d'un modèle ; le slash dans l'id s'écrit tel quel ou %2F. Modèle masqué ou inconnu — 404 model_not_found. |
GET /v1/capabilities | Capacités de la passerelle : paramètres, protocoles, plugins, champs de coût et limites (limits). |
GET /v1/plugins | Plugins : id et nom. |
GET /v1/network-status | État des modèles du réseau : disponibilité, latences, uptime. |
GET /v1/nodes | Résumé du pool de nœuds : total, actifs et en quarantaine. |
GET /v1/web-search/engines | Si la recherche web est activée et dans quel état sont ses moteurs. |
Anthropic Messages#
- URL de base —
https://gate.joingonka.ai: le SDK ajoutera/v1/messageslui-même. - Clé — dans l'en-tête
x-api-key(comme l'envoie le SDK Anthropic) ouAuthorization: Bearer. - Les modèles
claude-*sont remplacés par la passerelle par le modèle recommandé (MiniMaxAI/MiniMax-M2.7) ; le champmodelde la réponse conserve le nom envoyé par le client. max_tokensest obligatoire, comme dans l'API Anthropic ; au-delà du plafond du modèle — la valeur est tronquée.- Stream — événements Anthropic ; pendant les pauses, la passerelle envoie
event: ping, une erreur arrive via l'événementevent: error. - Les raisonnements du modèle n'apparaissent pas dans la réponse : pas de blocs
thinking. - L'outil intégré
web_searchest exécuté par le plugin de recherche web de la passerelle — voir la section Plugins. - Pas de comptage de tokens (
/v1/messages/count_tokens) — réponse404.
Claude Code se configure plus simplement avec l'installateur — connexion des outils. Manuellement — via des variables d'environnement ; ANTHROPIC_MODEL fixe le modèle du réseau.
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#
- La passerelle ne stocke pas les réponses : envoyez tout l'historique dans
input. Les champsprevious_response_idetconversation— erreur400avec code. storeest accepté sans rien changer.- Outils :
functionetweb_search— ce dernier est exécuté par le plugin de recherche web. Les autres outils intégrés sont ignorés par la passerelle et la requête s'exécute sans eux ; exiger un tel outil viatool_choice— erreur400. - Les parties
input_imageetinput_file— erreur400: les modèles du réseau travaillent avec du texte. - Les adresses d'état (
GET /v1/responses/{id},DELETE /v1/responses/{id},GET /v1/responses/{id}/input_items,POST /v1/responses/{id}/cancel,POST /v1/responses/compact) répondent404avec code — la passerelle ne stocke pas les réponses. - Codex CLI : définissez votre propre id de fournisseur dans
model_provider(pas openai) — Codex compresse alors l'historique lui-même, sans/v1/responses/compact.
Legacy Completions#
prompt— une chaîne ou un tableau d'une seule chaîne ; la réponse est danschoices[].text. Plusieurs prompts ou des tokens à la place du texte — erreur400.suffixest transmis au modèle comme indice dans le prompt : le réseau ne fait pas de vrai remplissage du milieu (fill-in-the-middle).- La réponse contient
logprobs: null;best_ofest ignoré ;echofonctionne.
Clés et autorisation#
La clé se transmet dans l'en-tête Authorization: Bearer jg-… ou x-api-key: jg-… — sur toutes les adresses. La clé se crée après inscription sur la page gate.joingonka.ai/keys.
| Préfixe | Clé | Requêtes vers les modèles |
|---|---|---|
jg- | Clé de compte classique | oui |
gc- | Clé enfant : limites propres, dépenses débitées du solde du propriétaire | oui |
gm- | Clé de gestion : uniquement la gestion des clés enfants | non — 403 forbidden |
- Chaque clé peut avoir une limite de dépenses par jour, par mois et au total dans l'espace client ; dépassement —
402 child_key_limit_exceeded. - Le nombre de requêtes par minute par clé est limité — les valeurs se trouvent dans la section Limites.
- Sans clé, seul le chat démo du site fonctionne : une requête sans clé depuis votre code recevra
402avecis_demo. - Les clés se gèrent uniquement dans l'espace client :
/api/keysavec une clé API est inaccessible. Solde et dépenses par clé — API du compte.
La clé est un secret : ne la stockez ni dans le dépôt ni dans le code front-end, transmettez-la via des variables d'environnement.
Exemples#
Une même requête dans quatre SDK. Modèle recommandé (MiniMaxAI/MiniMax-M2.7), clé issue de la variable d'environnement 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)Réponse en 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)Paramètres de requête#
Paramètres de POST /v1/chat/completions que la passerelle garantit elle-même — la liste supported_parameters dans la réponse de capacités :
| Paramètre | Description |
|---|---|
temperature | Aléa de la réponse : plus il est élevé, plus la réponse est variée. |
top_p | Sélection des tokens par probabilité cumulée. |
top_k | Sélection parmi les k tokens les plus probables. |
min_p | Élimination des tokens peu probables par rapport au plus probable. |
frequency_penalty | Pénalité pour les répétitions fréquentes. |
presence_penalty | Pénalité pour les tokens déjà apparus. |
repetition_penalty | Multiplicateur anti-répétition. |
stop | Chaînes sur lesquelles la génération s'arrête. |
seed | Graine pour la reproductibilité. |
max_tokens | Limite de tokens de la réponse ; au-delà du plafond du modèle, elle est ramenée au plafond. |
max_completion_tokens | Autre nom pour max_tokens : la passerelle y reporte la valeur. |
tools | Fonctions que le modèle peut appeler, au format OpenAI. |
tool_choice | Faut-il appeler une fonction : au choix du modèle, jamais, obligatoirement ou une fonction précise. |
response_format | Réponse structurée : json_object ou json_schema. |
- Sans
temperature, la passerelle applique0.7. - Sans
max_tokens, la passerelle applique la valeur par défaut du modèle : plus courte hors streaming, plafond du modèle en streaming. Les valeurs chiffrées par modèle sont dans la section Limites.
Transmis au réseau tel quel#
reasoning_effort, reasoning, enable_thinking, chat_template_kwargs, thinking_token_budget, min_tokens, logit_bias, n, parallel_tool_calls, extra_body. La passerelle ne les vérifie pas : une valeur hors de la liste du réseau renvoie une erreur 400 de type api_error.
Non transmis au réseau#
Les autres champs sont acceptés par la passerelle mais non transmis au réseau — par exemple user, metadata, store, logprobs, top_logprobs, thinking, stream_options, web_search_options. usage arrive toujours en streaming.
Streaming#
stream: true— réponse sous forme d'événements SSE ; le dernier événement estdata: [DONE].- Avant la fin, un chunk contenant
usagearrive — toujours, même sansstream_options. - Pendant les pauses, la passerelle envoie toutes les 15 s un commentaire
: keep-alive— les clients SSE l'ignorent. - Tant que le flux n'est pas ouvert, un refus arrive via un code de réponse classique ; une fois ouvert, via un chunk
joingonka-error. - Dans
delta.tool_calls— un appel par chunk : les appels fusionnés par le réseau sont découpés par la passerelle.
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]Chunks de service de la passerelle#
On les reconnaît au champ id :
id | Quand et quoi dedans |
|---|---|
joingonka-error | Échec après l'ouverture du flux : champ error, puis coupure sans [DONE]. |
joingonka-stream-stalled | Le réseau est resté silencieux au-delà de la pause autorisée : le flux se ferme avec finish_reason: stop. |
joingonka-stream-unfinished | Le réseau a interrompu la génération : finish_reason: length — reprenez avec une requête suivante. |
joingonka-citations | Sources de la recherche web dans delta.annotations — avant la fin. |
joingonka-meta | Coût et timings — uniquement avec l'en-tête x-joingonka-meta: 1. |
Streaming dans d'autres protocoles#
- Anthropic Messages : événements de
message_startàmessage_stop,event: pingpendant les pauses, échec —event: error. - OpenAI Responses : événements
response.*, échec —response.failed. - Legacy Completions : en cas d'échec —
data: {"error": …}, puis[DONE].
Appel d'outils#
- Format OpenAI :
toolsettool_choice. L'ancien formatfunctionsetfunction_callest aussi accepté — la réponse arrivera dans ce même format. - En streaming — un appel par chunk : les clients qui ne lisent que le premier élément ne perdent pas d'appels.
- L'historique sur lequel le réseau renverrait une erreur
400est corrigé par la passerelle : le rôledeveloperdevientsystem, les id d'appels vides ou en doublon reçoivent des identifiants uniques,argumentssous forme d'objet est converti en chaîne JSON, letypemanquant est complété, un appel sans nom est supprimé avec son résultat. - Un appel que le modèle a écrit en balisage dans le texte est déplacé par la passerelle dans
tool_calls; les faux appels dans une réponse à une requête sans outils sont supprimés. - La génération s'est interrompue au milieu des arguments — c'est
finish_reason: lengthqui arrive, pastool_calls: augmentez la limite de réponse.
{
"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"]
}
}
}]
}Contraintes JSON-Schema#
Les schémas d'outils et response_format sont compilés en grammaire par le réseau ; les expressions régulières par le moteur RE2. La passerelle ramène le schéma à une forme acceptable par le réseau :
- Les
$refsont développées sur place, les sections$defsetdefinitionssont supprimées ; une référence récursive devient un schéma sans contraintes. patterncontenant des constructions absentes de RE2 (lookahead, lookbehind, rétroréférences, groupes atomiques, quantificateurs possessifs) est retiré ; les répétitions supérieures à 1000 sont réduites à 1000.anyOfetoneOfcomposés de constantes sont repliés enenum; si les branches non repliables dépassent 16, l'union est supprimée.
Le schéma peut devenir plus permissif que l'original — validez les arguments d'appel de votre côté.
Réponse structurée#
response_format : {"type": "json_object"} — réponse en JSON valide, {"type": "json_schema", "json_schema": {"name": …, "schema": …}} — selon votre schéma avec les contraintes ci-dessus. Le JSON tronqué hors streaming est corrigé par le 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"]
}
}
}
}Raisonnement#
- Le raisonnement du modèle arrive séparément de la réponse :
message.reasoning_content, en streaming —delta.reasoning_content. Le champreasoningest renommé par la passerelle dans ce format. - Le raisonnement consomme
max_tokens: avec une limite basse, la réponse se coupe (finish_reason: length) avant même le texte. - Si la réponse ne contient pas de texte mais que le raisonnement est présent, la passerelle le reporte dans
content— sauf pour les réponses avec appel d'outil. reasoning_effortetreasoning.effortsont transmis au réseau. Si le modèle n'a que deux modes, la passerelle y ramène la valeur :noneetminimal→low, les valeurs plus élevées → raisonnement par défaut.- Si un nœud rejette la valeur, la passerelle la rétrograde (
maxetxhigh→high,minimal→low, sinon elle retire le champ) et relance la requête. - Dans
/v1/messages, le raisonnement n'est pas transmis — pas de blocsthinking.
Plugins#
Les plugins s'activent via le champ plugins — tableau de chaînes ou d'objets avec options. La liste — GET /v1/plugins.
| Plugin | Description | Conditions |
|---|---|---|
response-healing | Corrige le JSON tronqué dans la réponse du modèle. | Uniquement hors streaming et si la réponse commence par { ou [. |
privacy-sanitization | Masque dans les messages texte les emails, IPv4, numéros de carte, JWT, clés hex de 64 caractères et clés du type sk-…, gw_…, gm-…, Bearer …. | Mode — champ privacy_mode : redact (par défaut) ou tokenize. |
file-parser | Extrait le texte d'un PDF. | Si le texte du message est intégralement un PDF en base64 : data:application/pdf;base64,… ou sans préfixe. |
web | Recherche web : les résultats sont intégrés à la requête, la réponse reçoit des liens vers les sources. | Avec privacy-sanitization — erreur 400. |
Recherche web#
- Options :
max_results— de 1 à 10, par défaut 5 ;engine— indication du moteur ;search_prompt— texte personnalisé avant les résultats ;enabled: false— désactiver la recherche. - Sources — dans
message.annotations[].url_citation; en streaming — via le chunkjoingonka-citationsavant la fin. mode: "agent"— le modèle décide lui-même s'il faut chercher et quoi ;max_searches— de 1 à 5, par défaut 3.- Facturation : en mode normal — uniquement les tokens (les résultats de recherche sont inclus dans les tokens d'entrée) ; en mode agent — les tokens de toutes les étapes plus 1000 nGNK par recherche effectuée (
x_joingonka.web_search_surcharge_ngonka). - Dans Anthropic Messages et OpenAI Responses, l'outil intégré
web_searchexécute ce même plugin en mode agent.
{
"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}]
}Coût et champs de service#
Une réponse non-streaming indique le coût de la requête dans usage :
| Champ | Description |
|---|---|
usage.cost_gnk | Coût de la requête en GNK |
usage.platform_fee_gnk | Dont marge de la plateforme, GNK |
usage.total_cost_gnk | Total à débiter en GNK |
usage.total_cost_usd | Total en dollars au taux actuel du GNK |
- En streaming,
usagene contient que les tokens ; le coût se trouve dans le chunkjoingonka-meta. - Avec l'en-tête
x-joingonka-meta: 1, la réponsePOST /v1/chat/completionsinclut un blocx_joingonka: coût (cost_ngonka), solde après débit (balance_ngonka, uniquement hors streaming) et timings (ttft_ms). Les autres protocoles ne renvoient pas ce bloc. x-request-id— identifiant de la requête : joignez-le à toute demande au support.Retry-Afteraccompagne un429: nombre de secondes à attendre avant de réessayer.- Les en-têtes
X-TitleetHTTP-Referer(comme chez OpenRouter) aident la passerelle à identifier votre application ; leur contenu n'est pas conservé.
Limites#
- Images : les parties
image_urlsont remplacées par un texte de substitution — le modèle ne voit pas l'image (vision: falsedans les capacités). - Depuis un navigateur, l'API n'est accessible que depuis les domaines JoinGonka (vérification
Origin) : appelez-la depuis votre serveur, ne placez jamais la clé dans le frontend. - Embeddings :
POST /v1/embeddingsrenvoie501— aucun modèle d'embedding n'est disponible sur le réseau. - Codes d'erreur, limites et timeouts — dans la section Erreurs et limites.