> AI エージェント向け：セットアップの手順ガイド — [`/docs/agents.md`](https://gate.joingonka.ai/docs/agents.md)、ドキュメントのインデックス — [`/llms.txt`](https://gate.joingonka.ai/llms.txt)。

# APIリファレンス

ゲートウェイへのリクエストに関するすべて：プロトコル、アドレス、キー、パラメータ。以下ではストリーミング、ツール呼び出し、推論、プラグイン、そしてレスポンスに含まれるリクエストのコストを解説します。

## プロトコルとアドレス

ゲートウェイはOpenAIとAnthropicのフォーマットを受け付けます。OpenAI SDKのベースURLは`https://gate.joingonka.ai/v1`、Anthropic SDKは`https://gate.joingonka.ai`です。すべてのプロトコルは1つのキーと1つの残高で動作し、どのフォーマットのリクエストも同じ経路を通ります。

| メソッドとパス | フォーマット | 用途 | 特徴 |
| --- | --- | --- | --- |
| `POST /v1/chat/completions` | OpenAI Chat Completions | チャット、エージェント、ツール呼び出し | メイン経路：他のフォーマットはゲートウェイがこれに変換します。 |
| `POST /v1/messages` | Anthropic Messages | Claude CodeとAnthropic SDK | ベースURLに`/v1`は不要。モデル`claude-*`は推奨モデルに置き換えられます。`max_tokens`フィールドは必須です。 |
| `POST /v1/responses` | OpenAI Responses | Codex CLIと新しいOpenAI SDK | ステートレス：毎回のリクエストで履歴をすべて送ってください。 |
| `POST /v1/completions` | OpenAI Completions (legacy) | エディタでの自動補完とコード修正 | `suffix`はプロンプト内のヒントとしてモデルに渡されます。レスポンスには`logprobs: null`が含まれます。 |
| `POST /v1/embeddings` | OpenAI Embeddings | テキストのベクトル表現 | レスポンスは`501`：ネットワークに埋め込みモデルがありません。 |

### リファレンスアドレス

キーなしで応答します。コンテキストとステータスを含むモデル表は[モデル](https://gate.joingonka.ai/ja/docs/models)セクションにあります。

| メソッドとパス | 説明 |
| --- | --- |
| `GET /v1/models` | モデル一覧：コンテキスト、価格、対応パラメータ — フィールドはOpenRouter形式です。 |
| `GET /v1/models/{model}` | 1つのモデルのカード。idのスラッシュはそのままか`%2F`。非表示または不明なモデルは`404 model_not_found`。 |
| `GET /v1/capabilities` | ゲートウェイの機能：パラメータ、プロトコル、プラグイン、コストフィールド、リミット（`limits`）。 |
| `GET /v1/plugins` | プラグイン：idと名前。 |
| `GET /v1/network-status` | ネットワークモデルの状態：可用性、レイテンシ、アップタイム。 |
| `GET /v1/nodes` | ノードプールの概要：合計、アクティブ、隔離中。 |
| `GET /v1/web-search/engines` | ウェブ検索が有効かどうか、およびそのエンジンの状態。 |

### Anthropic Messages

- ベースURL — `https://gate.joingonka.ai`：SDKが自動で`/v1/messages`を追加します。
- キーは`x-api-key`ヘッダー（Anthropic SDKが送信する形式）または`Authorization: Bearer`で渡します。
- モデル`claude-*`はゲートウェイが推奨モデル（`MiniMaxAI/MiniMax-M2.7`）に置き換えます。レスポンスの`model`フィールドにはクライアントが送った名前がそのまま残ります。
- `max_tokens`はAnthropic APIと同様に必須です。モデルの上限を超える場合は切り詰められます。
- ストリームはAnthropicのイベント形式。ポーズ中にゲートウェイは`event: ping`を送り、障害は`event: error`イベントで通知されます。
- モデルの推論はレスポンスに含まれません：`thinking`ブロックはありません。
- 組み込みツール`web_search`はゲートウェイのウェブ検索プラグインが実行します — [プラグイン](https://gate.joingonka.ai/ja/docs/api#plugins)セクションを参照。
- トークン数カウント（`/v1/messages/count_tokens`）はありません — レスポンスは`404`。

Claude Codeはインストーラーで設定するのが簡単です — [ツールの接続](https://gate.joingonka.ai/ja/docs#connect)。手動の場合は環境変数で。`ANTHROPIC_MODEL`でネットワークのモデルを固定できます。

#### Claude Code

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

#### cURL

```bash
curl 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

- ゲートウェイはレスポンスを保存しません：`input`に履歴をすべて送ってください。`previous_response_id`と`conversation`フィールドはコード付きの`400`エラーになります。
- `store`は受け付けられますが何も変わりません。
- ツール：`function`と`web_search` — 後者はウェブ検索プラグインが実行します。その他の組み込みツールはゲートウェイがスキップし、リクエストはそれらなしで実行されます。`tool_choice`でそのようなツールを要求すると`400`エラーになります。
- `input_image`と`input_file`パートは`400`エラー：ネットワークのモデルはテキストのみ扱います。
- ステート関連のルート（`GET /v1/responses/{id}`, `DELETE /v1/responses/{id}`, `GET /v1/responses/{id}/input_items`, `POST /v1/responses/{id}/cancel`, `POST /v1/responses/compact`）はコード付きの`404`を返します — ゲートウェイはレスポンスを保存しません。
- Codex CLI：`model_provider`に独自のプロバイダーidを設定してください（openai以外）。そうすればCodexが`/v1/responses/compact`なしで履歴を自ら圧縮します。

### Legacy Completions

- `prompt`は文字列または1つの文字列の配列。レスポンスは`choices[].text`に含まれます。複数のプロンプトやテキストの代わりのトークンは`400`エラーになります。
- `suffix`はプロンプト内のヒントとしてモデルに渡されます：ネットワークには本当のmid-fill機能はありません。
- レスポンスには`logprobs: null`が含まれます。`best_of`は無視されます。`echo`は動作します。

## キーと認証

キーは`Authorization: Bearer jg-…`または`x-api-key: jg-…`ヘッダーで渡します — すべてのアドレスで同じです。キーは[gate.joingonka.ai/keys](https://gate.joingonka.ai/keys)ページで登録後に作成します。

| プレフィックス | キー | モデルへのリクエスト |
| --- | --- | --- |
| `jg-` | 通常のアカウントキー | はい |
| `gc-` | 子キー：独自のリミット、消費はオーナーの残高から | はい |
| `gm-` | 管理キー：子キーの管理のみ | いいえ — `403 forbidden` |

- マイページで各キーに日次・月次・累計の支出リミットを設定できます。超過時は`402 child_key_limit_exceeded`。
- キーごとの1分あたりのリクエスト数には上限があります — 値は[レート制限](https://gate.joingonka.ai/ja/docs/errors#limits)セクションにあります。
- キーなしで動作するのはサイト上のデモチャットのみです：自分のコードからキーなしでリクエストすると`is_demo`付きの`402`が返ります。
- キーの管理はマイページでのみ可能です：APIキーを使った`/api/keys`はアクセスできません。残高とキーごとの消費は[アカウントAPI](https://gate.joingonka.ai/ja/docs/billing#account-api)で確認できます。

> キーはシークレットです。リポジトリやフロントエンドのコードに保存せず、環境変数を通じて渡してください。

## 例

同じリクエストを4つのSDKで。モデルは推奨の`MiniMaxAI/MiniMax-M2.7`、キーは環境変数`JOINGONKA_API_KEY`から取得します。

### Python

```python
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)
```

### TypeScript

```typescript
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

```bash
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?"}]
  }'
```

### Anthropic SDK

```python
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)
```

### ストリーミング応答

#### Python

```python
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)
```

#### TypeScript

```typescript
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

```bash
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
  }'
```

#### Anthropic SDK

```python
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)
```

## リクエストパラメータ

ゲートウェイが自ら保証する`POST /v1/chat/completions`のパラメータ — 機能レスポンスの`supported_parameters`リスト:

| パラメータ | 説明 |
| --- | --- |
| `temperature` | 応答のランダム性。高いほど多様になります。 |
| `top_p` | 累積確率によるトークンの選別。 |
| `top_k` | 上位k個の最も確率の高いトークンからの選別。 |
| `min_p` | 最も確率の高いトークンに対する低確率トークンのカットオフ。 |
| `frequency_penalty` | 頻繁な繰り返しへのペナルティ。 |
| `presence_penalty` | 既出トークンへのペナルティ。 |
| `repetition_penalty` | 繰り返しを抑える乗数。 |
| `stop` | 生成を停止する文字列。 |
| `seed` | 再現性のためのシード。 |
| `max_tokens` | 応答トークンの上限。モデルの上限を超える場合は上限まで切り詰められます。 |
| `max_completion_tokens` | `max_tokens`の別名。ゲートウェイは値をこちらに移します。 |
| `tools` | モデルが呼び出せる関数。OpenAI形式。 |
| `tool_choice` | 関数を呼び出すかどうか: モデル任せ、呼ばない、必ず呼ぶ、特定の関数を指定。 |
| `response_format` | 構造化応答: `json_object`または`json_schema`。 |

- `temperature`がない場合、ゲートウェイは`0.7`を適用します。
- `max_tokens`がない場合、ゲートウェイはモデルのデフォルトを適用します。非ストリームでは短め、ストリームではモデルの上限。モデルごとの数値は[レート制限](https://gate.joingonka.ai/ja/docs/errors#limits)を参照。

### そのままネットワークに転送

`reasoning_effort`, `reasoning`, `enable_thinking`, `chat_template_kwargs`, `thinking_token_budget`, `min_tokens`, `logit_bias`, `n`, `parallel_tool_calls`, `extra_body`。ゲートウェイは検証しません。ネットワークのリスト外の値は`400`エラー（タイプ`api_error`）になります。

### ネットワークに転送されない

その他のフィールドはゲートウェイが受け取りますが、ネットワークには転送しません — 例えば`user`, `metadata`, `store`, `logprobs`, `top_logprobs`, `thinking`, `stream_options`, `web_search_options`。ストリームでの`usage`は常に届きます。

## ストリーミング

- `stream: true` — SSEイベントとしての応答。最後のイベントは`data: [DONE]`。
- 完了前に`usage`を含むチャンクが届きます — `stream_options`がなくても常に。
- ポーズ中、ゲートウェイは15秒ごとにコメント`: keep-alive`を送信します — SSEクライアントはこれをスキップします。
- ストリームが開く前は、拒否は通常のレスポンスコードで返ります。開いた後は`joingonka-error`チャンクで返ります。
- `delta.tool_calls`では1チャンクにつき1回の呼び出し。ネットワークが連結した呼び出しはゲートウェイが分割します。

```text
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]
```

### ゲートウェイの制御チャンク

`id`フィールドで識別できます:

| `id` | いつ、何が含まれるか |
| --- | --- |
| `joingonka-error` | ストリーム開放後の障害: `error`フィールド、その後`[DONE]`なしで切断。 |
| `joingonka-stream-stalled` | ネットワークが許容ポーズ以上に沈黙: ストリームは`finish_reason: stop`で閉じられます。 |
| `joingonka-stream-unfinished` | ネットワークが生成を中断: `finish_reason: length` — 次のリクエストで続けてください。 |
| `joingonka-citations` | `delta.annotations`内のウェブ検索ソース — 完了前に。 |
| `joingonka-meta` | コストとタイミング — `x-joingonka-meta: 1`ヘッダーがある場合のみ。 |

### 他プロトコルでのストリーム

- Anthropic Messages: `message_start`から`message_stop`までのイベント、ポーズ中は`event: ping`、障害は`event: error`。
- OpenAI Responses: イベント`response.*`、障害は`response.failed`。
- Legacy Completions: 障害時は`data: {"error": …}`、その後`[DONE]`。

## ツール呼び出し

- OpenAI形式: `tools`と`tool_choice`。旧形式の`functions`と`function_call`も受け付けます — 応答も同じ形式で返ります。
- ストリームでは1チャンクにつき1回の呼び出し。最初の要素だけを読むクライアントも呼び出しを失いません。
- ネットワークが`400`エラーを返すような履歴をゲートウェイが修正します: `developer`ロールは`system`になり、空または重複する呼び出しIDにはユニークなIDが付与され、`arguments`がオブジェクトの場合はJSON文字列に変換され、欠落した`type`が補完され、名前のない呼び出しは結果と共に削除されます。
- モデルがテキスト内のマークアップで書いた呼び出しは、ゲートウェイが`tool_calls`に移します。ツールなしのリクエストへの応答内の偽の呼び出しは削除します。
- 引数の途中で生成が中断された場合、`tool_calls`ではなく`finish_reason: length`が届きます: 応答の上限を増やしてください。

```json
{
  "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"]
      }
    }
  }]
}
```

### JSON-Schemaの制約

ツールスキーマと`response_format`はネットワークが文法にコンパイルします。正規表現はRE2エンジンです。ゲートウェイはスキーマをネットワークが受け入れる形式に整えます:

- `$ref`はその場で展開され、`$defs`と`definitions`セクションは削除されます。再帰参照は制約なしのスキーマになります。
- RE2にない構文（先読み・後読み、後方参照、アトミックグループ、独占的量指定子）を含む`pattern`は削除されます。1000を超える繰り返しは1000に短縮されます。
- 定数からなる`anyOf`と`oneOf`は`enum`に折りたたまれます。折りたたみ不可能なブランチが16を超える場合、unionは削除されます。

> スキーマは元より緩くなる可能性があります — 呼び出し引数はご自身で検証してください。

## 構造化応答

`response_format`: `{"type": "json_object"}` — 有効なJSONとして応答、`{"type": "json_schema", "json_schema": {"name": …, "schema": …}}` — 上記の制約付きのあなたのスキーマに従って。ストリームなしで切り詰められたJSONは`response-healing`プラグインが修正します。

```json
{
  "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"]
      }
    }
  }
}
```

## 推論

- モデルの推論は応答とは別に届きます: `message.reasoning_content`、ストリームでは`delta.reasoning_content`。`reasoning`フィールドはゲートウェイがこの形式にリネームします。
- 推論は`max_tokens`を消費します。上限が小さいと、テキストの前で応答が途切れます（`finish_reason: length`）。
- 応答テキストがなく推論がある場合、ゲートウェイはそれを`content`に移します — ツール呼び出しを含む応答を除く。
- `reasoning_effort`と`reasoning.effort`はネットワークに転送されます。モデルに2つのモードしかない場合、ゲートウェイは値をそれらに変換します: `none`と`minimal`は`low`へ、それ以上はデフォルトの推論へ。
- ノードが値を拒否した場合、ゲートウェイはそれを下げて（`max`と`xhigh` → `high`、`minimal` → `low`、それ以外はフィールドを削除）、リクエストを再試行します。
- `/v1/messages`では推論は転送されません — `thinking`ブロックはありません。

## プラグイン

プラグインは`plugins`フィールドで有効化します — 文字列の配列またはオプション付きオブジェクト。リストは`GET /v1/plugins`。

| プラグイン | 説明 | 条件 |
| --- | --- | --- |
| `response-healing` | モデル応答内の切り詰められたJSONを修正します。 | ストリームなしで、かつ応答が`{`または`[`で始まる場合のみ。 |
| `privacy-sanitization` | テキストメッセージ内のemail、IPv4、カード番号、JWT、64文字のhexキー、`sk-…`, `gw_…`, `gm-…`, `Bearer …`形式のキーをマスクします。 | モード — `privacy_mode`フィールド: `redact`（デフォルト）または`tokenize`。 |
| `file-parser` | PDFからテキストを抽出します。 | メッセージテキスト全体がbase64のPDFの場合: `data:application/pdf;base64,…`またはプレフィックスなし。 |
| `web` | ウェブ検索: 結果がリクエストに混ぜ込まれ、応答にソースへのリンクが付きます。 | `privacy-sanitization`と併用すると`400`エラー。 |

### ウェブ検索

- オプション: `max_results` — 1から10まで、デフォルト5; `engine` — エンジンのヒント; `search_prompt` — 結果の前のカスタムテキスト; `enabled: false` — 検索をオフ。
- ソース — `message.annotations[].url_citation`内; ストリームでは完了前の`joingonka-citations`チャンク。
- `mode: "agent"` — モデル自身が検索するかどうかと何を検索するかを決めます; `max_searches` — 1から5まで、デフォルト3。
- 課金：通常モードではトークンのみ（検索結果は入力トークンに含まれます）。エージェントモードでは全ステップのトークンに加え、実行された検索ごとに1000 nGNK（`x_joingonka.web_search_surcharge_ngonka`）がかかります。
- Anthropic MessagesとOpenAI Responsesでは、組み込みツール`web_search`が同じプラグインをエージェントモードで実行します。

#### plugins: web

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

#### mode: agent

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

## コストとメタデータフィールド

非ストリーミングのレスポンスは、リクエストのコストを`usage`に含めて返します：

| フィールド | 説明 |
| --- | --- |
| `usage.cost_gnk` | GNK建てのリクエストコスト |
| `usage.platform_fee_gnk` | うちプラットフォーム手数料（GNK） |
| `usage.total_cost_gnk` | 請求合計（GNK） |
| `usage.total_cost_usd` | 現在のGNKレートによるドル換算の合計 |

- ストリーミングでは`usage`にトークンのみが含まれ、コストはチャンク`joingonka-meta`に入ります。
- ヘッダー`x-joingonka-meta: 1`を付けると、レスポンス`POST /v1/chat/completions`にブロック`x_joingonka`が追加されます：コスト（`cost_ngonka`）、請求後の残高（`balance_ngonka`、非ストリーミングのみ）、タイミング（`ttft_ms`）。他のプロトコルはこのブロックを返しません。
- `x-request-id`はリクエストIDです。サポートへの問い合わせの際に添付してください。
- `Retry-After`は`429`とともに返されます。再試行までに待つべき秒数を示します。
- ヘッダー`X-Title`と`HTTP-Referer`（OpenRouterと同様）は、ゲートウェイがお客様のアプリを識別するのに役立ちます。テキストは保存されません。

## 制限

- 画像：`image_url`パートはテキストのプレースホルダーに置き換えられます。モデルは画像を見ることができません（機能の`vision: false`）。
- ブラウザからのAPIアクセスはJoinGonkaのドメインのみ許可されています（`Origin`チェック）。サーバー側から呼び出し、キーをフロントエンドに置かないでください。
- エンベディング：`POST /v1/embeddings`は`501`を返します。ネットワークにエンベディングモデルがありません。
- エラーコード、制限、タイムアウトは[エラーと制限](https://gate.joingonka.ai/ja/docs/errors)セクションをご覧ください。
