Keural API
APIキーで、OpenAI Chat Completions形式のリクエストを送信します。
Keuralに登録されたモデルを、OpenAI Chat Completions形式で呼び出します。
Base URLはhttps://<環境ごとの公開APIドメイン>/llm/v1の形式です。公開APIドメインは環境ごとに異なるため、管理者に確認してください。
| メソッド | パス | 説明 |
|---|---|---|
POST | /llm/v1/chat/completions | 会話の作成(ストリーミング対応) |
GET | /llm/v1/models | キーに接続されたモデルの一覧 |
GET | /llm/v1/models/{model} | キーに接続されたモデルの情報 |
埋め込み、画像生成、音声、Responses APIのパスは対応しておらず、404を返します。
利用の流れ
| 手順 | やること |
|---|---|
| 1. キーの発行 | 設定 → APIでモデルを選び、キーを受け取ります。モデルIDとキーをコピーしておきます。 |
| 2. クライアントの接続 | アプリやコードに、Base URL、APIキー、モデルIDを入力します。 |
| 3. 利用と管理 | 同じ画面で使用量を確認し、必要に応じてキーを再発行または回収します。 |
準備事項
| 項目 | 内容 |
|---|---|
| Keuralアカウント | サインインできるアカウントが必要です。 |
| APIメニュー | 設定にAPIメニューがない場合は、管理者に機能の有効化を依頼します。 |
| 組織メンバーの権限 | 組織のワークスペースでキーを受け取るには、組織の管理者が先に自分のAPI利用を許可する必要があります。組織メンバーのAPI権限を参照してください。 |
| Base URL | 管理者が案内した公開APIのアドレス |
| クライアント | OpenAI API互換の接続に対応したアプリまたはSDK |
APIキーの発行
- 左下のアカウントメニューから設定を開き、APIを選びます。デスクトップアプリとモバイルアプリでは、ツールの欄にあります。
- API keysタブで、キーの所有先(個人のワークスペースまたは組織のワークスペース)とModel IDを選びます。
- 必要に応じて、New key expiration (optional, Korea time)を決めます。空欄のままにすると、回収されるまで無期限です。
- Issue keyを押し、表示されたキーをCopy keyでコピーして、安全な場所に保管します。キーの全文は、このときに1回だけ表示されます。画面を閉じると、再び見ることはできません。
- キーは選択したワークスペースとモデル1つに紐づきます。使用量は、キーを発行した人に帰属します。
- 同じワークスペース・モデルのキーは1つだけです。新しく受け取るには、既存のキーを再発行するか回収します。
- キーを紛失した場合は再発行します。再発行すると、以前のキーは即座に無効になります。
- 発行できるモデルがない場合は、モデルの公開設定、料金プラン、組織のAPI権限を管理者に確認してください。
組織メンバーのAPI権限
組織のオーナー・管理者用です。組織のワークスペースでメンバーがキーを受け取るには、管理者が先に許可する必要があります。すべてのメンバーの既定値は遮断です。
組織管理 → Organization APIは、次の3つの領域で構成されます。メニューがない場合は、API機能がオフになっているか、組織管理の権限がないアカウントです。
| 領域 | 役割 |
|---|---|
| API permissions by user | メンバーごとに、API利用の許可をオン・オフします。 |
| Issued keys | 組織で発行されたキーの状態を確認し、回収します。キーの全文は見られません。 |
| API usage | 組織で発行されたキーのリクエスト数とトークン使用量を確認します。 |
| 操作 | 結果 |
|---|---|
| 許可をオンにする | そのメンバーが、組織のワークスペースでキーを発行できるようになります。 |
| 許可をオフにする | 新規の発行と、既存のキーによる呼び出しが遮断されます。発行済みのキーは自動で削除されないため、必要に応じてIssued keysで回収します。 |
メンバーが組織を退出したり、組織から除外されたりすると、そのメンバーが組織から受け取ったキーは自動的に回収されます。
クライアントに接続する
OpenAI API互換のアプリ(チャットクライアント、IDE拡張、自動化ツールなど)に、次の3つの値を入力します。
| 値 | 入力する内容 | アプリごとの項目名 |
|---|---|---|
| Base URL | 管理者が案内した公開APIのアドレス(…/llm/v1) | Base URL、API Base、Endpoint、Host |
| API Key | 発行を受けたキー(前後の空白なし) | API Key、Token、Secret Key、Authorization |
| Model | 発行画面のModel ID。キーに接続されたモデルと完全に一致している必要があります | Model、Model ID、Model Name |
- アプリの設定で、OpenAI互換の接続(Connection)を追加します。
- Base URLとAPI Keyを入力して保存します。
- モデル一覧からモデルを選びます。一覧には、キーに接続されたモデルが1つだけ表示されます。
- 短いメッセージを送り、応答を確認します。
リクエストは次のとおりです。
| 区分 | 内容 |
|---|---|
| 会話のリクエスト | POST <Base URL>/chat/completions |
| モデルの照会 | GET <Base URL>/models |
| 認証ヘッダー | Authorization: Bearer <発行されたキー> |
| コンテンツのヘッダー | Content-Type: application/json |
最初のリクエスト
export KEURAL_API_KEY='発行されたキー'
export KEURAL_BASE_URL='https://<環境ごとの公開APIドメイン>/llm/v1'
export MODEL_ID='発行画面のモデルID'
curl "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"こんにちは。\"}]}"リクエスト本文のmodelは、キーに接続されたモデルIDと同じである必要があります。provider/モデルIDのように前にパスが付いている場合は、最後の/の後ろを比較します。異なる場合は403を返します。レスポンスのmodelには、常にキーのモデルIDが入ります。
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["KEURAL_API_KEY"],
base_url=os.environ["KEURAL_BASE_URL"],
)
res = client.chat.completions.create(
model=os.environ["MODEL_ID"],
messages=[{"role": "user", "content": "こんにちは。"}],
)
print(res.choices[0].message.content)対応しているリクエストのフィールド
最上位のフィールドは、次の18個だけを受け付けます。ほかのフィールドを送ると400を返します。値がnullの省略可能なフィールドは、送信しなかったものとして処理します。
| フィールド | ルール |
|---|---|
model | 必須。キーのモデルID |
messages | 必須。1〜4,096個 |
stream・stream_options | stream_optionsはstream: trueのときだけ送ります。include_usageに対応しています。 |
tools | 最大128個。関数名は[A-Za-z0-9_-]の1〜64文字 |
tool_choice | none・auto・required・特定の関数。requiredはtoolsが必要です。 |
parallel_tool_calls | モデルが対応していない場合は400 |
response_format | text・json_object・json_schema |
max_tokens・max_completion_tokens | どちらか一方だけを送ります。送らない場合は4,096になります(モデルの上限がより低ければその値)。モデルの上限を超えると400です。 |
temperature | 0〜2。モデルが対応していない場合は400 |
top_p | 0〜1 |
frequency_penalty・presence_penalty | -2〜2 |
stop | 文字列、または最大4個の配列 |
seed | 整数 |
user | 最大256文字 |
n | 1のみ |
メッセージ
| ロール | 受け付けるフィールド |
|---|---|
system・developer | content、name |
user | content(文字列、またはテキスト・画像パーツの配列)、name |
assistant | content、name、refusal、tool_calls |
tool | content、tool_call_id |
toolメッセージは、直前のtool_callsのidに対して1回ずつだけ返答します。- 画像パーツ(
image_url)は、画像を受け付けるモデルのuserメッセージにだけ入れます。http・httpsのアドレス、またはPNG・JPEG・GIF・WebPのbase64データURIを入れます。detailはauto・low・highです。
本文
| 項目 | 上限 |
|---|---|
| Content-Type | application/json |
| サイズ | 1MiB |
| JSONの構造 | 最上位のオブジェクトが1つ、入れ子の深さは64以下、同じキーの重複は禁止 |
| リクエストの時間 | 最大600秒 |
本文のルールに違反すると400になり、paramはbodyです。
ストリーミング
リクエストに"stream": trueを入れると、SSEで応答します。チャンクはdata: ...のイベントで送信され、最後にdata: [DONE]が送信されます。"stream_options": {"include_usage": true}を入れると、[DONE]の直前に、トークン使用量のチャンクが追加で送信されます。
include_usageを入れると、すべてのチャンクにusage: nullが入り、最後の使用量のチャンクはchoicesが空の配列になります。ストリーミングでない応答は、入力・出力のトークンがどちらも確認できたときにだけusageを含みます。
応答のidはchatcmpl-<x-request-id>の形式です。すべての応答ヘッダーにはx-request-idが付きます。
ストリーミング中にエラーが発生すると、エラーのJSONを含むdata:のイベントが送信され、[DONE]なしで接続が終わります。チャンク1つが1MiBを超えるか、応答が16MiBを超えると、503で終わります。
curl -N "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"こんにちは。\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true}}"利用上限
リクエストは、ユーザー・組織・モデルごとに、同時リクエスト数、1分あたりのリクエスト数(RPM)、1分あたりのトークン数(TPM)が制限されます。実際の値は、環境ごとに異なります。
1分あたりのトークンは、リクエストを受け取る時点で先に差し引きます。入力は英語4文字につき1トークン、それ以外の文字は1文字につき1トークン、画像1枚は2,000トークンとして計算します。出力はmax_tokens(最大4,096)の分だけ差し引かれるため、出力の上限を必要な分だけ指定すると、利用上限の余裕が大きくなります。
429のcode | 原因 | Retry-After |
|---|---|---|
rate_limit_exceeded | RPM・TPM・同時リクエスト数の超過 | RPM・TPMは60秒、同時リクエストは1秒 |
api_busy | サーバーの処理能力を超過 | なし。少し待ってから再試行します。 |
upstream_rate_limit | モデルの提供事業者の上限を超過 | なし |
キーの管理
設定 → APIのAPI keysタブで、発行されたキーの状態(有効・期限切れ・回収済み)を確認し、再発行したり回収したりします。
キーはkrl_llm_で始まる51文字の文字列です。キーの所有先ごとに、キーは1つだけです。すでにある場合は、新たに発行せず再発行します。有効期限は、今日以降の日付のみ指定できます。
| 操作 | 結果 | 注意点 |
|---|---|---|
| 再発行 | 新しいキーを受け取ります。 | 以前のキーは即座に使えなくなります。接続しているアプリのキーも変更します。 |
| 回収 | キーを即座に遮断します。 | 漏えいが疑われるときに使います。回収したキーは元に戻せません。 |
使用量の確認
APIで送信したリクエストと使用したトークンは、次の2か所で確認します。
| 場所 | 内容 |
|---|---|
| 設定 → API → API usageタブ | 今のワークスペースで、自分が発行したキーの使用量 |
| 組織管理 → Organization APIの下のAPI usage | 組織で発行されたすべてのキーの使用量(組織のオーナー・管理者) |
照会の条件
| 条件 | 説明 |
|---|---|
| 開始日時・終了日時 | 韓国時間基準。開始日時は含み、終了日時は含みません。空欄の場合は直近7日間を表示し、一度に最大90日まで照会します。 |
| Model ID | 特定のモデルのリクエストだけを照会します。空欄の場合は全件です。 |
| リクエストの状態 | すべて・実行中・完了・失敗・中断・未確定から選びます。 |
条件を決めてSearchを押します。最近のリクエストを反映するにはRefreshを押します。
画面に表示される値
- 適用された照会期間(KST): 実際に照会された期間です。開始日時・終了日時を空欄にした場合や90日を超えた場合は、サーバーが調整した期間が表示されます。
- リクエスト数と入力トークン・出力トークン・合計トークンの合計: 確認された値のみを合算します。確認されていないトークンは0として扱わず、未確認と表示します。
- リクエストの一覧: リクエストごとに、リクエスト日時、Model ID、リクエストの状態、入力・出力・合計のトークンが1行ずつ表示されます。1ページに20件ずつ表示され、Previous・Nextで移動します。
行のRequest detailsを押すと、次の値が展開されます。
| 項目 | 説明 |
|---|---|
| リクエストID | お問い合わせの際に伝える値です。 |
| 応答方式 | ストリーミングまたは通常の応答 |
| 使用量の確認状態 | 確認済み・一部確認済み・未確認 |
| 終了日時・応答時間(ms) | リクエストが終わった日時と、かかった時間 |
| キャッシュ読み取り・キャッシュ作成・推論トークン | モデルがこの値を返した場合にのみ表示されます。 |
ストリーミングのリクエストは、stream_options.include_usageを入れなくても使用量が記録されます。リクエストが途中で切れると、一部確認済みや未確認のまま残ることがあります。
エラーの形式
エラーは、OpenAI互換の形式で返します。
{
"error": {
"message": "人が読める形式のエラーの説明",
"type": "authentication_error",
"code": "invalid_api_key",
"param": null
}
}typeはステータスコードで決まり、codeで原因を区別します。
| ステータス | type | code | 原因 |
|---|---|---|---|
400 | invalid_request_error | invalid_request | フィールド・値・本文のルール違反。paramに問題のあったフィールド |
400 | invalid_request_error | upstream_rejected_request | モデルの提供事業者がリクエストを拒否 |
401 | authentication_error | invalid_api_key | キーの形式エラー、キーがない、期限切れ・回収・再発行、Authorizationヘッダーが2つ以上 |
403 | permission_error | api_disabled | Keural APIの機能がオフになっている |
403 | permission_error | model_api_disabled | モデルのAPI公開がオフになっている |
403 | permission_error | model_not_allowed | modelがキーのモデルと異なる、メンバーのAPI権限がない |
404 | invalid_request_error | not_found | 存在しないパス |
405 | invalid_request_error | method_not_allowed | 誤ったメソッド。Allowヘッダーに許可されたメソッド |
429 | rate_limit_error | 上の利用上限の表 | 上限の超過 |
503 | server_error | upstream_timeout | 600秒以内に応答が終わらない |
503 | server_error | invalid_upstream_response | 提供事業者の応答形式が不正、ストリームのサイズ超過 |
503 | server_error | dependency_unavailable・unsupported_provider | 一時的な内部の問題。x-request-idを添えて問い合わせる |
トラブルシューティング
| 症状 | 応答コード | 確認する項目 |
|---|---|---|
| モデル一覧が空、または接続に失敗する | 404・405 | Base URLが…/llm/v1で終わっているか |
| 認証に失敗する | 401 | キーの入力ミス・前後の空白、期限切れ・回収・再発行されていないか |
| 接続はできるが、モデルを使えない | 403 | モデルIDがキーのモデルと一致しているか、組織のAPI権限 |
| 応答が遅い、または時々失敗する | 429 | 利用上限 |
| しばらく応答が来ない | 5xx | しばらくしてから再試行する |
| 使用量が表示されない、または実際と異なる | — | 照会期間と、キーの所属ワークスペース |
解決しない場合は、管理者に問い合わせてください。次の情報を添えると、原因を早く特定できます。キーの全文とプロンプトの内容は送信しないでください。
- 発生した日時
- 使用したモデルID
- クライアントアプリの名前とバージョン
- 応答ヘッダーの
x-request-id - 画面に表示されたエラーメッセージ