Chat Completions API
*.arkor.app 推論エンドポイントのリクエスト/レスポンス完全仕様。
すべての Arkor エンドポイントは https://<slug>.arkor.app で同じ OpenAI 互換サーフェスを提供します。このページはワイヤレベルのリファレンスで、ワンクリックエンドポイントにもプロジェクトのエンドポイントにも等しく適用されます。
ルート
| メソッド | パス | 用途 |
|---|---|---|
POST | /v1/chat/completions | チャット補完(JSON または SSE ストリーミング) |
POST | /v1/messages | Anthropic ネイティブの Messages API(Anthropic ダイアレクトのモデル専用) |
GET | /v1/models | エンドポイントが配信するモデル id の一覧 |
GET | /v1/chat/completions/runs/{id} | 保存済み実行の SSE リプレイ |
GET | /healthz | 死活監視。{ "ok": true } を返す |
GET /v1/models は OpenAI 標準のリスト形式を返します。マルチモデルエンドポイントでは現在の公開カタログを(モデルの公開に応じて一覧は変わります)、それ以外のエンドポイントでは固定された 1 モデルだけを返します。チャット補完と同じ API キー認証の背後にあり、レスポンスは最大 30 秒キャッシュされることがあります。
各モデルが話すワイヤダイアレクトは 1 つだけです。大半のモデルはこのページで説明する OpenAI chat completions サーフェスを話しますが、Anthropic のモデル(claude-* の id)は同じエンドポイントの POST /v1/messages(Anthropic ネイティブの Messages API)で配信されます。同じベース URL と API キーで Anthropic SDK を向ければ使えます。GET /v1/models は両者を区別せずに一覧するため、モデルを誤ったサーフェスに送ると、正しいルートを示すメッセージつきの 400 が返ります。
認証
Fixed API key モードのエンドポイントは、どちらのヘッダでもキーを受け付けます:
curl https://<slug>.arkor.app/v1/chat/completions \
-H "Authorization: Bearer $ARKOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"こんにちは"}]}'x-api-key: <key> も同じように動きます。No auth モードのエンドポイントはチェック自体を行いません。
認証失敗は 401 と機械可読な code を返します:
| コード | 意味 |
|---|---|
missing_key | キーが提示されていない |
invalid_key | どの有効キーとも一致しない |
no_keys | キー必須のエンドポイントにキーが 1 つも設定されていない |
これらの code 値が現れるのは OpenAI 形式のルートだけです。POST /v1/messages では同じ認証失敗が Anthropic のエラーエンベロープ { "type": "error", "error": { "type": "authentication_error", "message": "..." } } で返り、code フィールドはありません。
失効済みキーは、エッジのキャッシュが更新されるまで最大 30 秒ほど認証に通ることがあります。
リクエストボディ
POST /v1/chat/completions は OpenAI の chat completions 形式を取ります。1 MiB を超えるリクエストは 413 で拒否されます。
| フィールド | 型 | 備考 |
|---|---|---|
messages | 配列、必須 | チャットメッセージ 1 件以上。content はプレーン文字列、または OpenAI のコンテンツパート配列(テキストパートのみ、{ "type": "text", "text": "..." })。image_url / input_audio / file などのマルチモーダルパートは 400 で拒否されます |
model | string | 単一モデルのエンドポイントでは受理されるが無視される(モデルはエンドポイント側で固定)。マルチモデルエンドポイントでは id でモデルを選択する(大文字小文字は区別しない)。省略時はデフォルトモデル、未知の id は 404(コード model_not_found)。有効な id は GET /v1/models で一覧できます |
stream | boolean | デフォルト false(JSON レスポンス) |
stream_options.include_usage | boolean | ストリーミング時に usage チャンクを受け取るオプトイン |
n | integer | 1(OpenAI のデフォルト)のみ受理。それ以外は 400(パイプラインは単一 choice のみ配信) |
temperature | number | 0〜2 |
top_p | number | 0〜1 |
max_tokens | integer | 正の整数 |
max_completion_tokens | integer | OpenAI の新しい出力トークン上限フィールド。両方受理され、両方送られた場合は max_completion_tokens が優先されます |
stop | string または配列 | 停止シーケンス。空でない文字列のみ、リストは 16 個まで |
presence_penalty | number | -2〜2 |
frequency_penalty | number | -2〜2 |
seed | integer | ベストエフォートの決定的サンプリング |
logprobs | boolean | 出力トークンの対数確率を返す |
top_logprobs | integer | 0〜20。0 より大きい値には logprobs: true が必要(モデルサーバ側で検証) |
logit_bias | object | 文字列化したトークン id → バイアス(-100〜100) |
tools / tool_choice | OpenAI 形式 | Function calling。ツールパーサ対応モデルが必要なのは自動選択(tool_choice 未指定または "auto")のみで、名前付き関数指定・"required"・"none" はパーサなしでも動作します |
response_format | OpenAI 形式 | json_schema による構造化出力を含む |
structured_outputs | object | vLLM 拡張: json / regex / choice / grammar / json_object の制約フィールド(相互排他) |
enable_thinking | boolean | 対応モデルでの推論(thinking)モード |
reasoning_effort | string | none / minimal / low / medium / high / xhigh / max のいずれか(それ以外は 400)。Gemma 4 は Thinking のオン/オフのみを区別するため、none は Thinking オフ、それ以外の値はすべて Thinking オンに丸められます |
user | string | OpenAI のエンドユーザー・アトリビューションフィールド。X-Arkor-End-User-Id と同じ使用量アトリビューションに反映されます(両方ある場合はヘッダが優先)。値は使用量履歴に保存され、集計キーになります。制約はアトリビューションヘッダと同じで、印字可能な Latin-1 で 256 文字まで。それ以外の値(日本語など)は黙って破棄されます。認可には使われません |
メッセージのロールは OpenAI の 4 種 system / user / assistant / tool です。新しい developer ロールは受理されず 400 になります。assistant メッセージは tool_calls を持てて(その場合 content は省略可)、tool メッセージは必須の tool_call_id で応答先を指定します。任意の name 参加者ラベルは system / user / assistant メッセージで受理されます。
未知のフィールドは拒否されず取り除かれるので、OpenAI SDK 固有の追加フィールドがエラーになることはありません。ツール定義・JSON スキーマ・structured_outputs の制約はそのままモデルサーバに転送されます。
レスポンスとストリーミング
stream: false(デフォルト)では標準の chat.completion JSON オブジェクトを返します。stream: true では OpenAI 形式の SSE チャンクを返し、data: [DONE] で終端します。usage は stream_options.include_usage を指定した場合のみストリームに含まれます。
Reasoning パーサ付きで動くモデルは、推論内容を可視の回答とは別に delta.reasoning_content として出力します。
実行履歴の保存が有効な場合、Arkor が永続化したレスポンスには保存された実行を指す X-Arkor-Run-Id ヘッダが付きます(実行履歴参照)。外部のサードパーティプロバイダが配信したレスポンス(例: マルチモデルエンドポイント上の Gemini や Claude モデル)は保存設定に関わらず永続化されず、run id も付きません。
保存済み実行のリプレイ
GET /v1/chat/completions/runs/{id} は保存済み実行の SSE ストリームを再送します。Last-Event-ID または ?from= クエリでの再開に対応します。未知・期限切れ・別エンドポイントの実行 id は 410(コード run_gone)を返します。
アトリビューションヘッダ
2 つの任意リクエストヘッダで、使用量の内訳にリクエストをラベル付けできます:
X-Arkor-End-User-Id— あなたのアプリケーションのユーザー id。X-Arkor-Session-Id— 会話やセッションの id。
値は印字可能な Latin-1 で 256 文字までです。不正な値は黙って破棄され、リクエストが拒否されることはなく、認可に使われることもありません。
OpenAI の user ボディフィールドも同じエンドユーザー・アトリビューションに反映されます。フィールドと X-Arkor-End-User-Id ヘッダの両方がある場合はヘッダが優先されます。Anthropic Messages ルートでは標準の metadata.user_id フィールドが同じ役割を果たし、優先順位も同じです(ヘッダが優先)。上記の制約はこれらのボディフィールドにも適用されます: 256 文字超や印字可能な Latin-1 以外の値(日本語のテキストなど)は黙って破棄され、リクエストは成功してもエンドユーザー・アトリビューションは付きません。採用された値はリクエストの使用量行に保存されるため、記録されたくない識別子は送らないでください。
エラー
| ステータス | 条件 |
|---|---|
400 | 不正な JSON、スキーマ違反、response_format と structured_outputs の矛盾 |
401 | 認証失敗(上記コード参照) |
403 | 選択したモデルに Arkor アカウントが必要(コード model_requires_signup)。プレミアムモデルは匿名エンドポイントの GET /v1/models にも表示されますが、そこからのディスパッチはサインアップ案内つきで拒否されます |
404 | 未知のサブドメイン、無効化済み、または期限切れのエンドポイント(メッセージは一律)。マルチモデルエンドポイントでは未知の model id も該当(コード model_not_found) |
410 | 保存済み実行が存在しない(リプレイルート) |
413 | ボディが 1 MiB 超 |
429 | レート制限(コード rate_limit_exceeded)。理由は 2 通りあります: エンドポイント所有者の推論クォータ超過(匿名のワンクリックエンドポイントにはアカウント所有より厳しい分・日単位の上限があります)、または外部プロバイダが処理したマルチモデルリクエストでベンダ側のレート制限が尽きた場合。いずれもレスポンスに Retry-After ヘッダ(秒。外部の場合はベンダの値を転送)が付くので、それ以上待ってからリトライしてください |
499 | クライアントが処理中に接続を切断 |
502 | 上流モデルサーバのエラー |
503 | プロバイダが一時的に利用不可(コード provider_env_unavailable)。リトライ可能 |
504 | すべての推論候補が応答前にタイムアウト(コード inference_upstream_timeout)。リトライ可能 |
529 | 試行したすべての外部プロバイダが過負荷を報告(コード overloaded。Anthropic の慣例に準拠)。ベンダの Retry-After があれば転送されます。時間を置いてリトライしてください |
OpenAI 互換ルート(POST /v1/chat/completions と GET /v1/models)のエラーボディは OpenAI のネストされたエンベロープです:
{ "error": { "message": "...", "type": "...", "param": null, "code": "..." } }Arkor 固有のリプレイルート(GET /v1/chat/completions/runs/{id})だけはフラットなエンベロープを維持します: { "error": string, "code"?: string }。
CORS
エンドポイントは許容的な CORS(Access-Control-Allow-Origin: *、credentials なし)を送るため、ブラウザから直接呼び出せます。許可されるリクエストヘッダには Authorization、Content-Type、x-api-key、Last-Event-ID、および上記のアトリビューションヘッダが含まれます。