Para agentes de IA: guia passo a passo de configuração — /docs/agents.md, índice da documentação — /llms.txt.
Referência da API
Tudo sobre requisições ao gateway: protocolos, endereços, chaves e parâmetros. Abaixo — streaming, chamada de ferramentas, raciocínio, plugins e o custo da requisição na resposta.
Protocolos e endereços#
O gateway aceita os formatos da OpenAI e da Anthropic. A URL base para o SDK da OpenAI é https://gate.joingonka.ai/v1 e para o SDK da Anthropic, https://gate.joingonka.ai. Todos os protocolos funcionam com a mesma chave e o mesmo saldo: uma requisição em qualquer formato percorre o mesmo caminho.
| Método e caminho | Formato | Para que serve | Particularidades |
|---|---|---|---|
POST /v1/chat/completions | OpenAI Chat Completions | Chat, agentes, chamada de ferramentas | É o caminho principal: o gateway converte os demais formatos para ele. |
POST /v1/messages | Anthropic Messages | Claude Code e SDK da Anthropic | URL base sem /v1; os modelos claude-* são substituídos pelo recomendado; o campo max_tokens é obrigatório. |
POST /v1/responses | OpenAI Responses | Codex CLI e os novos SDKs da OpenAI | Sem estado: envie o histórico completo em cada requisição. |
POST /v1/completions | OpenAI Completions (legacy) | Autocompletar e edição de código em editores | suffix é passado ao modelo como dica; na resposta, logprobs: null. |
POST /v1/embeddings | OpenAI Embeddings | Representações vetoriais de texto | Resposta 501: a rede não tem modelos de embeddings. |
Endereços de referência#
Respondem sem chave. A tabela de modelos com contexto e status está na seção Modelos.
| Método e caminho | Descrição |
|---|---|
GET /v1/models | Lista de modelos: contexto, preços, parâmetros aceitos; campos no formato OpenRouter. |
GET /v1/models/{model} | Ficha de um modelo; a barra no id, como está ou %2F. Modelo oculto ou desconhecido: 404 model_not_found. |
GET /v1/capabilities | Recursos do gateway: parâmetros, protocolos, plugins, campos de custo e limites (limits). |
GET /v1/plugins | Plugins: id e nome. |
GET /v1/network-status | Estado dos modelos da rede: disponibilidade, latências, uptime. |
GET /v1/nodes | Resumo do pool de nós: quantos no total, ativos e em quarentena. |
GET /v1/web-search/engines | Se a busca na web está ativada e em que estado estão seus motores. |
Anthropic Messages#
- URL base:
https://gate.joingonka.ai. O SDK adiciona/v1/messagessozinho. - A chave vai no cabeçalho
x-api-key(é assim que o SDK da Anthropic envia) ouAuthorization: Bearer. - O gateway substitui os modelos
claude-*pelo recomendado (MiniMaxAI/MiniMax-M2.7); no campomodelda resposta permanece o nome enviado pelo cliente. max_tokensé obrigatório, como na API da Anthropic; se ultrapassar o teto do modelo, é cortado.- O stream são eventos da Anthropic; nas pausas o gateway envia
event: pinge uma falha chega como eventoevent: error. - O raciocínio do modelo não aparece na resposta: não há blocos
thinking. - A ferramenta integrada
web_searché executada pelo plugin de busca na web do gateway; consulte a seção Plugins. - Não há contagem de tokens (
/v1/messages/count_tokens): resposta404.
O Claude Code é configurado mais facilmente com o instalador: conexão de ferramentas. Manualmente, use variáveis de ambiente; ANTHROPIC_MODEL fixa o modelo da rede.
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#
- O gateway não armazena respostas: envie todo o histórico em
input. Os camposprevious_response_ideconversationgeram um erro400com código. storeé aceito e não muda nada.- Ferramentas:
functioneweb_search, executada pelo plugin de busca na web. O gateway ignora as outras ferramentas integradas e a requisição é executada sem elas; exigir uma dessas ferramentas viatool_choicegera um erro400. - As partes
input_imageeinput_filegeram um erro400: os modelos da rede trabalham com texto. - Os endereços de estado (
GET /v1/responses/{id},DELETE /v1/responses/{id},GET /v1/responses/{id}/input_items,POST /v1/responses/{id}/cancel,POST /v1/responses/compact) respondem404com código: o gateway não armazena respostas. - Codex CLI: defina seu próprio id de provedor em
model_provider(diferente de openai); assim o Codex compacta o histórico sozinho, sem/v1/responses/compact.
Legacy Completions#
prompté uma string ou um array de uma única string; a resposta vai emchoices[].text. Vários prompts ou tokens no lugar de texto geram um erro400.suffixé passado ao modelo como dica no prompt: a rede não faz um preenchimento real do meio.- Na resposta,
logprobs: null;best_ofé ignorado;echofunciona.
Chaves e autorização#
A chave é enviada no cabeçalho Authorization: Bearer jg-… ou x-api-key: jg-…, em todos os endereços. A chave é criada após o cadastro na página gate.joingonka.ai/keys.
| Prefixo | Chave | Requisições aos modelos |
|---|---|---|
jg- | Chave normal da conta | sim |
gc- | Chave filha: limites próprios, o gasto sai do saldo do proprietário | sim |
gm- | Chave de gerenciamento: só gerencia as chaves filhas | não: 403 forbidden |
- No painel, você pode definir para cada chave um limite de gastos diário, mensal e total; se ultrapassar,
402 child_key_limit_exceeded. - O número de requisições por minuto por chave é limitado; os valores estão na seção Limites.
- Sem chave, só funciona o chat de demonstração do site: uma requisição sem chave feita do seu próprio código receberá
402comis_demo. - As chaves são gerenciadas apenas no painel:
/api/keysnão está disponível com uma chave de API. O saldo e o gasto por chave estão em API da conta.
A chave é um segredo: não a guarde no repositório nem no código do frontend, passe-a por variáveis de ambiente.
Exemplos#
A mesma requisição em quatro SDKs. O modelo é o recomendado (MiniMaxAI/MiniMax-M2.7), a chave vem da variável de 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)Resposta em 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)Parâmetros da requisição#
Parâmetros de POST /v1/chat/completions que o gateway garante por conta própria: a lista supported_parameters na resposta de capacidades:
| Parâmetro | Descrição |
|---|---|
temperature | Aleatoriedade da resposta: quanto maior, mais variada. |
top_p | Seleção de tokens por probabilidade acumulada. |
top_k | Seleção entre os k tokens mais prováveis. |
min_p | Corte de tokens improváveis em relação ao mais provável. |
frequency_penalty | Penalidade por repetições frequentes. |
presence_penalty | Penalidade por tokens que já apareceram. |
repetition_penalty | Multiplicador contra repetições. |
stop | Strings em que a geração é interrompida. |
seed | Semente para reprodutibilidade. |
max_tokens | Limite de tokens da resposta; acima do teto do modelo, é cortado até o teto. |
max_completion_tokens | Outro nome de max_tokens: o gateway transfere o valor para ele. |
tools | Funções que o modelo pode chamar, no formato OpenAI. |
tool_choice | Se deve chamar uma função: à escolha do modelo, nunca, obrigatório ou uma específica. |
response_format | Resposta estruturada: json_object ou json_schema. |
- Sem
temperature, o gateway aplica0.7. - Sem
max_tokens, o gateway aplica o padrão do modelo: sem streaming, mais curto; no streaming, o teto do modelo. Os números por modelo estão na seção Limites.
São repassados à rede como estão#
reasoning_effort, reasoning, enable_thinking, chat_template_kwargs, thinking_token_budget, min_tokens, logit_bias, n, parallel_tool_calls, extra_body. O gateway não os valida: um valor fora da lista da rede gera um erro 400 com tipo api_error.
Não são repassados à rede#
Os demais campos o gateway aceita e não repassa à rede, por exemplo user, metadata, store, logprobs, top_logprobs, thinking, stream_options, web_search_options. O usage no streaming chega sempre.
Streaming#
stream: true: resposta por eventos SSE; o último evento édata: [DONE].- Antes do encerramento chega um chunk com
usage, sempre, mesmo semstream_options. - Nas pausas o gateway envia a cada 15 s um comentário
: keep-alive; os clientes SSE o ignoram. - Enquanto o stream não está aberto, a recusa chega com um código de resposta comum; depois de aberto, chega como chunk
joingonka-error. - Em
delta.tool_callshá uma chamada por chunk: as chamadas que a rede junta o gateway 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]Chunks internos do gateway#
Dá para reconhecê-los pelo campo id:
id | Quando e o que inclui |
|---|---|
joingonka-error | Falha após abrir o stream: campo error e depois corte sem [DONE]. |
joingonka-stream-stalled | A rede ficou em silêncio além da pausa permitida: o stream é fechado com finish_reason: stop. |
joingonka-stream-unfinished | A rede interrompeu a geração: finish_reason: length; continue com a próxima requisição. |
joingonka-citations | Fontes da busca na web em delta.annotations, antes do encerramento. |
joingonka-meta | Custo e tempos somente com o cabeçalho x-joingonka-meta: 1. |
Streaming em outros protocolos#
- Anthropic Messages: eventos de
message_startatémessage_stop, comevent: pingnas pausas eevent: errorem caso de falha. - OpenAI Responses: eventos
response.*, falharesponse.failed. - Legacy Completions: em caso de falha,
data: {"error": …}e depois[DONE].
Chamada de ferramentas#
- Formato OpenAI:
toolsetool_choice. O formato antigofunctionsefunction_calltambém é aceito, e a resposta vem nele mesmo. - No streaming, uma chamada por chunk: clientes que leem apenas o primeiro elemento não perdem chamadas.
- O histórico com o qual a rede retornaria um erro
400o gateway corrige: o papeldevelopervirasystem, ids de chamada vazios e repetidos recebem valores únicos,argumentscomo objeto vira string JSON, otypeausente é preenchido, e uma chamada sem nome é removida junto com o resultado. - A chamada que o modelo escreveu como marcação no texto o gateway move para
tool_calls; chamadas falsas na resposta a uma requisição sem ferramentas ele remove. - A geração foi interrompida no meio dos argumentos: virá
finish_reason: length, e nãotool_calls; aumente o limite da resposta.
{
"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"]
}
}
}]
}Restrições de JSON-Schema#
Os esquemas das ferramentas e response_format a rede compila em uma gramática; as expressões regulares usam o motor RE2. O gateway ajusta o esquema à forma que a rede aceita:
- Os
$refsão expandidos no lugar, as seções$defsedefinitionssão removidas; uma referência recursiva vira um esquema sem restrições. - O
patterncom construções que não existem no RE2 (lookahead e lookbehind, referências anteriores, grupos atômicos, quantificadores possessivos) é removido; repetições maiores que 1000 são reduzidas a 1000. anyOfeoneOfde constantes são colapsados emenum; se houver mais de 16 ramos não colapsáveis, a união é removida.
O esquema pode ficar mais permissivo que o original: valide os argumentos da chamada do seu lado.
Resposta estruturada#
response_format: {"type": "json_object"} para uma resposta JSON válida, {"type": "json_schema", "json_schema": {"name": …, "schema": …}} conforme o seu esquema com as restrições acima. O JSON truncado sem streaming é corrigido pelo 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"]
}
}
}
}Raciocínio#
- O raciocínio do modelo chega separado da resposta:
message.reasoning_content, e no streamingdelta.reasoning_content. O camporeasoningo gateway renomeia para esse formato. - O raciocínio consome
max_tokens: com um limite pequeno a resposta é cortada (finish_reason: length) antes mesmo do texto. - Se não há texto de resposta mas há raciocínio, o gateway o move para
content, exceto em respostas com chamada de ferramenta. reasoning_effortereasoning.effortsão repassados à rede. Se o modelo tem apenas dois modos, o gateway ajusta o valor a eles:noneeminimalparalow, os mais altos para o raciocínio padrão.- Se o nó rejeitar o valor, o gateway o rebaixa (
maxexhigh→high,minimal→low, ou então remove o campo) e repete a requisição. - Em
/v1/messageso raciocínio não é repassado: não há blocosthinking.
Plugins#
Os plugins são ativados pelo campo plugins: um array de strings ou de objetos com opções. A lista está em GET /v1/plugins.
| Plugin | Descrição | Condições |
|---|---|---|
response-healing | Corrige o JSON truncado na resposta do modelo. | Somente sem streaming e se a resposta começar com { ou [. |
privacy-sanitization | Mascara em mensagens de texto emails, IPv4, números de cartão, JWT, chaves hex de 64 caracteres e chaves no formato sk-…, gw_…, gm-…, Bearer …. | O modo é o campo privacy_mode: redact (padrão) ou tokenize. |
file-parser | Extrai o texto de um PDF. | Se o texto da mensagem for inteiramente um PDF em base64: data:application/pdf;base64,… ou sem prefixo. |
web | Busca na web: os resultados são incorporados à requisição e a resposta recebe links para as fontes. | Junto com privacy-sanitization, erro 400. |
Busca na web#
- Opções:
max_results, de 1 a 10, padrão 5;engine, dica de mecanismo;search_prompt, texto próprio antes dos resultados;enabled: false, desativar a busca. - As fontes estão em
message.annotations[].url_citation; no streaming, no chunkjoingonka-citationsantes do encerramento. mode: "agent": o modelo decide por conta própria se deve buscar e o quê;max_searches, de 1 a 5, padrão 3.- Pagamento: no modo normal, apenas tokens (os resultados de busca entram nos tokens de entrada); no modo agente, os tokens de todas as etapas mais 1000 nGNK por cada busca realizada (
x_joingonka.web_search_surcharge_ngonka). - No Anthropic Messages e no OpenAI Responses, a ferramenta integrada
web_searchexecuta esse mesmo plugin no modo 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}]
}Custo e campos de serviço#
A resposta sem streaming traz o custo da requisição em usage:
| Campo | Descrição |
|---|---|
usage.cost_gnk | Custo da requisição em GNK |
usage.platform_fee_gnk | Desse valor, a margem da plataforma, GNK |
usage.total_cost_gnk | Total a debitar em GNK |
usage.total_cost_usd | Total em dólares pela cotação atual do GNK |
- No streaming,
usagecontém apenas tokens; o custo está no chunkjoingonka-meta. - Com o cabeçalho
x-joingonka-meta: 1, a respostaPOST /v1/chat/completionsrecebe o blocox_joingonka: custo (cost_ngonka), saldo após o débito (balance_ngonka, somente sem streaming) e timings (ttft_ms). Outros protocolos não retornam esse bloco. x-request-id— identificador da requisição: inclua-o ao falar com o suporte.Retry-Aftervem com429: quantos segundos esperar antes de tentar de novo.- Os cabeçalhos
X-TitleeHTTP-Referer(como no OpenRouter) ajudam o gateway a identificar seu aplicativo; o texto deles não é armazenado.
Limitações#
- Imagens: as partes
image_urlsão substituídas por um marcador de texto — o modelo não vê a imagem (vision: falsenas capacidades). - Do navegador, a API só é acessível a partir de domínios da JoinGonka (verificação
Origin): chame-a do seu próprio servidor e não coloque a chave no frontend. - Embeddings:
POST /v1/embeddingsresponde501— não há modelos de embeddings na rede. - Códigos de erro, limites e timeouts estão na seção Erros e limites.