> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/tech/ja/ai-gateway/ai-gateway-openai-compatible.md).

# AI Gateway：OpenAI 互換 API 連携

OpenAI SDK でアプリケーションのロジックを変更せずに MaiAgent AI Gateway に接続する方法を説明します。エンドポイントと base URL、Bearer 認証、モデル識別子（エイリアス、カスタムモデル、フォールバックグループ）、推論レベル、ストリーミング、音声認識と音声合成、エラー形式、Credits の課金と制限を扱います。

このページは、MaiAgent AI Gateway 経由で言語モデルを呼び出すエンジニア、特に OpenAI SDK で既にアプリケーションを開発している独立系ソフトウェアベンダー（ISV）向けです。Gateway は OpenAI 互換のインターフェースを提供します。SDK の `base_url` を MaiAgent に、`api_key` を MaiAgent API Key に変更するだけで、呼び出しロジックを変えずに、組織が利用できる各ベンダーのモデルを単一の窓口から呼び出せます。

Gateway がソース、モデル、データ、責任、記録の 5 つの側面で提供する保護については、[AI Gateway のセキュリティ](/tech/ja/ai-gateway/ai-gateway-security.md)をご覧ください。このページでは連携方法のみを説明します。

{% hint style="info" %}
AI Gateway は MaiAgent プラットフォーム側で組織に対して有効化する必要があります。組織で有効化されていない場合、どのキーで推論エンドポイントを呼び出しても、無効なキーと同じ `401` が返されます。
{% endhint %}

## エンドポイント一覧 <a href="#endpoints" id="endpoints"></a>

| メソッド   | パス                             | 認証 | 用途                            |
| ------ | ------------------------------ | -- | ----------------------------- |
| `POST` | `/api/v1/chat/completions`     | 必須 | チャット補完。ストリーミングと非ストリーミングに対応します |
| `POST` | `/api/v1/embeddings`           | 必須 | テキストのベクトル化                    |
| `POST` | `/api/v1/audio/transcriptions` | 必須 | 音声認識（音声ファイル全体をアップロードします）      |
| `POST` | `/api/v1/audio/speech`         | 必須 | 音声合成（音声ファイル全体を返します）           |
| `GET`  | `/api/v1/models`               | 任意 | 呼び出し可能なモデル識別子と料金を一覧表示します      |

**Base URL**（OpenAI SDK の `base_url` に指定します）：

```
https://api.maiagent.ai/api/v1
```

SDK が自動的に `/chat/completions`、`/embeddings`、`/audio/transcriptions`、`/audio/speech`、`/models` を末尾に追加します。パスの末尾にスラッシュは**付けないでください**。

## 認証 <a href="#authentication" id="authentication"></a>

推論エンドポイントは Bearer 認証を使用します。OpenAI SDK がデフォルトで送信するヘッダーと同じです：

```
Authorization: Bearer <GATEWAY_API_KEY>
Content-Type: application/json
```

* キーは MaiAgent の API Key ですが、Gateway エンドポイントは `Bearer` プレフィックスのみを受け付けます。MaiAgent の他の API で使用する `Api-Key <金鑰>` 形式では、ここでは `401` が返されます。
* 次の場合はすべて同じ `401 invalid_api_key` が返され、どのチェックで拒否されたかは開示されません：キーが存在しない、失効している、無効化されている、有効期限が切れている、関連付けられたメンバーまたはユーザーが無効化されている、組織で AI Gateway が有効化されていない場合です。
* リクエスト本文は JSON のみを受け付けます。唯一の例外は音声認識で、`multipart/form-data` で音声ファイルをアップロードします（OpenAI SDK が自動処理します）。

### Gateway キーの取得 <a href="#get-api-key" id="get-api-key"></a>

MaiAgent 管理画面で、<mark style="color:blue;">組織設定</mark> → <mark style="color:blue;">API Key 管理</mark> → <mark style="color:blue;">API Key を作成</mark>に進みます。作成ウィザードは、メンバーの選択、有効化と制限、キーの生成の 3 ステップです。

* キーは 1 人のメンバーに関連付けられます。呼び出しはそのメンバーの名義で記録され、メンバーの Credits 利用枠の制限を受けます。
* 「有効化と制限」では、キーで呼び出せるモデル（組織が利用できる範囲内でのみ絞り込めます。デフォルトはすべて有効）、1 分あたりのリクエスト数（RPM）、1 分あたりのトークン数（TPM）を設定できます。
* キー全体が表示されるのは作成時の 1 回だけです。直ちにシークレット管理システムに保存してください。
* 同じメンバーが複数の有効なキーを同時に保持できます。ローテーション時は新しいキーを先に発行し、デプロイ完了後に古いキーを失効させることで、サービスを中断せずに切り替えられます。
* API Key 管理ページを使用するには「API Key 管理権限」が必要です。この権限がないメンバーは、右上のアバター → <mark style="color:blue;">アカウント</mark> → <mark style="color:blue;">API キー</mark>で自分のキーを作成できます（Gateway にも使用できます）。モデルの有効化と RPM／TPM は、管理者が API Key 管理ページで設定します。

管理画面の左メニューの <mark style="color:blue;">AI Gateway</mark> → <mark style="color:blue;">連携サンプル</mark>では、選択したモデルに応じたコピー可能な cURL／Python／Node.js のサンプルが生成されます。呼び出しに失敗した場合は、<mark style="color:blue;">AI Gateway</mark> → <mark style="color:blue;">概要</mark>で<mark style="color:blue;">アクセス診断</mark>を実行し、キー、メンバー、組織、モデルの有効化状態を順に確認できます。AI Gateway メニューを表示するには、ロールに AI Gateway 権限が必要です。設定方法は、ユーザーマニュアルの[特定のロールで AI Gateway を使用できるようにする](https://docs.maiagent.ai/org/role-permission#enable-ai-gateway-for-role)をご覧ください。

## 最小構成のサンプル <a href="#minimal-examples" id="minimal-examples"></a>

キーはコードに直接記述せず、先に環境変数に保存してください：

```bash
export GATEWAY_API_KEY="<GATEWAY_API_KEY>"
```

{% tabs %}
{% tab title="OpenAI Python SDK" %}

```python
import os

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["GATEWAY_API_KEY"],
    base_url="https://api.maiagent.ai/api/v1",
)

resp = client.chat.completions.create(
    model="<vendor>/<model>",  # GET /models で取得した id、またはフォールバックグループの slug
    messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)
```

{% endtab %}

{% tab title="curl" %}

```bash
curl https://api.maiagent.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<vendor>/<model>",
    "messages": [
      { "role": "user", "content": "Hello!" }
    ]
  }'
```

{% endtab %}
{% endtabs %}

## モデル識別子 <a href="#model-ids" id="model-ids"></a>

`model` フィールドには、各ベンダーのネイティブ ID ではなく、**Gateway モデル識別子**を指定します。識別子には必ず `/` が含まれます。`/` がない値は直ちに `400` を返します。

| 呼び出す対象                  | `model` に指定する値                                           | 取得場所                                       |
| ----------------------- | -------------------------------------------------------- | ------------------------------------------ |
| MaiAgent マネージドモデル       | `{vendor}/{model}`（またはプラットフォームで設定したエイリアス）                | `GET /models` が返す `id`                     |
| 組織のカスタムモデル（BYOK／セルフホスト） | システムが生成する Gateway モデル ID。形式は `{供應商 slug}/{模型名}-{隨機碼}` です | 管理画面の AI Gateway → モデルページの「Gateway モデル ID」 |
| フォールバックグループ             | システムが生成するグループ slug。形式は `maiagent/fallbacks-{隨機碼}` です     | 管理画面の AI Gateway → フォールバックモデルグループ          |

解決順序は、プラットフォームのエイリアス、`{vendor}/{model}`、組織のカスタムモデル、フォールバックグループです。プラットフォームモデル（エイリアスと `{vendor}/{model}`）は、「組織が利用可能 ∩ Gateway で有効 ∩ このキーで有効」の範囲内でのみ検索されます。カスタムモデルとフォールバックグループは自分の組織が所有するものに限られ、このキーのアクセス許可リストによる制限を受けます。範囲外のモデルと存在しないモデルは、同じ `404 model_not_found` を返します。

### /models で呼び出し可能なモデルを一覧表示 <a href="#list-models" id="list-models"></a>

```python
for m in client.models.list():
    print(m.id)
```

Gateway キーを付けて呼び出すと、そのキーで実際に呼び出せるモデルのみが一覧に表示されます（組織のブロック設定とキーのアクセス許可リストが適用されます）。認証なしでは、組織によるフィルタリングを行わず、プラットフォームの公開カタログを返します。各項目には OpenAI 標準の `id`、`object`、`created`、`owned_by` に加えて、次のフィールドがあります：

| フィールド                         | 説明                                                                                                                                                                                                 |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                        | 表示名                                                                                                                                                                                                |
| `type`                        | 言語モデルは `language`、音声モデルは `transcription`（音声認識）または `speech`（音声合成）です。フィールドの違いは「音声認識と音声合成」をご覧ください                                                                                                     |
| `tags`                        | 機能タグ：`tool-use`、`multimodal`、`reasoning`、`prompt-caching`、`streaming`。`reasoning` はモデルが `reasoning_effort` を受け付けることを示します。「推論レベル」をご覧ください                                                            |
| `pricing`                     | マネージドモデル：`input`／`output`、単位は `credits_per_1k_tokens` です（Gateway キーを付けて呼び出す場合は組織の Gateway サービス料を含みます。認証なしの公開カタログはサービス料を加算しない基本単価です）。カスタムモデル：`traffic_fee_percent`、単位は `percent_of_total_tokens` です |
| `providers`                   | このモデルを提供できるバックエンドプロバイダーの一覧です。各項目に `slug` があり、下記の `provider.order` で指定できます                                                                                                                          |
| `context_window`、`max_tokens` | 設定されている場合のみ表示されます                                                                                                                                                                                  |

### 組織が中国のモデルを非表示にした場合の連携動作 <a href="#hidden-china-models" id="hidden-china-models"></a>

組織が「中国のモデルを非表示」を有効にすると、プラットフォームに登録されたモデルの原産地に基づき、中国のプラットフォームモデルが除外されます。今後追加されるモデルにも適用されます。この制限は、Gateway のモデルカタログと実際の呼び出しの両方に適用されます：

* **キー付きのカタログ取得**：`GET /models` は非表示のプラットフォームモデルを一覧に含めません。認証なしの公開カタログには組織情報がないため、この制限は適用されません。
* **プラットフォームモデルの直接呼び出し**：非表示のモデルは、エイリアスや `{vendor}/{model}` では呼び出せず、`404 model_not_found` を返します。同じプラットフォームモデルを自分のキーで呼び出しても、組織の非表示設定を回避できません。
* **フォールバックグループの呼び出し**：非表示のプラットフォームモデルを使用するステップを先に除外し、残りのステップを使用します。ステップが残らない場合は `404 model_not_found` を返し、キー付きで取得するカタログにもそのグループは表示されません。
* **組織のカスタムモデル**：組織が作成した Gateway モデルは、この原産地に基づく非表示設定の対象外です。ただし、従来のキーのアクセス許可ルールには従う必要があります。

例えば、企業の連携エンジニアが中国のプラットフォームモデルをデフォルトに設定していた場合、組織が非表示を有効にすると、元の識別子は `404` を返します。エンジニアはサービスが実際に使用するキーで `/models` を再取得し、デフォルトを一覧内の利用可能なモデルに変更してから呼び出しを再開してください。認証なしの公開カタログで、組織にモデルの使用権限があるかどうかを判断しないでください。

{% hint style="info" %}
非表示設定は、既存のモデル別ブロックリストを削除しません。非表示を解除した後も、元の組織の有効化状態とキーのアクセス許可範囲に基づいて判断されます。
{% endhint %}

### バックエンドプロバイダーの指定 <a href="#provider-order" id="provider-order"></a>

同じモデル識別子を複数のプロバイダーが提供している場合があります（例えば、同じモデルが開発元とクラウドプラットフォームの両方で提供されている場合です）。特定のプロバイダーを使用するには、リクエスト本文に `provider.order` を追加し、`/models` が返す `providers[].slug` を指定します：

```python
resp = client.chat.completions.create(
    model="<vendor>/<model>",
    messages=[{"role": "user", "content": "Hello!"}],
    extra_body={"provider": {"order": ["<provider-slug>"]}},
)
```

現在はリストの最初の値のみが使用されます。そのプロバイダーがモデルを提供していない場合は `404 model_not_found` を返します。`provider.order` を指定した場合、フォールバックグループには解決されません。

### 自分のキーの持ち込み（BYOK） <a href="#byok" id="byok"></a>

組織のオーナーは、管理画面の <mark style="color:blue;">AI Gateway</mark> → <mark style="color:blue;">モデルプロバイダー</mark>で、組織独自のプロバイダー認証情報を登録できます。登録後は次のように動作します：

* マネージドモデルを呼び出す際、組織に同じプロバイダーの有効な認証情報があれば、Gateway は組織の認証情報で上流を呼び出します（同じプロバイダーの登録が複数ある場合は、最も最近更新されたものを使用します）。呼び出し側の `model` を変更する必要はありません。
* これらの認証情報で「カスタムモデル」を作成し、システムが生成する Gateway モデル ID で呼び出すこともできます。
* 上流が組織の認証情報を 401／403 で拒否した場合、Gateway は `502 upstream_auth_error` を返します。メッセージには組織の BYOK 認証情報が拒否されたことが示されます。AI Gateway 設定で認証情報を更新してください。

### プロバイダー認証情報の部分更新 <a href="#credential-partial-update" id="credential-partial-update"></a>

連携アプリケーションは `PATCH /api/v1/gateway/credentials/{id}/` で、自分の組織のプロバイダー認証情報を更新できます。この管理インターフェースには、ログイン、組織の AI Gateway 有効化、AI Gateway アクセス権限が必要で、更新者は組織のオーナーである必要があります。認証の用途は、[推論エンドポイント](#authentication)で使用する Gateway Bearer キーとは異なります。

リクエストには `name`、`isActive`、`credentials` を含められます。`credentials` 内では、`apiBase`、`apiKey` などの camelCase フィールド名を使用します。各認証情報フィールドは次のように処理されます：

| 送信する値     | 更新結果                                      |
| --------- | ----------------------------------------- |
| フィールドを省略  | 元の値を保持します                                 |
| 空文字列 `""` | 元の値を保持します。変更なしを意味します                      |
| 空ではない新しい値 | 元の値を置き換え、プロバイダーのルールで検証します                 |
| `null`    | 任意フィールドをクリアします。必須フィールドはクリアできず、`400` を返します |

例えば、vLLM と OpenAI 互換プロバイダーの `apiKey` は `null` でクリアできますが、`apiBase` は必須です。Anthropic の任意フィールド `apiBase` を `null` にすると、認証情報内のカスタムエンドポイントを削除できます。API Key は引き続き必須です。

{% hint style="warning" %}
API Key が既に保存されている場合、`apiBase` を別の空ではないエンドポイントに変更するには、同時に `apiKey` を再入力するか、プロバイダーが許可する場合は明示的に `null` でキーをクリアする必要があります。キーを省略するか空文字列を送信すると、`credentials.apiKey` にエラーが付いた `400` が返され、元の設定は維持されます。名前のみの変更や同じエンドポイントの再送信では、キーの再入力は不要です。
{% endhint %}

取得レスポンスにはマスクされたプレビュー `credentialsPreview` のみが含まれ、元の認証情報は返されません。管理画面の操作方法は[モデルプロバイダー設定](https://docs.maiagent.ai/build/ai-gateway#provider-credentials)をご覧ください。この節では、連携アプリケーション向けの更新の意味のみを説明します。

### フォールバックグループ <a href="#fallback-groups" id="fallback-groups"></a>

フォールバックグループは、組織のオーナーが管理画面で作成する、順序付きのモデルリストです。`model` にグループの slug を指定した場合のみ、フォールバックチェーン全体が有効になります。単一モデルの呼び出しでは自動的に切り替わりません。

* **切り替え条件**（システム固定）：タイムアウト、接続失敗、上流の 408／429／500／502／503／504／529 レスポンスです。パラメーターの誤りや無効なキーなど、リクエスト側のエラーでは切り替えず、そのままエラーを返します。
* **ストリーミング**：Gateway は上流から最初のコンテンツを取得してから応答を開始します。そのため、接続エラーやレート制限が発生した場合、最初のバイトを送信する前に切り替えられます。コンテンツの返却が始まると、それ以降は切り替えません。
* レスポンスの `model` フィールドには、送信したグループの slug が保持されます。実際に処理したモデルやフォールバックの発生有無は、管理画面の使用量とリクエスト記録に保存されます。
* モデルデータが存在しなくなったステップや、組織のカスタムモデルが削除（無効化）されたステップは、呼び出し前にスキップされます。プライマリモデルも、リスト内の最初の呼び出し可能なステップに変更されます。**プラットフォームモデルが無効化されただけの場合、このスキップルールは適用されません**。
* チェーン全体に呼び出し可能なステップがない場合、推論は `400 invalid_request_error` を返し、エラーコードは `fallback_group_unavailable` になります。グループを編集して利用可能なモデルを追加してください。一時的な上流エラーとして再試行しないでください。
* `GET /api/v1/gateway/fallback-groups/{id}/` でグループを取得すると、上記の無効なステップは `modelId: null`、`modelName: ""`、`managedModel: null`、`customModel: null` を返します。管理インターフェースの取得には、ログイン、組織の AI Gateway 有効化、AI Gateway アクセス権限が必要です。取得できるのは、表示可能なプラットフォームグループと自分の組織のグループのみです。
* 組織が所有するフォールバックグループは、呼び出し可能なステップが残っている場合のみ `/models` に表示されます。このルールは、すべてのプラットフォーム仮想モデルがモデルカタログから消えることを意味するものではありません。

## チャット補完のパラメーター <a href="#chat-completions-params" id="chat-completions-params"></a>

`POST /chat/completions` が受け付けるフィールドは次のとおりです：

| フィールド                          | 説明                                                                                                                                                            |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`                        | 必須です。前の節をご覧ください                                                                                                                                               |
| `messages`                     | 必須で、空にはできません。`role` は `system`、`user`、`assistant`、`tool` を指定できます。`content` は文字列、または `text`／`image_url` のマルチモーダル配列です。`tool_calls`、`tool_call_id`、`name` に対応します |
| `stream`                       | デフォルトは `false` です                                                                                                                                             |
| `stream_options.include_usage` | デフォルトは `false` です。「ストリーミング」をご覧ください                                                                                                                            |
| `temperature`                  | 数値です                                                                                                                                                          |
| `max_tokens`                   | 最小値は 1 です                                                                                                                                                     |
| `top_p`                        | 0 から 1 です                                                                                                                                                     |
| `stop`                         | 文字列または文字列の配列です                                                                                                                                                |
| `n`                            | 1 から 8、デフォルトは 1 です                                                                                                                                            |
| `tools`                        | `type: "function"` のみ対応します。関数名は最大 64 文字です                                                                                                                     |
| `tool_choice`                  | `auto`、`none`、`required`、または特定の関数オブジェクトです                                                                                                                     |
| `parallel_tool_calls`          | デフォルトは `true` です                                                                                                                                              |
| `response_format`              | `type` は `text`、`json_object`、`json_schema` です。`json_schema` には `json_schema` オブジェクトが必要です                                                                     |
| `reasoning_effort`             | `none`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max` です。`/models` で `reasoning` タグが付いたモデルにのみ適用されます。「推論レベル」をご覧ください                                             |
| `provider`                     | MaiAgent の拡張フィールドです。「バックエンドプロバイダーの指定」をご覧ください                                                                                                                  |

注意事項：

* 対象モデルが `top_p` または `stop` に対応していない場合、エラーにはならず、そのパラメーターは無視されます。
* `tools` と `response_format: json_schema` は同時に使用できません。使用すると `400` を返します。
* `json_schema` モードでストリーミングする場合、JSON 全体が単一の delta で一度に送信され、文字ごとのストリーミングにはなりません。
* `json_object` モードでは、システムメッセージに「有効な JSON のみを出力してください」という指示が追加されます。
* `json_object` の応答全体が単一の Markdown `json` コードブロックのみで構成され、その内容が有効な JSON である場合、Gateway はコードブロックのマーカーを取り除いて返します。通常の応答とストリーミング応答の両方に適用されます。
* ブロック外に説明文がある場合、ブロック内容が有効な JSON ではない場合、または応答の切り詰めによって完全で有効な JSON ブロックにならない場合、Gateway はモデルの元の応答を保持します。連携側でも JSON を解析し、無効な JSON を処理する必要があります。`json_object` だけで毎回解析可能なオブジェクトを取得できるとは限りません。
* ストリーミングの `json_object` 応答がバッククォートで始まる場合、Gateway は応答全体が終了するまで待ってから内容を送信します。他の応答は通常どおり順次送信されます。上流が途中で失敗した場合、受信済みで未送信の内容をそのまま送信してから、エラーを報告します。

レスポンスは標準の `chat.completion` オブジェクトです。`id` は `chatcmpl-...` 形式で、`model` は送信した識別子を返します。レスポンスヘッダーの `x-request-id` は `id` と同じです。問題を報告する際は添付してください。

### 推論レベル（reasoning\_effort） <a href="#reasoning-effort" id="reasoning-effort"></a>

`reasoning_effort` は、プロバイダー共通のレベルで、モデルがどの程度深く推論するかを指定します。弱い順に次のとおりです：

`none` < `minimal` < `low` < `medium` < `high` < `xhigh` < `max`

* **指定可能な値**：上記の 7 つの値または `null` のみを受け付けます。それ以外の値（`off` や数値のトークン予算を含みます）は `400 invalid_request` を返します。`none` は推論を無効にします。
* **省略または `null`**：Gateway はレベルを指定しません。プラットフォームにそのモデルのデフォルト推論レベルが設定されている場合は、それを使用します。それ以外は推論パラメーターを送信せず、プロバイダーのデフォルトに従います。例外として、一部の OpenAI モデル（GPT-5.6 シリーズなど）はレベルを指定しないとツール定義を受け付けないため、プラットフォームはこれらのモデルに `none` を送信します。
* **モデルに `reasoning` タグがない場合**：モデルに推論制御がないため、`reasoning_effort` は無視され、エラーにはなりません。
* **変換方法**：まず対象モデルが対応するレベルにマッピングし、次にプロバイダーのネイティブパラメーター（OpenAI の `reasoning_effort`、Claude の effort や推論トークン予算、Gemini の思考予算など）に変換します。モデルが対応するレベルは、プラットフォームがモデルファミリーごとに管理します。現在 `/models` は `reasoning` タグのみを提供し、各モデルの対応レベルは一覧表示しません。

モデルが指定したレベルに対応していない場合、Gateway はエラーを返さず、次のルールで調整します：

| 状況                              | 実際に送信する値                                                                                      |
| ------------------------------- | --------------------------------------------------------------------------------------------- |
| モデルがそのレベルに対応しています               | そのまま送信します                                                                                     |
| 対応していませんが、より弱いレベルがあります          | 要求より強くない最も近いレベルを使用します（例えばモデルの上限が `high` の場合、`max` を指定しても `high` が送信されます）。調整によって料金が上がることはありません |
| 要求したレベルがモデルの最低レベルを下回ります         | モデルの最低レベルを使用します                                                                               |
| 推論を要求しています（`none` 以外）           | 無効には調整されません                                                                                   |
| `none` を指定しましたが、モデルが推論を無効にできません | 推論パラメーターを送信せず、プロバイダーのデフォルトに従います。このようなモデルは引き続き推論し、実際のトークン数で課金されます                              |

{% hint style="info" %}
同じレベルでも、モデルによって実際の推論量は異なります。モデルを変更する際は、レイテンシとトークン使用量を再評価してください。同じレベルで料金も同じになるとは考えないでください。
{% endhint %}

## ストリーミング <a href="#streaming" id="streaming"></a>

`stream: true` の場合、レスポンスは Server-Sent Events（`Content-Type: text/event-stream`）になります。各イベントは `data: {chat.completion.chunk JSON}` の 1 行で、正常終了時は `data: [DONE]` で終わります。OpenAI SDK でそのまま反復処理できます：

```python
stream = client.chat.completions.create(
    model="<vendor>/<model>",
    messages=[{"role": "user", "content": "Hello!"}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
```

* `include_usage: true` の場合、最後に `choices` が空配列で `usage` を含むイベントが追加されます。このオプションは使用量を返すかどうかのみを制御し、課金には影響しません。有効かどうかにかかわらず、Gateway は使用量を記録して課金します。
* ストリーミング開始前のエラー（認証、利用枠、モデルが存在しない、上流への接続失敗）は、SSE ではなく通常の HTTP エラーとして返されます。
* ストリーミング中に上流でエラーが発生した場合、HTTP ステータスは既に `200` です。Gateway は `data: {"error": {...}}` イベントを送信して終了し、`[DONE]` は送信しません。クライアントでこのイベントを処理してください。

## ベクトル化 <a href="#embeddings" id="embeddings"></a>

`POST /embeddings` は OpenAI と同じように使用できます：

```python
emb = client.embeddings.create(
    model="<embedding-model>",
    input=["最初のテキスト", "2 番目のテキスト"],
)
print(len(emb.data), len(emb.data[0].embedding))
```

* `input`：空ではない文字列、または空ではない文字列の配列です。
* `encoding_format`：`float`（デフォルト）または `base64` です。
* `model`：プラットフォームで Gateway に対して有効化されたベクトルモデルの識別子に照合し、その次に名前に照合します。ベクトルモデルは `/models` の一覧には含まれず、API Key のモデルアクセス許可リストの制限も受けません。利用可能なベクトルモデル識別子は MaiAgent に確認してください。
* `usage.prompt_tokens` は Gateway が `cl100k_base` トークナイザーで推定します。この数値が課金の基準にもなります。

## 音声認識と音声合成 <a href="#ai-gateway-audio" id="ai-gateway-audio"></a>

Gateway は OpenAI 互換の音声エンドポイントを 2 つ提供します。OpenAI SDK の `client.audio.transcriptions.create()` と `client.audio.speech.create()` は、`base_url` と `api_key` を変更するだけで呼び出せます。どちらも同期呼び出しです。音声ファイル全体をアップロードして文字起こしを取得するか、テキストを送信して音声ファイル全体を取得します。ストリーミングには対応していません。

### 利用可能な音声モデル <a href="#audio-models" id="audio-models"></a>

音声モデルは MaiAgent プラットフォームが管理し、常にプラットフォームのプロバイダー認証情報を使用します。BYOK とカスタムモデルには対応していません。現在の公開カタログには次のモデルが表示されますが、実際に呼び出せるモデルはキー付きの `GET /models` の結果に従ってください：

| `model`                  | `type`          | 用途                                                                                                           |
| ------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------ |
| `openai/gpt-transcribe`  | `transcription` | 音声認識                                                                                                         |
| `azure/speech-to-text`   | `transcription` | 音声認識                                                                                                         |
| `openai/gpt-4o-mini-tts` | `speech`        | 音声合成。音声：`alloy`、`ash`、`ballad`、`coral`、`echo`、`fable`、`onyx`、`nova`、`sage`、`shimmer`、`verse`、`marin`、`cedar` |

`/models` における音声モデルのフィールドは、言語モデルとは異なります：

* `tags` は空配列で、`providers`、`context_window`、`max_tokens` はありません。
* `pricing` は `{"price": "…", "unit": "…", "currency": "credits"}` です。`unit` は `credits_per_second`（音声認識、1 秒あたり）または `credits_per_1k_characters`（音声合成、1,000 文字あたり）です。Gateway キー付きで呼び出す場合は組織の Gateway サービス料を含みます。認証なしの公開カタログは基本単価です。
* `speech` モデルには、`voices`（利用可能な音声）と `response_formats`（利用可能な音声ファイル形式。最初の項目がデフォルトです）もあります。

{% hint style="warning" %}
**呼び出せるモデルを制限したキーでは、音声モデルを使用できません。** API Key のモデルアクセス許可リストでは、現在は言語モデルのみを選択できます。キーにアクセス許可リストが設定されていると、`/models` に音声モデルが表示されず、音声エンドポイントの呼び出しは `404 model_not_found` を返します。音声を使用するには、モデルアクセス許可リストが設定されていないキーを使用してください。
{% endhint %}

文字数課金プランの組織は、音声エンドポイントを使用できません。呼び出しは `403`（`type` は `permission_error`、`code` は `billing_mode_not_supported`）を返し、キー付きの `/models` にも音声モデルは表示されません。

### 音声認識 <a href="#audio-transcriptions" id="audio-transcriptions"></a>

`POST /audio/transcriptions` の本文は `multipart/form-data` です：

```python
with open("meeting.mp3", "rb") as f:
    result = client.audio.transcriptions.create(
        model="openai/gpt-transcribe",
        file=f,
        language="zh",
    )
print(result.text)
```

| フィールド             | 必須  | 説明                                                                                                                 |
| ----------------- | --- | ------------------------------------------------------------------------------------------------------------------ |
| `file`            | はい  | 音声ファイルです。上限は 25 MB（25 × 1024 × 1024 bytes）です。形式はファイル名の拡張子で判定し、`mp3`、`mp4`、`mpeg`、`mpga`、`m4a`、`wav`、`webm` を受け付けます |
| `model`           | はい  | `type` が `transcription` のモデル識別子です                                                                                 |
| `language`        | いいえ | 音声ファイルの言語です。省略するとモデルが自動判定します。ルールは下記をご覧ください                                                                         |
| `prompt`          | いいえ | 文字起こしのヒントです。OpenAI モデルにのみ送信します                                                                                     |
| `temperature`     | いいえ | `0` から `1` です。OpenAI モデルにのみ送信します                                                                                   |
| `response_format` | いいえ | `json`（デフォルト）または `text` です。他の値は `400` を返します                                                                        |
| `stream`          | いいえ | `false` のみを受け付けます。`true` を送信すると `400` を返します                                                                        |

`language` の処理方法はモデルによって異なります：

* **`openai/gpt-transcribe`**：ISO-639-1 の2文字コード（例：`zh`、`en`）を使用します。完全なロケール（例：`zh-TW`）を指定した場合は、`-` より前の言語コードのみを使用します。
* **`azure/speech-to-text`**：2文字コード `zh`、`en`、`ja`、`ko`、`th`、`vi`、`id`、`ms`、`fr`、`de`、`es`、`it`、`pt`、`ru`、`hi`（対応するロケールに変換されます。例：`zh` → `zh-TW`）、または完全なロケール（例：`zh-TW`）を直接指定できます。それ以外の2文字コードには `400` を返します。省略すると、`zh-TW` と `en-US` の間で自動判定します。

レスポンス：

* `response_format: json`：`Content-Type: application/json` となり、`usage.seconds` は今回の請求対象の秒数です。

  ```json
  {"text": "文字起こしの内容", "usage": {"type": "duration", "seconds": 6}}
  ```
* `response_format: text`：`Content-Type: text/plain; charset=utf-8` となり、本文には文字起こしの内容が入ります。

### 音声合成 <a href="#audio-speech" id="audio-speech"></a>

`POST /audio/speech` を使用し、本文は JSON です：

```python
response = client.audio.speech.create(
    model="openai/gpt-4o-mini-tts",
    voice="alloy",
    input="MaiAgent へようこそ。",
    response_format="mp3",
)
response.write_to_file("welcome.mp3")
```

| フィールド             | 必須  | 説明                                                                                |
| ----------------- | --- | --------------------------------------------------------------------------------- |
| `model`           | はい  | `type` が `speech` のモデル識別子です                                                       |
| `input`           | はい  | 合成するテキストです。空にはできません。上限は 4,096 文字です                                                |
| `voice`           | はい  | モデルの `voices` に含まれる値である必要があります。未対応の値には `400` を返し、利用可能な値を一覧表示します                   |
| `response_format` | いいえ | モデルの `response_formats` に含まれる値（現在は `mp3`、`wav`）である必要があります。省略すると、そのモデルの最初の形式を使用します |
| `speed`           | いいえ | 話す速度です。現在掲載されている OpenAI モデルでは `0.25`–`4.0` に対応し、範囲外の値には `400` を返します               |
| `instructions`    | いいえ | 話し方の指示です。OpenAI モデルのみが対応しています。他のモデルに送信すると `400` を返します                             |
| `stream_format`   | いいえ | `audio` のみを受け付けます。SSE ストリーミングには対応していません                                           |

レスポンス本文は完全な音声ファイルで、`Content-Type` は `audio/mpeg`（`mp3`）または `audio/wav`（`wav`）です。

### 音声エンドポイントの共通動作 <a href="#audio-behavior" id="audio-behavior"></a>

* **レスポンスヘッダー**：成功時のレスポンスと、フィールド検証を通過した後に発生したエラーには、`x-request-id` が含まれます。問題を報告する際は、この値を添付してください。
* **`Accept` ヘッダー**：Gateway は `Accept` に基づく形式のネゴシエーションを行いません。OpenAI SDK がデフォルトで送信する `Accept: application/octet-stream` はエラーの原因になりません。
* **プロバイダー呼び出し前の検証**：認証、フィールド検証、モデル、音声／形式／速度／言語などのパラメーター、課金プラン、Credits は、すべてプロバイダーを呼び出す前に検証します。いずれかの検証でリクエストが拒否された場合、Credits は消費されません。
* **上流のタイムアウト**：音声文字起こしは 300 秒、音声合成は 120 秒です。Gateway は自動再試行しません。
* **上流のエラー**：プロバイダーが 400／413／415／422 で拒否した場合は `400 upstream_invalid_request`、プラットフォームの認証情報を拒否した場合は `502 upstream_auth_error`、タイムアウトやその他のエラーでは `502 upstream_error` を返します。いずれの場合もプロバイダーの元のエラーメッセージは返さず、Credits も消費されません。
* **エラー形式**：他の Gateway エンドポイントと同じです。「エラー形式」を参照してください。

## エラー形式 <a href="#errors" id="errors"></a>

すべてのエラーは OpenAI 形式で、OpenAI SDK が対応する例外に変換します：

```json
{
  "error": {
    "message": "Model 'vendor/model' not found or not enabled",
    "type": "invalid_request_error",
    "code": "model_not_found",
    "param": null
  }
}
```

| HTTP | `type`                  | `code`                       | よくある原因                                                              | 推奨される対処                                               |
| ---- | ----------------------- | ---------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------- |
| 400  | `invalid_request_error` | `invalid_request`            | フィールド検証の失敗、`model` に `/` がない、`tools` と `json_schema` の併用です          | リクエストを修正し、再試行はしないでください                                |
| 400  | `invalid_request_error` | `upstream_invalid_request`   | 上流が 400／413／415／422 でリクエストを拒否しました（パラメーター、ツール定義、入力サイズがモデルの制限を超えています） | 対象モデルの制限に合わせてリクエストを調整してください                           |
| 400  | `invalid_request_error` | `fallback_group_unavailable` | フォールバックグループに呼び出し可能なステップがありません                                       | グループを編集し、利用可能なモデルを追加してください                            |
| 401  | `authentication_error`  | `invalid_api_key`            | キーが無効、無効化済み、有効期限切れ、失効済み、または組織で Gateway が有効になっていません                  | キーを確認し、管理画面のアクセス診断で原因を特定してください                        |
| 402  | `billing_error`         | `insufficient_credits`       | 組織の Credits 不足、またはメンバー／グループの利用枠を使い切っています。上流呼び出し前に拒否されます             | Credits をチャージするか、利用枠を調整してください                         |
| 403  | `permission_error`      | `billing_mode_not_supported` | 文字数課金プランの組織が音声エンドポイントを呼び出しました                                       | Credits 課金プランに変更してください                                |
| 404  | `invalid_request_error` | `model_not_found`            | モデルが存在しない、組織に公開されていない、このキーで有効になっていない、または指定したプロバイダーがそのモデルを提供していません   | `/models` で利用可能な ID を確認してください                         |
| 429  | `rate_limit_error`      | `rate_limit_exceeded`        | キーの RPM または TPM 制限を超えています                                           | バックオフして再試行してください                                      |
| 502  | `server_error`          | `upstream_auth_error`        | 上流が認証情報（BYOK またはプラットフォームの認証情報）を拒否しました                               | BYOK：認証情報を更新してください。プラットフォームの認証情報：MaiAgent にお問い合わせください |
| 502  | `server_error`          | `upstream_error`             | 上流のタイムアウト、レート制限、5xx、その他のエラーです。上流の元のエラーメッセージは返しません                   | バックオフして再試行するか、フォールバックグループを使用してください                    |

## 使用量と Credits 課金 <a href="#billing" id="billing"></a>

呼び出しが成功するたびに組織の Credits を消費します。チャット補完は上流が報告するトークン数、埋め込みは Gateway が推定するトークン数に基づきます（「埋め込み」を参照してください）：

* **マネージドモデル**：モデルの入力／出力トークン単価（プロンプトキャッシュを含みます）で計算し、組織の Gateway サービス手数料率を加算します。Gateway キーで `/models` を呼び出す場合、`pricing` はすでにサービス手数料を加算した単価です。認証なしの公開カタログには、サービス手数料を加算する前の基本単価を表示します。
* **セルフホストモデルと BYOK 認証情報**：上流の費用はお客様の会社がプロバイダーに直接支払います。MaiAgent はトラフィック料金のみを請求し、呼び出しの合計トークン数（入力＋出力＋プロンプトキャッシュの書き込みと読み取り）× 組織のトラフィック単価で計算します。LLM トークン単価による料金は請求しません。ユーザーマニュアルの [AI Gateway セルフホストモデルのトラフィック料金](https://docs.maiagent.ai/org/credits#ai-gateway-traffic-fee) で、管理画面での確認方法を説明しています。
* **埋め込み**：入力トークン数に基づいて課金し、Gateway サービス手数料を加算します。
* **音声文字起こし**：プロバイダーが報告する音声の長さを整数秒に切り上げ、最小 1 秒として、モデルの1秒あたりの単価を掛け、Gateway サービス手数料を加算します。レスポンスの `usage.seconds` が請求対象の秒数です。プロバイダーが長さを報告しない場合、リクエスト全体が `502` で失敗し、文字起こしの内容は返さず、Credits も消費されません。
* **音声合成**：`input` の文字数 ÷ 1000 × モデルの1,000文字あたりの単価で計算し、Gateway サービス手数料を加算します。
* **音声呼び出しの利用枠チェック**：プロバイダーを呼び出す前に、組織の Credits が最低費用を支払える必要があります（音声文字起こしは 1 秒分、音声合成は今回の `input` の全額で計算します）。不足している場合は `402` を返します。音声呼び出しの失敗では Credits を消費しません。音声モデルはプラットフォームの認証情報を使用し、トラフィック料金は発生しません。
* **ストリーミングの中断**：クライアントが途中で切断した場合や、上流で途中にエラーが発生した場合も、すでに生成されたトークンは課金対象です。
* 組織の Credits が不足している場合やメンバーの利用枠を使い切っている場合、上流を呼び出す前に `402` を返します。

管理画面の <mark style="color:blue;">AI Gateway</mark> → <mark style="color:blue;">概要</mark> で、モデル、プロバイダー、API Key ごとの使用量を確認できます。Credits 消費の明細は Credits 消費記録で確認できます。

## 制限 <a href="#limits" id="limits"></a>

* **RPM**：キーの1分あたりの最大リクエスト数は、Gateway だけでなく、このキーで呼び出せるすべての MaiAgent API に適用されます。
* **TPM**：1分あたりの最大トークン数は、Gateway のチャット補完と埋め込みにのみ適用され、音声エンドポイントには適用されません（音声エンドポイントには RPM 制限が適用されます）。トークン数は上流のレスポンス後に判明するため、単一のリクエストでその分の制限を一度超えることがあります。その後、同じ分のリクエストはすべて `429` を返し、次の分にリセットされます。
* RPM／TPM を設定していない場合、レート制限はありません。
* 現在提供している OpenAI 互換エンドポイントは、上の表にある5つのみです。OpenAI の Responses、Assistants、画像などのエンドポイント、および音声翻訳（`/audio/translations`）とリアルタイム音声は、Gateway の対象外です。

## 関連ドキュメント <a href="#related" id="related"></a>

* [AI Gateway のセキュリティ](/tech/ja/ai-gateway/ai-gateway-security.md)：エンドポイントの取得元、モデルのチェック、データ保護、監査ログです
* [クイックスタート](/tech/ja/api-integration/quickstart.md)：MaiAgent プラットフォーム API（Agent、会話、ナレッジベース）の認証方法です
* ユーザーマニュアル [Credits](https://docs.maiagent.ai/org/credits)：Credits 残高、課金方法、消費記録です


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/tech/ja/ai-gateway/ai-gateway-openai-compatible.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
