# 글 — /v1/chat/completions

> OpenAI 채팅 형식 하나로 다섯 벤더의 글 모델을 부릅니다.

> 원문: https://schoolorder.kr/docs/reference/chat

가장 많이 쓰는 문이에요. OpenAI 채팅 형식 그대로 받아요. Claude 를 부르시면 저희가 Anthropic 형식으로 번역해 넘기고 답을 다시 OpenAI 형식으로 돌려드려요 — 그래서 OpenAI 형식만 아는 도구(Cursor · Cline · LangChain)에서도 Claude 가 그대로 돌아가요.

**가장 짧은 호출**

```bash
curl https://schoolorder.kr/v1/chat/completions \
  -H "Authorization: Bearer $SCHOOLORDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "messages": [{"role": "user", "content": "안녕하세요"}]
  }'
```

- stream: true — 받는 대로 흘려드려요. 긴 답은 이쪽이 안전해요(한 번에 기다리는 시간이 5분이라서요).
- tools — 도구 호출을 벤더 형식으로 번역해 넘기고, 모델이 부른 도구를 OpenAI 형식으로 돌려드려요.
- reasoning_effort — 얼마나 따져볼지 고르실 수 있어요. 받는 모델인지는 GET /v1/models 의 supports_effort 가 알려드려요.

> **⚠️ Claude 5 세대에는 temperature 를 안 보내요**
>
> Fable · Opus 5 · Sonnet 5 와 Opus 4.8 은 temperature 를 받으면 400 을 내요. 보내셔도 저희가 빼고 넘기니 그대로 두셔도 되지만, 그 값이 반영되지 않는다는 건 알고 계셔야 해요.

## 요청 파라미터

**요청 본문 (JSON)**

| 파라미터 | 받는 값 | 저희가 하는 일 |
| --- | --- | --- |
| `model` (필수) | 모델 id 문자열 | 없으면 400 이에요. 모르는 이름이면 404 와 함께 가장 가까운 이름을 알려드려요 — 시키지 않은 모델로 몰래 바꾸지 않아요. |
| `messages` (필수) | role · content 배열 | Claude 로 갈 때는 role: system 을 따로 떼어 Anthropic 의 system 필드로 옮겨요. 그쪽은 system 을 messages 안에 못 받거든요. |
| `max_tokens` | 정수 (max_completion_tokens 도 받아요) | Anthropic 은 이 값이 필수예요. 안 보내시면 8,192 로 채워 넘겨요 — 안 채우면 400 이 나거든요. |
| `stream` | true / false | 그대로 넘겨요. 답을 받는 대로 흘려드려요. |
| `reasoning_effort` | low · medium · high | Claude 로 갈 때는 Anthropic 이 실제로 받는 output_config.effort 로 옮겨요. 못 받는 모델엔 아예 안 실어요. 받는 모델인지는 GET /v1/models 의 supports_effort 로 보세요. |
| `temperature · top_p` | 숫자 | Claude 5 세대(Fable · Opus 5 · Sonnet 5 · Opus 4.8 · 4.7)로 갈 때는 빼고 넘겨요. 그 모델들이 이 값에 400 을 내는데, 어차피 안 읽는 값이라 빼도 답이 같아요. |
| `stop` | 문자열 또는 배열 | Claude 로 갈 때 stop_sequences 로 옮기고, 문자열 하나면 배열로 감싸요. |
| `tools` | OpenAI 함수 배열 | Anthropic 형식(input_schema)으로 번역해 넘기고, 모델이 부른 도구를 OpenAI 의 tool_calls 로 되돌려 드려요. |
| `tool_choice` | none · auto · required · 특정 함수 | Anthropic 형식으로 옮겨요. 다만 Fable 5.1 은 강제 호출에 400 을 내서 auto 로 낮춰 보내요 — 400 보다 「강제가 안 됨」이 낫다고 봤어요. |

## 응답

OpenAI 채팅 응답 그대로예요. Claude 에서 온 답도 저희가 이 모양으로 되돌려 드리니 받는 코드는 손댈 게 없어요. 끝난 이유(finish_reason)도 OpenAI 낱말로 옮겨요 — end_turn·stop_sequence 는 stop, max_tokens 는 length, tool_use 는 tool_calls, 거절은 content_filter 예요.

**응답 예시 (줄임)**

```json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "model": "claude-sonnet-5",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "안녕하세요!" },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 12, "completion_tokens": 8, "total_tokens": 20 }
}
```

**응답 헤더 — 저희가 붙이는 것**

| 파라미터 | 받는 값 | 저희가 하는 일 |
| --- | --- | --- |
| `x-gateway-fallback-depth` | 0 부터의 정수 | 몇 번째 경로에서 성공했는지예요. 0 이면 첫 번에 됐다는 뜻이고, 1 이상이면 벤더가 한 번 막았지만 저희가 다른 경로로 돌려 성공했다는 뜻이에요. |

## 무엇이 되고 무엇이 안 되나

Claude 를 이 문으로 부르실 때는 저희가 몸통을 Anthropic 형식으로 옮겨요. 그래서 「옮기는 자리가 있느냐」가 곧 「되느냐」예요. 아래는 옮기는 코드를 그대로 읽어 적은 것이고, 다른 벤더(GPT · Gemini · Grok)는 번역 없이 그대로 나가니 그쪽 문서대로 다 돼요.

| 기능 | 이 문으로 Claude 부르기 | /v1/messages 로 직접 |
| --- | --- | --- |
| 스트리밍 | 됩니다 | 됩니다 |
| 도구 호출 | 됩니다 — 도구를 부르고 그 결과를 먹여 이어가는 여러 턴까지 | 됩니다 |
| 그림 입력 | 됩니다 — image_url 을 Anthropic 그림 블록으로 옮겨요(data: 와 http 둘 다) | 됩니다 |
| 생각 강도 | 됩니다 — reasoning_effort 를 output_config.effort 로 옮겨요 | Anthropic 모양 그대로 |
| 프롬프트 캐싱 | 됩니다 — 글 블록의 cache_control 을 같이 옮겨요 | 그대로 나가요 |
| temperature | Claude 5 세대엔 빼고 넘겨요(그 모델이 400 을 내요) | 그대로 나가서 400 이 날 수 있어요 |
| 강제 도구 호출 | Fable 5.1 에선 auto 로 낮춰요(그 모델이 400 을 내요) | 그대로 나가요 |

> **새 기능이 급하시면 /v1/messages 로**
>
> 이 문은 아는 필드를 옮기는 방식이라, Anthropic 이 새 파라미터를 내면 저희가 배선하기 전까지는 안 실려요. 그때는 /v1/messages 로 부르시면 몸통이 그대로 나가요. 무엇이 빠졌는지 알려주시면 여기도 이어드릴게요.

## 이 문이 받는 모델

#### 글 — `POST /v1/chat/completions`

| model | 제공사 | 입력 / 1M | 출력 / 1M | 컨텍스트 |
| --- | --- | --- | --- | --- |
| claude-fable-5 | anthropic | $10 | $50 | 1000K |
| claude-opus-5 | anthropic | $5 | $25 | 1000K |
| claude-sonnet-5 | anthropic | $2 | $10 | 1000K |
| claude-haiku-4-5 | anthropic | $1 | $5 | 200K |
| claude-opus-4-8 | anthropic | $5 | $25 | 1000K |
| claude-opus-4-7 | anthropic | $5 | $25 | 1000K |
| claude-opus-4-6 | anthropic | $5 | $25 | 1000K |
| claude-sonnet-4-6 | anthropic | $3 | $15 | 1000K |
| claude-sonnet-4-5 | anthropic | $3 | $15 | 1000K |
| gpt-5.6-sol | openai | $4 | $20 | 400K |
| gpt-5.6-terra | openai | $2 | $12 | 400K |
| gpt-5.6-luna | openai | $0.2 | $1.2 | 400K |
| gpt-5.5 | openai | $5 | $30 | 400K |
| gpt-5.2 | openai | $1.75 | $14 | — |
| gpt-5.1 | openai | $1.25 | $10 | — |
| gpt-5.4 | openai | $2.5 | $15 | 400K |
| gpt-5 | openai | $1.25 | $10 | 400K |
| gpt-5-mini | openai | $0.25 | $2 | 400K |
| gpt-5.4-mini | openai | $0.75 | $4.5 | 400K |
| gpt-4.1 | openai | $2 | $8 | 1000K |
| gpt-4o | openai | $2.5 | $10 | 128K |
| gpt-4o-mini | openai | $0.15 | $0.6 | 128K |
| o1 | openai | $15 | $60 | 200K |
| o3-mini | openai | $1.1 | $4.4 | 200K |
| gpt-5.4-nano | openai | $0.2 | $1.25 | — |
| gpt-5-nano | openai | $0.05 | $0.4 | — |
| gpt-4.1-mini | openai | $0.4 | $1.6 | — |
| gpt-4.1-nano | openai | $0.1 | $0.4 | — |
| o3 | openai | $2 | $8 | — |
| o4-mini | openai | $1.1 | $4.4 | — |
| gemini-3.1-pro-preview | google | $2 | $12 | 1000K |
| gemini-3.7-flash | google | $0.75 | $3.75 | 1000K |
| gemini-3.6-flash | google | $0.75 | $3.75 | 1000K |
| gemini-3.5-flash | google | $1.5 | $9 | 1000K |
| gemini-3.5-flash-lite | google | $0.3 | $2.5 | 1000K |
| gemini-3.1-flash-lite | google | $0.25 | $1.5 | 1000K |
| grok-4.6 | xai | $2 | $6 | 2000K |
| grok-4.20-0309-reasoning | xai | $1.25 | $2.5 | — |
| grok-4.20-0309-non-reasoning | xai | $1.25 | $2.5 | — |
| grok-build-0.1 | xai | $1 | $2 | — |
| grok-4.5 | xai | $2 | $6 | 2000K |
| grok-4.3 | xai | $1.25 | $2.5 | 2000K |
| deepseek-ai/DeepSeek-V4-Flash | deepinfra | $0.09 | $0.18 | 1049K |
| deepseek-ai/DeepSeek-V4-Pro | deepinfra | $1.3 | $2.6 | 1049K |
| deepseek-ai/DeepSeek-V3.1 | deepinfra | $0.25 | $0.95 | 164K |
| deepseek-ai/DeepSeek-V3.2 | deepinfra | $0.26 | $0.38 | 164K |
| deepseek-ai/DeepSeek-R1-0528 | deepinfra | $0.5 | $2.15 | 164K |
| meta-llama/Llama-3.3-70B-Instruct-Turbo | deepinfra | $0.1 | $0.32 | 131K |
| meta-llama/Llama-4-Scout-17B-16E-Instruct | deepinfra | $0.1 | $0.3 | 328K |
| meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo | deepinfra | $0.02 | $0.04 | 131K |
| meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 | deepinfra | $0.2 | $0.8 | 1049K |
| Qwen/Qwen3-235B-A22B-Instruct-2507 | deepinfra | $0.09 | $0.55 | 262K |
| Qwen/Qwen3.5-9B | deepinfra | $0.1 | $0.15 | 262K |
| Qwen/Qwen3-VL-30B-A3B-Instruct | deepinfra | $0.15 | $0.6 | 262K |
| Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo | deepinfra | $0.3 | $1 | 262K |
| mistralai/Mistral-Small-3.2-24B-Instruct-2506 | deepinfra | $0.075 | $0.2 | 128K |
| mistralai/Mistral-Nemo-Instruct-2407 | deepinfra | $0.019 | $0.03 | 131K |
| moonshotai/Kimi-K2.5 | deepinfra | $0.45 | $2.25 | 262K |
| moonshotai/Kimi-K2.6 | deepinfra | $0.75 | $3.5 | 262K |
| MiniMaxAI/MiniMax-M3 | deepinfra | $0.28 | $1.1 | 524K |
| zai-org/GLM-4.7 | deepinfra | $0.4 | $1.75 | 203K |
| openai/gpt-oss-120b | deepinfra | $0.037 | $0.17 | 131K |
| openai/gpt-oss-20b | deepinfra | $0.03 | $0.14 | 131K |
| google/gemma-3-27b-it | deepinfra | $0.08 | $0.16 | 131K |
| google/gemma-4-31B-it | deepinfra | $0.13 | $0.38 | 262K |
| nvidia/NVIDIA-Nemotron-3-Super-120B-A12B | deepinfra | $0.085 | $0.4 | 262K |
| microsoft/phi-4 | deepinfra | $0.07 | $0.14 | 16K |
| ibm-granite/granite-4.2-8b | deepinfra | $0.06 | $0.25 | 131K |

> **이 문이 안 받는 것**
>
> pro 등급(gpt-5-pro · o3-pro 류)은 벤더가 이 문으로 안 받아요 — /v1/responses 로 보내주세요. 그림·임베딩·음성 모델을 넣으시면 없다고 하지 않고 어느 문으로 가야 하는지 알려드려요.

