OpenAI /v1/responses
POST /v1/responses は cc-router v2.3+ で追加された OpenAI Responses 互換入口 です。設計意図は、Codex CLI や任意の OpenAI Responses 風クライアントが、追加のアダプタを書かずに cc-router の上流サブスクリプションをそのまま再利用できるようにすることです。
対応バージョン:cc-router v3.0.0 以上。
プロトコル位置付けと翻訳フロー
クライアント (OpenAI Responses) cc-router 上流
─────────────────────────── ───────────────────────────────── ─────────────
POST /v1/responses ─────────────────────►│ handler::responses │
body: OpenAI Responses 形式 │ ↓ request_to_anthropic │
│ Anthropic Messages 形式 │
│ ↓ pipeline::dispatch │──► サブ選択 / model 書換
│ pipeline が Anthropic SSE/JSON を返す│◄── 上流応答
│ ↓ translate_*_to_responses │
│ OpenAI Responses 形式 │
◄──────────────────── HTTP レスポンス─────│ │
ディスパッチ pipeline は完全に無改造です——既にプロトコル翻訳を行う 4 つの provider(codex / openai / gemini / kiro)を含む、すべての上流 provider 経路をそのまま再利用します。/v1/responses は pipeline の前後に入口翻訳層を 1 段被せただけです。
リクエスト
POST /v1/responses
Content-Type: application/json
| ヘッダ | 必須 | 説明 |
|---|---|---|
Content-Type: application/json | はい | リクエストボディは JSON 必須 |
x-api-key または Authorization: Bearer ... | 認証設定による | /v1/responses は許可リスト外、認証有効時は必須 |
| その他 OpenAI SDK 付属ヘッダ | いいえ | 消費せず、上流へも転送しない(上流プロトコルが Anthropic のため) |
認証の注意:/v1/messages と同じ token チェックですが、401 エラーボディは Anthropic 形式のままです(auth_layer は handler の前で動くため)。responses handler に入った後に発生する 4xx/5xx だけが OpenAI 形式になります。
リクエストボディ は OpenAI Responses API 標準のサブセットです。cc-router が消費・翻訳するフィールド:
| フィールド | 型 | 必須 | 挙動 |
|---|---|---|---|
model | string | はい | 仮想モデルに解決。gpt-5.5 / gpt-5.4 / gpt-5.4-mini などのエイリアスをサポート。欠落時は 400 |
stream | boolean | いいえ(既定 false) | true で SSE 翻訳、false で JSON 翻訳 |
instructions | string | いいえ | Anthropic system へ翻訳。input 内に developer/system role テキストがあれば連結合併 |
input | array | はい | フラットな item 列(message / function_call / function_call_output / reasoning)を Anthropic messages に翻訳 |
max_output_tokens | integer | いいえ | Anthropic max_tokens に翻訳(無指定時は 4096、Anthropic 必須のため) |
reasoning.effort | string | いいえ | Anthropic thinking { type: enabled, budget_tokens } に翻訳。minimal → 0 / low → 1024 / medium → 8192 / high → 16384 |
tools | array | いいえ | Anthropic tool schema に翻訳 |
tool_choice | object | いいえ | Anthropic tool_choice に翻訳 |
非ストリーミングリクエストの例
curl http://127.0.0.1:23456/v1/responses \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-5.4",
"max_output_tokens": 256,
"instructions": "You are concise.",
"input": [
{ "type": "message", "role": "user",
"content": [{ "type": "input_text", "text": "cc-router を一文で説明して" }] }
]
}' | jq
レスポンス(非ストリーミング)
200 OK、Content-Type: application/json- ボディは OpenAI Responses 標準の
responseJSON- cc-router は pipeline が返す Anthropic message を OpenAI Responses 形式に翻訳
output[]をフラット化:text content_block →messageitem、tool_use →function_callitem、thinking →reasoningitem(encrypted_contentは Anthropic のsignatureで往復)usage.input_tokens / output_tokensを OpenAI フィールドに翻訳stop_reasonをstatus / incomplete_detailsに翻訳(例:max_tokens→incomplete_details.reason = max_output_tokens)
{
"id": "resp_xxx",
"object": "response",
"created_at": 1767225600,
"status": "completed",
"model": "gpt-5.5",
"output": [
{
"type": "message",
"role": "assistant",
"content": [{ "type": "output_text", "text": "..." }]
}
],
"usage": { "input_tokens": 42, "output_tokens": 128, "total_tokens": 170 }
}
レスポンス(ストリーミング SSE)
200 OK、Content-Type: text/event-stream(このヘッダのみ設定。cache-control / transfer-encodingは設定しない——axum に chunked エンコーディングを任せ、HTTPS+rustls 経路でIncompleteMessageを起こさないため)- ストリームは OpenAI Responses SSE プロトコル。内部コンバータが上流 Anthropic SSE からリアルタイムで翻訳します。
イベントマッピング
| Anthropic イベント | OpenAI Responses イベントへの翻訳 |
|---|---|
message_start | response.created + response.in_progress |
content_block_start (text) | response.output_item.added + response.content_part.added |
content_block_delta (text_delta) | response.output_text.delta |
content_block_start (thinking) | response.output_item.added(reasoning item) |
content_block_delta (thinking_delta) | response.reasoning_summary_text.delta |
content_block_start (tool_use) | response.output_item.added(function_call item) |
content_block_delta (input_json_delta) | response.function_call_arguments.delta |
content_block_stop | response.content_part.done + response.output_item.done |
message_delta | (usage を副次的に抽出。直接フレームは送出しない) |
message_stop | response.completed |
上流切断 / message_stop 欠落 | フォールバックで response.completed を送出 |
Anthropic SSE との重要な違い:
data: [DONE]を送らない——OpenAI Responses クライアントはresponse.completedで終了- 切断時の保険:上流の転送層が落ちた、または上流が
message_stopを出し忘れた場合でも、cc-router は最低限response.completedを出すので、OpenAI SDK が終結イベント待ちでハングしない
ストリーミングリクエストの例
curl -N http://127.0.0.1:23456/v1/responses \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-5.4",
"stream": true,
"max_output_tokens": 256,
"input": [
{ "type": "message", "role": "user",
"content": [{ "type": "input_text", "text": "ping" }] }
]
}'
ストリームは event: response.completed で終了(data: [DONE] は送出しない)。
ディスパッチ
/v1/messages と完全に同一です——/v1/responses はクライアントの model フィールドを仮想モデルに解決し、同じディスパッチ + リトライロジックを実行します。
つまり:
gpt-5.5/gpt-5.4/gpt-5.4-miniとmodel-sonnet/claude-sonnet-4-6などの任意の仮想モデルエイリアスがすべて/v1/responsesから入れる- 上流は任意の 9 社の Anthropic provider または codex / openai / gemini / kiro——クライアントには見えない
/v1/responsesは OAuth-only の codex provider を fallback としてバインド不可(/v1/messagesと同じ制約)
完全な対応表は Anthropic /v1/messages → 仮想モデルマッピング を参照。
エラーレスポンス
/v1/responses 内で生成されるエラーは OpenAI Responses 形式:
{
"error": {
"message": "...",
"type": "<kind>",
"code": null
}
}
| Status | 発生条件 | 出典 |
|---|---|---|
400 | リクエストボディが正しい JSON でない | handler::responses |
400 | model フィールド欠落 | handler::responses |
400 | OpenAI → Anthropic 翻訳に失敗(input の構造が不正など) | request_to_anthropic |
401 | 認証失敗 | Anthropic 形式(auth_layer は handler の前で動く) |
500 | パイプライン内部エラー | handler::responses |
500 | pipeline JSON ボディの読み取り失敗 / 上流応答の解析失敗 | translate_json_to_responses |
| 上流 status 透過 | pipeline の Anthropic エラーボディを OpenAI 形式へ自動翻訳 | translate_json_to_responses |
未実装の OpenAI エンドポイント
下記の公式 OpenAI エンドポイントは cc-router では未実装で、これは設計上の選択です:
POST /v1/chat/completions(Chat Completions API)——cc-router の OpenAI 互換層は Responses API のみを実装GET /v1/responses/{id}、POST /v1/responses/{id}/cancelなどの Responses 状態エンドポイント——cc-router は無状態プロキシで response をキャッシュしないため、クライアントはストリーミングのresponse.completedで終了するだけで十分- OpenAI Assistants / Threads / Files API
cc-router が想定するクライアントは Codex CLI / Claude Code のような無状態対話クライアントで、POST /v1/responses または POST /v1/messages と GET /v1/models のみに依存します。