Documentation

Quickstart

JoinGonka Gateway supports OpenAI and Anthropic API for accessing Gonka models. Replace base_url in your client — and it works.

Base URL: https://gate.joingonka.ai/v1

Model: MiniMaxAI/MiniMax-M2.7

Authorization: Bearer YOUR_API_KEY

Python (OpenAI SDK)

python
from openai import OpenAI

client = OpenAI(
    base_url="https://gate.joingonka.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.chat.completions.create(
    model="MiniMaxAI/MiniMax-M2.7",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is Gonka?"},
    ],
    temperature=0.7,
    max_tokens=1024,
)

print(response.choices[0].message.content)

TypeScript (OpenAI SDK)

typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://gate.joingonka.ai/v1",
  apiKey: "YOUR_API_KEY",
});

const response = await client.chat.completions.create({
  model: "MiniMaxAI/MiniMax-M2.7",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "What is Gonka?" },
  ],
  temperature: 0.7,
  max_tokens: 1024,
});

console.log(response.choices[0].message.content);

cURL

bash
curl https://gate.joingonka.ai/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MiniMaxAI/MiniMax-M2.7",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "What is Gonka?"}
    ],
    "temperature": 0.7,
    "max_tokens": 1024
  }'

Anthropic API (Claude Code)

JoinGonka Gateway natively supports Anthropic Messages API (/v1/messages). Claude Code, Anthropic SDK, and any tools using the Anthropic format work directly — without a proxy.

Claude Code

The recommended way is the installer: a single command sets up Claude Code, Codex CLI, Cursor, OpenClaw, Cline, opencode, and other agentic tools — a total of 25.

bash
npx @joingonka/setup

Or set it up manually:

bash
export ANTHROPIC_BASE_URL=https://gate.joingonka.ai
export ANTHROPIC_AUTH_TOKEN=YOUR_API_KEY
export ANTHROPIC_MODEL=MiniMaxAI/MiniMax-M2.7
claude

ANTHROPIC_MODEL pins the network model: without it, Claude Code sends its own claude-* identifier, and the gateway substitutes the default model. The actual context window and the model's output limit (model table below) are set by the CLAUDE_CODE_MAX_CONTEXT_TOKENS and CLAUDE_CODE_MAX_OUTPUT_TOKENS variables — the installer sets them automatically.

Python (Anthropic SDK)

python
import anthropic

client = anthropic.Anthropic(
    base_url="https://gate.joingonka.ai",
    api_key="YOUR_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)

cURL (Anthropic format)

bash
curl https://gate.joingonka.ai/v1/messages \
  -H "x-api-key: YOUR_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?"}
    ]
  }'

Streaming (Python)

python
import anthropic

client = anthropic.Anthropic(
    base_url="https://gate.joingonka.ai",
    api_key="YOUR_API_KEY",
)

with client.messages.stream(
    model="MiniMaxAI/MiniMax-M2.7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Explain Gonka"}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

Tool Use (cURL)

bash
curl https://gate.joingonka.ai/v1/messages \
  -H "x-api-key: YOUR_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MiniMaxAI/MiniMax-M2.7",
    "max_tokens": 1024,
    "tools": [{
      "name": "get_weather",
      "description": "Get current weather",
      "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
      }
    }],
    "messages": [{"role": "user", "content": "Weather in Moscow?"}]
  }'

Both formats (OpenAI and Anthropic) use one API key and one balance.

API Endpoints

Inference

POST/v1/chat/completions

Response generation — OpenAI format (streaming supported)

json
{
  "id": "chatcmpl-abc123...",
  "object": "chat.completion",
  "model": "MiniMaxAI/MiniMax-M2.7",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "Hello! How can I help you?",
      "tool_calls": []
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 8,
    "total_tokens": 20
  },
  "x_joingonka": {
    "cost_ngonka": "24",
    "balance_ngonka": "11999976"
  }
}
POST/v1/messages

Response generation — Anthropic format (streaming, tool_use)

json
{
  "id": "msg_abc123...",
  "type": "message",
  "role": "assistant",
  "content": [{"type": "text", "text": "Hello!"}],
  "model": "MiniMaxAI/MiniMax-M2.7",
  "stop_reason": "end_turn",
  "usage": {"input_tokens": 12, "output_tokens": 8}
}
POST/v1/responses

Response generation — OpenAI Responses (streaming, function tools; no conversation history saved)

json
{
  "id": "resp_abc123...",
  "object": "response",
  "status": "completed",
  "model": "MiniMaxAI/MiniMax-M2.7",
  "output": [{
    "type": "message",
    "role": "assistant",
    "content": [{"type": "output_text", "text": "Hello!", "annotations": []}]
  }],
  "output_text": "Hello!",
  "store": false,
  "usage": {"input_tokens": 12, "output_tokens": 8, "total_tokens": 20}
}
POST/v1/completions

Text continuation — legacy OpenAI Completions (streaming). Raw prompt as input, choices[].text as output; this is how autocomplete and inline-editing work in editors

json
{
  "id": "cmpl-abc123...",
  "object": "text_completion",
  "model": "MiniMaxAI/MiniMax-M2.7",
  "choices": [{
    "index": 0,
    "text": " 42;",
    "logprobs": null,
    "finish_reason": "stop"
  }],
  "usage": {"prompt_tokens": 12, "completion_tokens": 3, "total_tokens": 15}
}
GET/v1/models

List of available models

json
{
  "object": "list",
  "data": [{
    "id": "MiniMaxAI/MiniMax-M2.7",
    "object": "model",
    "owned_by": "gonka-network",
    "context_length": 200000,
    "pricing": {
      "prompt": "0.00000007",
      "completion": "0.0000001"
    },
    "architecture": {
      "modality": "text->text"
    },
    "top_provider": {
      "context_length": 200000,
      "max_completion_tokens": 8192,
      "is_moderated": false
    },
    "supported_parameters": [
      "temperature", "top_p", "tools",
      "tool_choice", "max_tokens", "stop"
    ],
    "x_gonka": {
      "v_ram": 320,
      "context_window": 200000,
      "max_output": 8192,
      "actual_cost_ngonka": 1.2
    }
  }]
}
GET/v1/models/{model}

Single model card — same record as in the list; ID with slash is accepted both as %2F and raw

json
// GET /v1/models/MiniMaxAI%2FMiniMax-M2.7
// (слэш в id можно слать и сырым: /v1/models/MiniMaxAI/MiniMax-M2.7)
{
  "id": "MiniMaxAI/MiniMax-M2.7",
  "object": "model",
  "owned_by": "gonka-network",
  "context_length": 200000,
  "top_provider": {
    "context_length": 200000,
    "max_completion_tokens": 8192,
    "is_moderated": false
  }
}

Plugins

Plugins extend API capabilities. Pass an array of plugins in the request to activate.

GET/v1/plugins

List of available plugins

json
{
  "plugins": [
    {"id": "web", "description": "Web search — inject fresh results with citations"},
    {"id": "response-healing", "description": "Auto-fix truncated JSON"},
    {"id": "privacy-sanitization", "description": "Mask sensitive data"},
    {"id": "file-parser", "description": "Extract text from PDF"}
  ]
}

Usage in request

json
{
  "model": "MiniMaxAI/MiniMax-M2.7",
  "messages": [{"role": "user", "content": "..."}],
  "plugins": ["response-healing", "privacy-sanitization"]
}

web

Web search directly in Gonka models. The models themselves do not have search — the gateway injects fresh results from the internet into the context and returns citation sources. Works in stream and non-stream. Own backend (self-hosted): requests do not go to third-party search APIs under your account.

Method 1 — web object in the plugins array (result injection with options):

json
{
  "model": "MiniMaxAI/MiniMax-M2.7",
  "messages": [{"role": "user", "content": "What's new in the Gonka network?"}],
  "plugins": [{
    "id": "web",
    "max_results": 5,
    "search_prompt": "Relevant web search results:"
  }]
}

Method 2 — Agent mode (mode: "agent"): the model itself calls web_search only when search is needed:

json
{
  "model": "MiniMaxAI/MiniMax-M2.7",
  "messages": [{"role": "user", "content": "What's new in the Gonka network?"}],
  "plugins": [{ "id": "web", "mode": "agent", "max_searches": 3 }]
}

Options: max_results — number of results (default 5, max 10); search_prompt — your own grounding prompt preceding the results.

The response is enriched with annotations[].url_citation (url, title) — OpenRouter standard:

json
{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "...",
      "annotations": [{
        "type": "url_citation",
        "url_citation": {
          "url": "https://gonka.ai/...",
          "title": "Gonka Network"
        }
      }]
    }
  }]
}

Pricing: plugins mode:[{ "id": "web" }] — tokens only (appended results are counted as regular prompt-tokens). Agent mode (mode: "agent") — tokens of all loop steps plus a 1000 nGNK surcharge for each web_search call (≈ $0.0002 per 1000 searches at a rate of ~$0.23 per GNK).

Incompatible with privacy-sanitization: a joint request will return 400.

response-healing

Automatic healing of truncated JSON/structured output. Works only for non-streaming requests with JSON content.

privacy-sanitization

Masking sensitive data (API keys, email, IP addresses, JWTs, card numbers) in messages before sending to the model.

Modes: redact (replace with [REDACTED]) or tokenize (replace with [TOKEN_001]). Pass privacy_mode in the body.

file-parser

Extract text from PDF documents. Supports data:application/pdf;base64,... and raw base64.

Management Keys

Hierarchical API keys for SaaS integrations. A management key (gm-) creates child keys (gc-) with limits and TTL.

POST/api/management/keys

Create a management key (prefix gm-). Used only for managing child keys.

POST/api/management/keys/:id/children

Create a child key (prefix gc-) with optional limits. Billing is charged from the management key owner's balance.

json
{
  "name": "Client A",
  "limit_daily_ngonka": "1000000000",
  "limit_monthly_ngonka": "10000000000",
  "expires_at": "2026-04-01T00:00:00Z",
  "rate_limit_rpm": 30
}
GET/api/management/keys/:id/children

List of child keys with usage statistics.

PUT/api/management/keys/:id/children/:childId

Update limits, RPM, or status of a child key.

DELETE/api/management/keys/:id/children/:childId

Deactivate child key (soft delete).

Account

GET/api/balance

Current balance

json
{
  "balance_ngonka": "11999976",
  "balance_usd": 0.008,
  "cost_per_token_ngonka": 1,
  "tokens_remaining": 11999976
}
GET/api/keys

List of API keys

POST/api/keys

Create API key

DELETE/api/keys/:id

Delete API key

Billing

GET/api/usage

Usage statistics

Query: period=day|week|month|quarter&tz=-180

json
{
  "period": "month",
  "usage": [{
    "date": "2026-03-20",
    "requests": 42,
    "tokens": 18500,
    "costNgonka": "22200"
  }]
}
GET/api/usage/by-model

Usage statistics by model: summaries for each model and a 'day (or hour if period=day) × model' series

Query: period=day|week|month|quarter&tz=-180 | from=2026-03-01&to=2026-03-31&tz=-180

json
{
  "period": "week",
  "granularity": "day",
  "from": "2026-03-14",
  "to": "2026-03-20",
  "models": [{
    "model": "MiniMaxAI/MiniMax-M2.7",
    "requests": 42,
    "promptTokens": 15000,
    "completionTokens": 3500,
    "costNgonka": "841500",
    "avgLatencyMs": 4100,
    "avgTtftMs": 820,
    "lastUsed": "2026-03-20T12:00:00Z"
  }],
  "series": [{
    "bucket": "2026-03-20",
    "model": "MiniMaxAI/MiniMax-M2.7",
    "requests": 12,
    "promptTokens": 4000,
    "completionTokens": 900,
    "costNgonka": "221100"
  }]
}
GET/api/deposits

Deposit history

Query: limit=50&offset=0&from=2026-03-01&to=2026-03-21

json
{
  "deposits": [{
    "id": "abc-123",
    "type": "DEPOSIT_GNK",
    "amountNgonka": "10000000",
    "description": "GNK deposit via memo",
    "createdAt": "2026-03-20T12:00:00Z"
  }],
  "total": 3
}
GET/api/transactions

Transaction history. Detailed INFERENCE records older than 90 days are consolidated into a single daily summary (type remains INFERENCE, amounts and fees are preserved exactly)

Query: limit=50&offset=0&type=INFERENCE&from=2026-03-01&to=2026-03-21

json
{
  "transactions": [{
    "id": "def-456",
    "type": "INFERENCE",
    "amountNgonka": "-1200",
    "feeNgonka": "120",
    "description": null,
    "createdAt": "2026-03-20T14:30:00Z"
  }],
  "total": 128
}
GET/api/pricing

Rates and fees (public, without authorization)

json
{
  "deposit_usdt_fee_percent": 5,
  "deposit_gnk_fee_percent": 0,
  "usage_fee_percent": 10,
  "withdrawal_fee_percent": 5,
  "gnk_usd_price": 0.3465
}

Streaming & Errors

With stream: true, the response comes in chunks via SSE (Server-Sent Events).

OpenAI (stream: true)

text
data: {"choices":[{"delta":{"content":"Hello"}}]}

data: {"choices":[{"delta":{"content":"!"}}]}

data: {"choices":[],"x_joingonka":{"cost_ngonka":"24"}}

data: [DONE]

Anthropic (stream: true)

text
event: message_start
data: {"type":"message_start","message":{...}}

event: content_block_delta
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"Hello"}}

event: message_stop
data: {"type":"message_stop"}

// сбой уже в открытом потоке (таймаут ноды и т. п.):
// поток закрывается событием error, message_stop не будет
event: error
data: {"type":"error","error":{"type":"timeout","message":"..."}}

Errors

json
// 400 — неверный запрос
{"error": {"message": "...", "type": "invalid_request_error"}}

// 401 — не авторизован
{"error": {"message": "...", "type": "authentication_error"}}

// 404 — неизвестный маршрут или модель (GET /v1/models/{model})
{"error": {"message": "The model 'x' does not exist", "type": "invalid_request_error", "param": "model", "code": "model_not_found"}}

// 402 — недостаточный баланс
{"error": {"message": "...", "type": "insufficient_funds", "balance_ngonka": "0"}}

// 429 — rate limit
{"error": {"message": "...", "type": "rate_limit_error"}}

// 429 — модель перегружена сетью Gonka (+ заголовок Retry-After)
{"error": {"message": "...", "type": "rate_limit_exceeded", "code": "upstream_rate_limited"}}

// 503 — свободных нод под модель не осталось
{"error": {"message": "...", "type": "service_unavailable"}}

// 504 — сеть приняла запрос, но не ответила вовремя
{"error": {"message": "...", "type": "timeout", "code": "upstream_timeout"}}

// 502 — ошибка сети Gonka
{"error": {"message": "...", "type": "api_error"}}

// stream: коды выше приходят обычным HTTP-ответом, пока поток не открыт.
// Если сбой случился уже В потоке — статус остаётся 200, ошибка приезжает
// чанком, и терминатора [DONE] не будет:
data: {"id":"joingonka-error","object":"chat.completion.chunk","choices":[],"error":{"message":"...","type":"timeout"}}

Models

The Gonka network supports multiple models via a single API — the current list can always be retrieved by a GET /v1/models request. To select a model, pass its ID in the model field of the request body.

ModelVendorContextMax outputVRAMStatus
MiniMax M2.7MiniMax195K8K320 GBAvailable
DeepSeek V4 FlashDeepSeek371K32K280 GBAvailable
GLM 5.3 FlashZ.ai381K8K560 GBAvailable

By default (if model is not specified), the network's flagship model is used. The current list with metadata — GET /v1/models.

The current list of models with all metadata - GET /v1/models. Vision and multimodal input (image_url) are not yet supported by the upstream Gonka network.

Rates and fees

Full transparency: all gateway fees are below. Current values are loaded live from the API — the public endpoint GET /api/pricing is available without authorization.

OperationFeeNote
Inference markup10%Platform markup above the Gonka network price — the gateway's main source of revenue. Charged per request alongside the token cost.
Deposit via USDT5%Charged by the payment provider when paying with crypto (USDT).
Deposit via GNKfreeDirect on-chain GNK transfer is credited without gateway fees.
Withdrawal5%Charged when withdrawing GNK to an external address. Withdrawal is processed manually within 24–48 hours.
Current GNK price$0.231The GNK/USD rate used to calculate deposits and balance. Updated automatically.

GET /api/pricing

Limits

Models: All Gonka network models (DevShards multi-model architecture)

Request limit: with API key, the number of requests is not strictly limited (limited by network concurrency); without a key — 20/day per IP (anti-spam)

Max tokens: up to 32,768 tokens per request for DeepSeek V4 Flash and up to 8,192 for other models (values exceeding the limit are clipped by the gateway). For long responses, use stream:true to avoid timeouts.

Reasoning models: GLM 5.3 Flash reasons before responding (default is full reasoning), and reasoning consumes the max_tokens budget — several hundred tokens even for a simple question. Set max_tokens to at least 600 or do not specify it in stream:true mode (then the model's ceiling applies) — otherwise the entire budget will be used for reasoning and the response will cut off with finish_reason=length before reaching the text. The model's switch is binary: reasoning_effort: "low" disables reasoning (the response is significantly shorter and faster), any other value leaves it full — the gateway maps none and minimal to low, while medium, high, xhigh, and max are ignored as redundant. The fields enable_thinking, chat_template_kwargs, reasoning.enabled, and thinking.type are ignored by the network. The reasoning text comes in a separate field reasoning_content (in a stream — delta.reasoning_content), while content contains only the answer.

Streaming: supported (SSE, stream: true)

Network timeout: Waiting for the first token from the network — up to 150 seconds; the gateway always accesses the node in stream mode, so the limit is the same for stream:true and standard requests. If the network has accepted the request but has not started responding within this time, the request terminates with an upstream_timeout error (504 if the stream is not yet open; a chunk with an error field with status 200 if the stream is already open), and the prompt processing is deducted based on the estimate: a request accepted by the network cannot be cancelled; the node processes it in any case. Completion is not billed on timeout. Started generation is limited to approximately 5 minutes (300 seconds) by the network broker: upon expiration, the stream closes, and the gateway sends a chunk with finish_reason=length — the response can be continued in the next request by passing the already received part in the context. A pause longer than 30 seconds between chunks also terminates the stream. The longer the prompt, the longer the wait for the first token — very large contexts (hundreds of thousands of tokens) are more likely to exceed the limit than short ones.