目次

APIリファレンス

はじめに

DMM AI Routerは、さまざまなLLMを1つのAPIキーと共通のリクエスト形式で呼び出せるREST APIを提供します。すべてのリクエストはJSONで送り、応答はJSON(ストリーミング時はServer-Sent Events)で返ります。提供するエンドポイントは、呼び出せるモデルの一覧を返すGET /v1/modelsと、会話形式でテキストを生成するPOST /v1/chat/completionsの2つです。EmbeddingsやResponses API、画像・音声の入出力は提供していません。

1つのモデルに複数の供給元(provider)の経路があるとき、最も安い経路から順に試します。障害のほか、レート制限や負荷の集中で一時的に利用できないときも、次の経路に切り替えます。どの供給元が応答したかは、レスポンスのprovider項目で確認できます。

供給元のフォールバックあなたのアプリ"provider": "b"DMM AI Router最も安い経路から順に試す1. 最初の経路供給元A(最安)一時的に利用不可2. 次の経路供給元B応答
ベースURL
https://api.airouter.dmm.com/v1
curl https://api.airouter.dmm.com/v1/chat/completions \
  -H "Authorization: Bearer $AIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "google/gemini-2.5-flash", "messages": [{"role": "user", "content": "Hello!"}]}'

認証

APIキーをAuthorization: Bearerヘッダで渡します。キーはダッシュボードの「APIキー」で発行し、利用料はキーが属するワークスペースの残高から精算します。用途ごとに複数のキーを作れます。失効したキーは即座に使えなくなり、元に戻せません。

キーごとに1か月あたりの利用額の上限を設定できます。上限に達すると、そのキーからのリクエストは402(monthly_limit_exceeded)になります。集計は毎月1日0:00 UTC(日本時間9:00)にリセットされます。

  • キーはサーバー側だけで使い、ブラウザやモバイルアプリに埋め込まないでください。
  • ソースコードにキーを書かず、環境変数やシークレット管理の仕組みから読み込んでください。
HTTP
POST /v1/chat/completions HTTP/1.1
Host: api.airouter.dmm.com
Authorization: Bearer sk-air-...
Content-Type: application/json
Shell
curl https://api.airouter.dmm.com/v1/models \
  -H "Authorization: Bearer $AIROUTER_API_KEY"

Models

GET/v1/models

現在呼び出せるモデルの一覧を返します。idがそのままmodelに指定する値、owned_byはモデルの開発元です。

各モデルのコンテキスト長・最大出力・単価・データ保持方針はモデル一覧で確認できます。単価は最も安い経路のもので、利用料は実際に応答した経路の単価で精算します。

レスポンス

modelオブジェクトの一覧。

一覧オブジェクト

  • objectstring

    常にlist

    取りうる値:list
  • dataarray

    モデルの配列

    4個の子の項目を表示
    • idstring

      公開モデルID。modelに指定する値

    • objectstring

      常にmodel

      取りうる値:model
    • createdinteger

      登録時刻(UNIX秒)

    • owned_bystring

      モデルの開発元

リクエスト
curl https://api.airouter.dmm.com/v1/models \
  -H "Authorization: Bearer $AIROUTER_API_KEY"
レスポンスJSON
{
  "object": "list",
  "data": [
    {
      "id": "google/gemini-2.5-flash",
      "object": "model",
      "created": 1759363200,
      "owned_by": "google"
    },
    {
      "id": "deepseek/deepseek-v4-pro",
      "object": "model",
      "created": 1759363200,
      "owned_by": "deepseek"
    }
  ]
}

Chat Completions

POST/v1/chat/completions

会話からモデルの応答を生成します。streamがtrueのときはchat.completion.chunkの列をServer-Sent Eventsで返します。

temperatureやreasoning_effortなどの生成パラメータは、供給元とモデルごとにベストエフォートで適用されます。

リクエスト本文

  • modelstring必須

    公開モデルID。GET /v1/modelsのidと同じ

  • messagesarray必須

    会話の履歴。古い順に並べた1件以上の配列。JSONにして2,000,000文字まで

    6個の子の項目を表示
    • rolestring必須

      発言者の役割

      取りうる値:systemuserassistanttool
    • contentstring | array | null必須

      本文。文字列か、typeがtextのパートの配列。assistantでツール呼び出しだけを返した発言ではnull可

    • namestring

      発言者の識別名

      対象: system, user, assistant

    • tool_callsarray

      モデルが返したツール呼び出しをそのまま入れる

      対象: assistant

      3個の子の項目を表示
      • idstring必須

        呼び出しのID。toolメッセージのtool_call_idと対応

      • typestring必須

        常にfunction

        取りうる値:function
      • functionobject必須

        呼び出す関数

        2個の子の項目を表示
        • namestring必須

          関数名

        • argumentsstring必須

          引数のJSON文字列。モデルが出した値をそのまま渡す

    • refusalstring | null

      モデルが生成を拒否したときの文

      対象: assistant

    • tool_call_idstring必須

      応答先のツール呼び出しのid

      対象: tool

  • streamboolean既定: false

    trueでServer-Sent Eventsによる逐次応答

  • stream_optionsobject

    ストリーミングの追加設定。streamがtrueのときだけ指定可

    1個の子の項目を表示
    • include_usageboolean

      usageイベントは指定に関わらず常に送るため、結果は変わらない

  • max_completion_tokensinteger

    生成する出力トークンの上限

  • max_tokensinteger

    max_completion_tokensと同じ意味の旧名。どちらか一方だけ指定可

  • reasoning_effortstring

    推論の労力。取りうる値と効果はモデルによる

  • temperaturenumber

    出力のランダムさ。0から2

  • top_pnumber

    nucleusサンプリングの確率質量。0から1

  • seedinteger

    決定的な出力を得るための乱数シード。保証はモデルによる

  • presence_penaltynumber

    既出トークンへのペナルティ。-2から2

  • frequency_penaltynumber

    出現頻度に応じたペナルティ。-2から2

  • response_formatobject

    応答の形式。省略時は制限しない

    2個の子の項目を表示
    • typestring必須

      形式の種類

      取りうる値:textjson_objectjson_schema
    • json_schemaobject

      typeがjson_schemaのとき必須

      4個の子の項目を表示
      • namestring必須

        スキーマの名前。英数字・_・-で1から64文字

      • descriptionstring

        スキーマの説明

      • schemaobject必須

        JSON Schemaオブジェクト

      • strictboolean

        trueでスキーマへの厳密な準拠を要求

  • toolsarray

    モデルが呼び出せる関数の一覧

    2個の子の項目を表示
    • typestring必須

      常にfunction

      取りうる値:function
    • functionobject必須

      関数の定義

      4個の子の項目を表示
      • namestring必須

        関数名

      • descriptionstring

        関数の説明。モデルが呼ぶかどうかを判断する材料

      • parametersobject

        引数のJSON Schema

      • strictboolean

        trueで引数のスキーマへの厳密な準拠を要求

  • tool_choicestring | object既定: auto

    ツール呼び出しの制御。none・auto・requiredの文字列か、関数を指定するオブジェクト(typeがfunction、function.nameに関数名)

  • parallel_tool_callsboolean

    falseで1回の応答のツール呼び出しを1つに制限するよう要求

上限

  • リクエスト本文は10 MiBまで。超えると413(payload_too_large)を返します。
  • messages全体はJSONにして2,000,000文字まで。超えると400を返します。

レスポンス

chat.completionオブジェクト。idは応答ヘッダx-request-idと同じ値です。

利用料はprompt_tokensとcompletion_tokensにモデルの単価を掛けた額で、ワークスペースの残高から精算します。居住国が日本の場合は消費税を加えます。

レスポンスオブジェクト

  • idstring

    受付ID。応答ヘッダx-request-idと同じ値

  • objectstring

    常にchat.completion

    取りうる値:chat.completion
  • createdinteger

    作成時刻(UNIX秒)

  • modelstring

    応答した公開モデルID

  • providerstring

    応答した供給元のID

  • choicesarray

    生成結果。常に1件

    3個の子の項目を表示
    • indexinteger

      候補の番号。常に0

    • messageobject

      モデルの応答

      4個の子の項目を表示
      • rolestring

        常にassistant

        取りうる値:assistant
      • contentstring | null

        本文。ツール呼び出しだけのときはnull

      • refusalstring | null

        生成を拒否したときの文。通常はnull

      • tool_callsarray

        モデルが要求したツール呼び出し。無いときは項目ごと省く

        3個の子の項目を表示
        • idstring必須

          呼び出しのID。toolメッセージのtool_call_idと対応

        • typestring必須

          常にfunction

          取りうる値:function
        • functionobject必須

          呼び出す関数

          2個の子の項目を表示
          • namestring必須

            関数名

          • argumentsstring必須

            引数のJSON文字列。モデルが出した値をそのまま渡す

    • finish_reasonstring

      生成が終わった理由

      取りうる値:stoplengthtool_callscontent_filter
  • usageobject

    トークン使用量

    5個の子の項目を表示
    • prompt_tokensinteger

      入力トークン数

    • completion_tokensinteger

      出力トークン数

    • total_tokensinteger

      合計

    • prompt_tokens_detailsobject

      入力の内訳。供給元が返したときだけ含まれる

    • completion_tokens_detailsobject

      出力の内訳。供給元が返したときだけ含まれる

リクエスト
curl https://api.airouter.dmm.com/v1/chat/completions \
  -H "Authorization: Bearer $AIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Hello!"}
    ]
  }'
レスポンスJSON
{
  "id": "01K72W3M9Q4ZJ8N2T6VY5XH0RB",
  "object": "chat.completion",
  "created": 1759968000,
  "model": "google/gemini-2.5-flash",
  "provider": "edensoft",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello! How can I help you today?",
        "refusal": null
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 17,
    "completion_tokens": 9,
    "total_tokens": 26
  }
}

ストリーミング

streamをtrueにするとtext/event-streamで返ります。各イベントはdata: に続くJSONです。

イベントの順序

  1. 本文を少しずつ運ぶチャンク。choices[0].deltaに差分が入り、生成が進むたびに届きます
  2. 最後のチャンク。usageにトークン数が入ります
  3. data: [DONE]。ストリームの終わりです

各チャンクのchoices[0].deltaには差分だけが入ります。contentを順に連結すると本文になります。ツール呼び出しはtool_calls[].indexが同じ断片をつなぎ、function.argumentsは連結してからJSONとして解釈します。

チャンクオブジェクト

  • idstring

    受付ID。応答ヘッダx-request-idと同じ値

  • objectstring

    常にchat.completion.chunk

    取りうる値:chat.completion.chunk
  • createdinteger

    作成時刻(UNIX秒)

  • modelstring

    応答した公開モデルID

  • providerstring

    応答した供給元のID

  • choicesarray

    差分

    3個の子の項目を表示
    • indexinteger

      候補の番号。常に0

    • deltaobject

      前のチャンクからの差分

      4個の子の項目を表示
      • rolestring

        最初のチャンクにだけassistant

      • contentstring | null

        本文の断片

      • refusalstring | null

        拒否文の断片

      • tool_callsarray

        ツール呼び出しの断片。indexが同じものをつなぐ

        4個の子の項目を表示
        • indexinteger必須

          呼び出しの番号

        • idstring

          最初の断片にだけ

        • typestring

          最初の断片にだけfunction

        • functionobject

          関数の断片

          2個の子の項目を表示
          • namestring

            最初の断片にだけ

          • argumentsstring

            引数JSON文字列の断片

    • finish_reasonstring | null

      途中はnull。最後の本文チャンクで確定。開始後に失敗したときはerror

      取りうる値:stoplengthtool_callscontent_filtererror
  • usageobject

    終端直前のusageイベントにだけ

    5個の子の項目を表示
    • prompt_tokensinteger

      入力トークン数

    • completion_tokensinteger

      出力トークン数

    • total_tokensinteger

      合計

    • prompt_tokens_detailsobject

      入力の内訳。供給元が返したときだけ含まれる

    • completion_tokens_detailsobject

      出力の内訳。供給元が返したときだけ含まれる

  • errorobject

    開始後に失敗したときの終端イベントにだけ。形はエラー応答のerrorと同じ

    3個の子の項目を表示
    • messagestring

      エラーの説明

    • codestring

      分岐に使う安定した識別子

    • paramstring | null

      入力が原因のときの場所(ドット区切り、配列は添字付き)。それ以外はnull

リクエスト
curl https://api.airouter.dmm.com/v1/chat/completions \
  -H "Authorization: Bearer $AIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true
  }'
ストリームSSE
data: {"id":"01K72W3M9Q4ZJ8N2T6VY5XH0RB","object":"chat.completion.chunk","created":1759968000,"model":"google/gemini-2.5-flash","provider":"edensoft","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"01K72W3M9Q4ZJ8N2T6VY5XH0RB","object":"chat.completion.chunk","created":1759968000,"model":"google/gemini-2.5-flash","provider":"edensoft","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"id":"01K72W3M9Q4ZJ8N2T6VY5XH0RB","object":"chat.completion.chunk","created":1759968000,"model":"google/gemini-2.5-flash","provider":"edensoft","choices":[{"index":0,"delta":{"content":"! How can I help you today?"},"finish_reason":"stop"}]}

data: {"id":"01K72W3M9Q4ZJ8N2T6VY5XH0RB","object":"chat.completion.chunk","created":1759968000,"model":"google/gemini-2.5-flash","provider":"edensoft","choices":[{"index":0,"delta":{},"finish_reason":null}],"usage":{"prompt_tokens":17,"completion_tokens":9,"total_tokens":26}}

data: [DONE]
チャンクオブジェクトJSON
{
  "id": "01K72W3M9Q4ZJ8N2T6VY5XH0RB",
  "object": "chat.completion.chunk",
  "created": 1759968000,
  "model": "google/gemini-2.5-flash",
  "provider": "edensoft",
  "choices": [
    {
      "index": 0,
      "delta": {"content": "Hello"},
      "finish_reason": null
    }
  ]
}

ツール呼び出し

モデルに関数の定義を渡し、呼び出しの指示を受け取って、結果を返す往復を行います。

  1. toolsに関数の名前・説明・引数のJSON Schemaを渡してリクエストします。
  2. モデルが呼び出しを決めると、finish_reasonがtool_callsになり、message.tool_callsに呼び出す関数と引数(JSON文字列)が入ります。
  3. 関数をあなたのコードで実行し、tool_callsを含むassistantメッセージの直後に、roleがtool、tool_call_idが呼び出しのidのメッセージを追加して再度リクエストします。
  4. モデルが結果を踏まえた最終的な応答を返します。
リクエスト
curl https://api.airouter.dmm.com/v1/chat/completions \
  -H "Authorization: Bearer $AIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [{"role": "user", "content": "What is the weather in Tokyo?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {"type": "string", "description": "City name"}
          },
          "required": ["city"]
        }
      }
    }],
    "tool_choice": "auto"
  }'
レスポンスJSON
{
  "id": "01K72W3M9Q4ZJ8N2T6VY5XH0RB",
  "object": "chat.completion",
  "created": 1759968000,
  "model": "google/gemini-2.5-flash",
  "provider": "edensoft",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "refusal": null,
        "tool_calls": [
          {
            "id": "call_7Yq3",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\": \"Tokyo\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 58,
    "completion_tokens": 14,
    "total_tokens": 72
  }
}
結果を返すリクエスト
curl https://api.airouter.dmm.com/v1/chat/completions \
  -H "Authorization: Bearer $AIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [
      {"role": "user", "content": "What is the weather in Tokyo?"},
      {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_7Yq3",
            "type": "function",
            "function": {"name": "get_weather", "arguments": "{\"city\": \"Tokyo\"}"}
          }
        ]
      },
      {
        "role": "tool",
        "tool_call_id": "call_7Yq3",
        "content": "{\"temperature_c\": 24, \"condition\": \"sunny\"}"
      }
    ],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {"type": "string", "description": "City name"}
          },
          "required": ["city"]
        }
      }
    }]
  }'
ストリーミングでの受け取りPython
calls = {}
for chunk in stream:
    choice = chunk.choices[0]
    for part in choice.delta.tool_calls or []:
        call = calls.setdefault(part.index, {"id": None, "name": None, "arguments": ""})
        if part.id:
            call["id"] = part.id
        if part.function and part.function.name:
            call["name"] = part.function.name
        if part.function and part.function.arguments:
            call["arguments"] += part.function.arguments
    if choice.finish_reason == "tool_calls":
        break
# calls[index]["arguments"] is now a complete JSON string

構造化出力

response_formatで応答をJSONに限定できます。json_schemaはスキーマに従ったJSONを、json_objectは任意のJSONを返すよう指示します。

json_schema.nameとjson_schema.schemaが必須です。strictをtrueにすると、対応するモデルではスキーマへの厳密な準拠を求めます。応答のmessage.contentはJSONの文字列なので、受け取った側でパースしてください。

リクエスト
curl https://api.airouter.dmm.com/v1/chat/completions \
  -H "Authorization: Bearer $AIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [
      {"role": "system", "content": "Extract the event details."},
      {"role": "user", "content": "Team lunch on Friday at 12:30 in Shibuya."}
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "event",
        "schema": {
          "type": "object",
          "properties": {
            "title": {"type": "string"},
            "day": {"type": "string"},
            "time": {"type": "string"},
            "location": {"type": "string"}
          },
          "required": ["title", "day", "time", "location"],
          "additionalProperties": false
        },
        "strict": true
      }
    }
  }'
レスポンスJSON
{
  "role": "assistant",
  "content": "{\"title\":\"Team lunch\",\"day\":\"Friday\",\"time\":\"12:30\",\"location\":\"Shibuya\"}",
  "refusal": null
}
json_objectの例JSON
{
  "model": "google/gemini-2.5-flash",
  "messages": [
    {"role": "system", "content": "Answer in JSON with keys \"answer\" and \"confidence\"."},
    {"role": "user", "content": "What is the capital of Japan?"}
  ],
  "response_format": {"type": "json_object"}
}
非対応モデルの応答JSON
{
  "error": {
    "message": "This model does not support JSON output.",
    "code": "unsupported_parameter",
    "param": "response_format"
  }
}

エラー

エラーはHTTPステータスとJSON本文で返します。本文はerrorオブジェクトを1つ持ち、message・code・paramで構成されます。

エラーオブジェクト

  • messagestring

    エラーの説明

  • codestring

    分岐に使う安定した識別子

  • paramstring | null

    入力が原因のときの場所(ドット区切り、配列は添字付き)。それ以外はnull

ストリーム中のエラー

ストリームを始める前の失敗は通常のHTTPエラー応答です。始まったあとの失敗はHTTP 200のまま、finish_reasonがerrorでerrorを持つイベントを送り、[DONE]で閉じます。途中まで届いた本文は破棄するか再試行してください。

HTTPステータス

HTTPステータス意味
400リクエストの内容に問題がある
401APIキーが無効
402残高不足、またはキーの月額上限
404モデルが存在しない
413本文が大きすぎる
5xxサーバーまたは供給元の障害

エラーコード一覧

code意味
validation_failed400本文が仕様に合わない。paramに場所が入るparamとmessageを見て修正する
invalid_request400JSONとして読めないなど、HTTPリクエスト自体の問題リクエストの組み立てを確認する
unsupported_parameter400モデルが対応しない指定(JSON出力など)指定を外すか、別のモデルを使う
provider_rejected_request400すべての供給元がリクエストの内容を理由に拒否した。パラメータや入力がモデルに合わないパラメータを減らす・入力を見直す・別のモデルを使う
invalid_api_key401キーが無い・形式が違う・失効済みAuthorizationヘッダとキーを確認する
insufficient_credits402ワークスペースの残高が不足チャージする
monthly_limit_exceeded402キーの月額上限に達した上限を見直すか、翌月まで待つ
model_not_found404モデルが存在しないか提供終了GET /v1/modelsでIDを確認する
payload_too_large413本文が10 MiBを超えた入力を減らす
internal_error5xxサーバーまたは供給元の障害時間をおいて再試行する

応答が得られなかったリクエストには課金しません。

すべての応答にx-request-idヘッダが付きます。サポートへ問い合わせる際は、この値と発生時刻をお知らせください。

レスポンスHTTP
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
x-request-id: 01K72W3M9Q4ZJ8N2T6VY5XH0RB

{
  "error": {
    "message": "messages[1].role: role must be one of system, user, assistant or tool.",
    "code": "validation_failed",
    "param": "messages[1].role"
  }
}
ストリーム中のエラーSSE
data: {"id":"01K72W3M9Q4ZJ8N2T6VY5XH0RB","object":"chat.completion.chunk","created":1759968000,"model":"google/gemini-2.5-flash","provider":"edensoft","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"id":"01K72W3M9Q4ZJ8N2T6VY5XH0RB","object":"chat.completion.chunk","created":1759968000,"model":"google/gemini-2.5-flash","provider":"edensoft","choices":[{"index":0,"delta":{},"finish_reason":"error"}],"error":{"message":"An unexpected error occurred. Please try again later.","code":"internal_error","param":null}}

data: [DONE]