> สำหรับเอเจนต์ AI: คำแนะนำการตั้งค่าทีละขั้นตอน — [`/docs/agents.md`](https://gate.joingonka.ai/docs/agents.md), ดัชนีเอกสาร — [`/llms.txt`](https://gate.joingonka.ai/llms.txt).

# เอกสารอ้างอิง API

ทุกเรื่องเกี่ยวกับคำขอที่ส่งไปยังเกตเวย์: โปรโตคอล ที่อยู่ คีย์ และพารามิเตอร์ ด้านล่างนี้ — สตรีมมิ่ง การเรียกใช้เครื่องมือ การให้เหตุผล ปลั๊กอิน และค่าใช้จ่ายของคำขอที่อยู่ใน réponse

## โปรโตคอลและที่อยู่

เกตเวย์รองรับรูปแบบของ OpenAI และ Anthropic Base URL สำหรับ SDK ของ OpenAI คือ `https://gate.joingonka.ai/v1` และสำหรับ SDK ของ Anthropic คือ `https://gate.joingonka.ai` ทุกโปรโตคอลใช้คีย์เดียวกันและยอดคงเหลือเดียวกัน คำขอในรูปแบบใดก็เดินผ่านเส้นทางเดียวกัน

| เมธอดและเส้นทาง | รูปแบบ | ใช้ทำอะไร | จุดสังเกต |
| --- | --- | --- | --- |
| `POST /v1/chat/completions` | OpenAI Chat Completions | แชท เอเจนต์ การเรียกใช้เครื่องมือ | เส้นทางหลัก: รูปแบบอื่น ๆ เกตเวย์จะแปลงมาเป็นเส้นทางนี้ |
| `POST /v1/messages` | Anthropic Messages | Claude Code และ SDK ของ Anthropic | Base URL ไม่มี `/v1`; โมเดล `claude-*` จะถูกแทนที่ด้วยโมเดลที่แนะนำ; ฟิลด์ `max_tokens` จำเป็นต้องใส่ |
| `POST /v1/responses` | OpenAI Responses | Codex CLI และ SDK ใหม่ของ OpenAI | ไม่เก็บสถานะ: ส่งประวัติทั้งหมดมาในทุกคำขอ |
| `POST /v1/completions` | OpenAI Completions (legacy) | การเติมข้อความอัตโนมัติและแก้โค้ดในโปรแกรมแก้ไข | `suffix` ถูกส่งให้โมเดลเป็นคำใบ้; คำตอบมี `logprobs: null` |
| `POST /v1/embeddings` | OpenAI Embeddings | การแทนข้อความในรูปแบบเวกเตอร์ | การตอบกลับ `501`: ยังไม่มีโมเดล embedding ในเครือข่าย |

### ที่อยู่สำหรับอ้างอิง

ตอบกลับได้โดยไม่ต้องใช้คีย์ ตารางโมเดลพร้อมบริบทและสถานะอยู่ในหมวด [โมเดล](https://gate.joingonka.ai/th/docs/models)

| เมธอดและเส้นทาง | คำอธิบาย |
| --- | --- |
| `GET /v1/models` | รายการโมเดล: บริบท ราคา พารามิเตอร์ที่รองรับ — ฟิลด์ในรูปแบบ OpenRouter |
| `GET /v1/models/{model}` | ข้อมูลของโมเดลเดียว; เครื่องหมายสแลชใน 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

- Base URL — `https://gate.joingonka.ai`: SDK จะเติม `/v1/messages` เอง
- คีย์ — ในเฮดเดอร์ `x-api-key` (แบบที่ SDK ของ Anthropic ส่ง) หรือ `Authorization: Bearer`
- โมเดล `claude-*` เกตเวย์จะแทนที่ด้วยโมเดลที่แนะนำ (`MiniMaxAI/MiniMax-M2.7`); ในฟิลด์ `model` ของคำตอบจะยังคงชื่อที่ไคลเอนต์ส่งมา
- `max_tokens` จำเป็นต้องใส่ เหมือนใน API ของ Anthropic; ถ้าเกินเพดานของโมเดลจะถูกตัด
- สตรีม — อีเวนต์ของ Anthropic; ในช่วงหยุด เกตเวย์จะส่ง `event: ping` และข้อผิดพลาดจะมาเป็นอีเวนต์ `event: error`
- การคิดวิเคราะห์ของโมเดลจะไม่ปรากฏในคำตอบ: ไม่มีบล็อก `thinking`
- เครื่องมือในตัว `web_search` ทำงานผ่านปลั๊กอินเว็บค้นหาของเกตเวย์ — ดูหมวด [ปลั๊กอิน](https://gate.joingonka.ai/th/docs/api#plugins)
- ไม่มีการนับโทเค็น (`/v1/messages/count_tokens`) — ตอบกลับ `404`

Claude Code ตั้งค่าผ่านตัวติดตั้งได้ง่ายกว่า — [การเชื่อมต่อเครื่องมือ](https://gate.joingonka.ai/th/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: ตั้งค่า id ผู้ให้บริการของคุณเองใน `model_provider` (ไม่ใช่ openai) — แล้ว Codex จะบีบอัดประวัติเองโดยไม่ต้องใช้ `/v1/responses/compact`

### Legacy Completions

- `prompt` — สตริงหรืออาร์เรย์ที่มีสตริงเดียว; คำตอบอยู่ใน `choices[].text` หลายพรอมท์หรือส่งโทเค็นแทนข้อความ — ข้อผิดพลาด `400`
- `suffix` ถูกส่งให้โมเดลเป็นคำใบ้ในพรอมท์: เครือข่ายยังไม่รองรับการเติมกลางข้อความจริง ๆ
- คำตอบมี `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`
- จำนวนคำขอต่อนาทีต่อคีย์มีลิมิต — ดูค่าต่าง ๆ ในหมวด [ขีดจำกัด](https://gate.joingonka.ai/th/docs/errors#limits)
- หากไม่มีคีย์ ใช้ได้เฉพาะเดโมแชทบนเว็บไซต์: คำขอจากโค้ดของคุณเองโดยไม่มีคีย์จะได้รับ `402` พร้อม `is_demo`
- จัดการคีย์ได้เฉพาะในหน้าบัญชี: `/api/keys` ที่ใช้ API-คีย์เข้าไม่ได้ ยอดคงเหลือและค่าใช้จ่ายตามคีย์ — [API ของบัญชี](https://gate.joingonka.ai/th/docs/billing#account-api)

> คีย์คือความลับ: อย่าเก็บไว้ในรีโปหรือโค้ดฝั่งฟรอนต์เอนด์ ให้ส่งผ่านตัวแปรสภาพแวดล้อม

## ตัวอย่าง

คำขอเดียวกันในสี่ 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` ในผลลัพธ์ capabilities:

| พารามิเตอร์ | คำอธิบาย |
| --- | --- |
| `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/th/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`
- ในช่วงหยุด เกตเวย์จะส่งคอมเมนต์ `: keep-alive` ทุก 15 วินาที — ไคลเอนต์ SSE จะข้ามไป
- ตราบใดที่สตรีมยังไม่เปิด การปฏิเสธจะมาเป็นรหัสตอบกลับปกติ; หลังเปิดแล้ว — เป็นชังก์ `joingonka-error`
- ใน `delta.tool_calls` — หนึ่งการเรียกต่อชังก์: การเรียกที่เครือข่ายรวมกัน เกตเวย์จะแยกออก

```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` ก็รับได้ — คำตอบจะมาในรูปแบบนั้น
- ในสตรีม — หนึ่งการเรียกต่อชังก์: ไคลเอนต์ที่อ่านแค่รายการแรกจะไม่พลาดการเรียก
- ประวัติที่ทำให้เครือข่ายตอบข้อผิดพลาด `400` เกตเวย์จะซ่อม: บทบาท `developer` กลายเป็น `system` id การเรียกที่ว่างและซ้ำจะได้รับ id ไม่ซ้ำ `arguments` แบบออบเจกต์กลายเป็นสตริง JSON `type` ที่หายไปถูกเติม การเรียกที่ไม่มีชื่อถูกลบพร้อมกับผลลัพธ์
- การเรียกที่โมเดลเขียนเป็น markup ในข้อความ เกตเวย์จะย้ายไปที่ `tool_calls`; การเรียกปลอมในคำตอบของคำขอที่ไม่มีเครื่องมือจะถูกลบ
- การสร้างขาดกลางอาร์กิวเมนต์ — จะได้ `finish_reason: length` ไม่ใช่ `tool_calls`: เพิ่มขีดจำกัดคำตอบ

```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` ถูกลบ; การอ้างอิงแบบเวียนเกิดกลายเป็นสคีมาที่ไม่มีข้อจำกัด
- `pattern` ที่มีโครงสร้างซึ่งไม่มีใน RE2 (lookahead และ lookbehind, backreference, atomic group, possessive quantifier) ถูกถอดออก; การซ้ำที่เกิน 1000 ถูกย่อลงเหลือ 1000
- `anyOf` และ `oneOf` ของค่าคงที่ถูกรวมเป็น `enum`; ถ้ากิ่งที่รวมไม่ได้มีมากกว่า 16 การรวมจะถูกถอดออก

> สคีมาอาจกลายเป็นแบบหลวมกว่าต้นฉบับ — ตรวจสอบอาร์กิวเมนต์ของการเรียกที่ฝั่งของคุณ

## คำตอบแบบมีโครงสร้าง

`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` ถูกส่งไปยังเครือข่าย ถ้าโมเดลมีเพียงสองโหมด เกตเวย์จะปรับค่าให้ตรง: `none` และ `minimal` — เป็น `low` ค่าที่สูงกว่า — เป็นการให้เหตุผลแบบเริ่มต้น
- ถ้าโหนดปฏิเสธค่า เกตเวย์จะลดค่า (`max` และ `xhigh` → `high`, `minimal` → `low` ไม่เช่นนั้นจะถอดฟิลด์ออก) แล้วส่งคำขอซ้ำ
- ใน `/v1/messages` การให้เหตุผลจะไม่ถูกส่ง — ไม่มีบล็อก `thinking`

## ปลั๊กอิน

ปลั๊กอินเปิดด้วยฟิลด์ `plugins` — อาร์เรย์ของสตริงหรือออบเจกต์ที่มีออปชัน รายการ — `GET /v1/plugins`

| ปลั๊กอิน | คำอธิบาย | เงื่อนไข |
| --- | --- | --- |
| `response-healing` | ซ่อม JSON ที่ถูกตัดในคำตอบของโมเดล | เฉพาะแบบไม่สตรีม และถ้าคำตอบขึ้นต้นด้วย `{` หรือ `[` |
| `privacy-sanitization` | ปิดบังในข้อความ email, IPv4, หมายเลขบัตร, JWT, hex key 64 ตัวอักษร และคีย์รูปแบบ `sk-…`, `gw_…`, `gm-…`, `Bearer …` | โหมด — ฟิลด์ `privacy_mode`: `redact` (ค่าเริ่มต้น) หรือ `tokenize` |
| `file-parser` | ดึงข้อความจาก PDF | ถ้าข้อความในข้อความทั้งหมดเป็น PDF ใน base64: `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` — ตัวระบุคำขอ: แนบไปกับคำร้องขอ支援
- `Retry-After` มาพร้อมกับ `429`: รอกี่วินาทีก่อนลองใหม่
- เฮดเดอร์ `X-Title` และ `HTTP-Referer` (เหมือน OpenRouter) ช่วยให้เกตเวย์รู้จักแอปของคุณ; ข้อความของเฮดเดอร์เหล่านี้ไม่ถูกบันทึก

## ข้อจำกัด

- รูปภาพ: ส่วน `image_url` จะถูกแทนที่ด้วยข้อความแทน — โมเดลมองไม่เห็นรูป (`vision: false` ในความสามารถ)
- จากเบราว์เซอร์ API เข้าถึงได้เฉพาะจากโดเมนของ JoinGonka (ตรวจสอบ `Origin`): เรียกจากเซิร์ฟเวอร์ของคุณเอง อย่าใส่คีย์ในฟรอนต์เอนด์
- เอ็มเบดดิ้ง: `POST /v1/embeddings` ตอบกลับ `501` — ในเครือข่ายไม่มีโมเดลเอ็มเบดดิ้ง
- รหัสข้อผิดพลาด ลิมิต และไทม์เอาต์ — อยู่ในส่วน [ข้อผิดพลาดและขีดจำกัด](https://gate.joingonka.ai/th/docs/errors)
