> ## Documentation Index
> Fetch the complete documentation index at: https://mixroute.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Decisions API

> gpt-6-luna で OpenAI 互換 Decisions を利用するためのパラメーター、predicate・choice・score の結果、エラー処理。

MixRoute の OpenAI 互換 Decisions エンドポイントで、共通の入力に名前付きの質問を行い、型付きの回答を取得します。モデルは `gpt-6-luna` を使用します。Jev System One とは別のプロトコルです。

## 接続方法

`POST https://api.mixroute.ai/v1/decisions`

`Authorization: Bearer $MIXROUTE_API_KEY` と `Content-Type: application/json` を送信します。API キーはサーバー側で保持してください。モデルとチャネルの利用可否はアカウントに依存します。モデル一覧に掲載されていても、すべてのエンドポイントが利用できるとは限りません。

> [!WARNING]
>
> `state` ではなく `input` を使用します。`questions` は名前を指定できる配列で、質問 ID をキーにしたオブジェクトではありません。真偽判定は `noul` ではなく `predicate`、分類は `choices`、評価は `levels` を使い、Jev の `criteria` は使いません。回答の `answers` も配列です。Jev の仕様は [System One](https://mixroute.ai/docs/ja/api-reference/endpoint/jev.md)を参照してください。

## リクエストパラメーター

| フィールド | 型 | 要件 | 説明 |
| - | - | - | - |
| `model` | string | 必須 | gpt-6-luna を指定します。他のチャットモデルや Jev ID にそのまま置き換えることはできません。 |
| `input` | string / array | 必須 | 全質問が共有する入力。テキスト、または順序付きのメッセージ、関数呼び出しと結果、カスタムツール呼び出しと結果の配列。 |
| `questions` | object\[] | 必須 | 1-400 件の predicate、choice、score の配列。各質問は独立して評価されます。先行する回答に依存する場合は別リクエストに分けます。 |
| `prompt_cache_key` | string / null | 任意 | 呼び出し元が指定するキャッシュ分割キー。最大 64 文字。 |
| `prompt_cache_options` | object / null | 任意 | 任意のキャッシュ設定。mode は implicit（既定）または explicit。ttl は現在 30m に対応します。実際のキャッシュ対応と課金はルートによって異なります。 |
| `safety_identifier` | string / null | 任意 | 不透明なエンドユーザー識別子。最大 128 文字。個人情報を含まない安定した識別子を推奨します。 |

## 質問のフィールド

| フィールド | 型 | 要件 | 説明 |
| - | - | - | - |
| `type` | string | 必須 | predicate、choice、score のいずれか。 |
| `instructions` | string / array | 必須 | 判断内容を示す文字列、または対応するコンテンツ項目の空でない配列。テキストや画像はメッセージで囲まず instructions に直接指定します。 |
| `name` | string | 任意 | 回答に返される名前。質問ごとに異なる名前を指定してください。名前を省略すると回答の name が null になる場合があります。 |
| `choices` | object\[] | 型による | choice では必須。2-255 個の重複しない選択肢。それぞれ value（文字列またはブール値）が必須、description（文字列）は任意です。文字列 "true" とブール値 true は別の値です。 |
| `levels` | object\[] | 型による | score では必須。低い順に並べた 2-10 段階。各段階の label（文字列）は必須、description（文字列）は任意です。インデックスは 0 から始まります。 |

## 回答の型

| 型 | 説明 |
| - | - |
| `predicate` | probability は条件が真である推定確率で、範囲は 0-1 です。ブール値ではありません。 |
| `choice` | choice は指定した文字列またはブール値の選択肢です。probabilities は value/probability の配列で、confidence は別フィールドです。 |
| `score` | score は段階インデックスの確率加重平均で、0 から levels.length-1 の範囲です。小数になり得ます。probabilities には value（インデックス）、label、probability が含まれます。 |

どの質問も要求した型の代わりに type=refusal を返す場合があります。他の質問には回答が返ることもあります。name または質問順で対応付け、フィールドを読む前に type を確認し、拒否を明示的に処理してください。確率と信頼度は正しさを保証しません。

## リクエスト例

呼び出し前に `MIXROUTE_API_KEY` を設定してください。例は一度だけ送信し、自動再試行しません。クライアントのタイムアウトは推論が未実行であることを意味しません。

> [tab] cURL
>
> ```bash theme={null}
> curl --request POST "https://api.mixroute.ai/v1/decisions" \
>   --header "Authorization: Bearer $MIXROUTE_API_KEY" \
>   --header "Content-Type: application/json" \
>   --data '{
>   "model": "gpt-6-luna",
>   "input": "CSV export fails on every attempt. The customer needs the file today and asks for a human agent.",
>   "questions": [
>     {
>       "type": "choice",
>       "name": "team",
>       "instructions": "Which team should handle this ticket?",
>       "choices": [
>         {
>           "value": "engineering",
>           "description": "Software defects"
>         },
>         {
>           "value": "billing",
>           "description": "Payments and refunds"
>         }
>       ]
>     },
>     {
>       "type": "score",
>       "name": "urgency",
>       "instructions": "How soon does the customer need help?",
>       "levels": [
>         {
>           "label": "No deadline",
>           "description": "No deadline is specified."
>         },
>         {
>           "label": "This week",
>           "description": "Help is needed within a week."
>         },
>         {
>           "label": "Today",
>           "description": "Help is explicitly required today."
>         }
>       ]
>     },
>     {
>       "type": "predicate",
>       "name": "needs_human",
>       "instructions": "Does the customer request a human agent?"
>     }
>   ]
> }'
> ```

> [tab] Python
>
> ```python theme={null}
> import json
> import os
> import requests
>
> payload = json.loads(r'''{
>   "model": "gpt-6-luna",
>   "input": "CSV export fails on every attempt. The customer needs the file today and asks for a human agent.",
>   "questions": [
>     {
>       "type": "choice",
>       "name": "team",
>       "instructions": "Which team should handle this ticket?",
>       "choices": [
>         {
>           "value": "engineering",
>           "description": "Software defects"
>         },
>         {
>           "value": "billing",
>           "description": "Payments and refunds"
>         }
>       ]
>     },
>     {
>       "type": "score",
>       "name": "urgency",
>       "instructions": "How soon does the customer need help?",
>       "levels": [
>         {
>           "label": "No deadline",
>           "description": "No deadline is specified."
>         },
>         {
>           "label": "This week",
>           "description": "Help is needed within a week."
>         },
>         {
>           "label": "Today",
>           "description": "Help is explicitly required today."
>         }
>       ]
>     },
>     {
>       "type": "predicate",
>       "name": "needs_human",
>       "instructions": "Does the customer request a human agent?"
>     }
>   ]
> }''')
> response = requests.post(
>     "https://api.mixroute.ai/v1/decisions",
>     headers={"Authorization": "Bearer " + os.environ["MIXROUTE_API_KEY"]},
>     json=payload,
>     timeout=60,
>     allow_redirects=False,
> )
> response.raise_for_status()
> result = response.json()
> if not isinstance(result.get("answers"), list):
>     raise ValueError("Expected an answers array")
> for answer in result["answers"]:
>     kind = answer["type"]
>     if kind == "refusal":
>         print(answer.get("name"), "refused")
>         continue
>     field = {"predicate": "probability", "choice": "choice", "score": "score"}.get(kind)
>     if field is None:
>         raise ValueError("Unexpected answer type: " + kind)
>     print(answer.get("name"), answer[field])
> ```

> [tab] JavaScript
>
> ```javascript theme={null}
> const apiKey = process.env.MIXROUTE_API_KEY;
> if (!apiKey) throw new Error("Set MIXROUTE_API_KEY");
> const payload = {
>   "model": "gpt-6-luna",
>   "input": "CSV export fails on every attempt. The customer needs the file today and asks for a human agent.",
>   "questions": [
>     {
>       "type": "choice",
>       "name": "team",
>       "instructions": "Which team should handle this ticket?",
>       "choices": [
>         {
>           "value": "engineering",
>           "description": "Software defects"
>         },
>         {
>           "value": "billing",
>           "description": "Payments and refunds"
>         }
>       ]
>     },
>     {
>       "type": "score",
>       "name": "urgency",
>       "instructions": "How soon does the customer need help?",
>       "levels": [
>         {
>           "label": "No deadline",
>           "description": "No deadline is specified."
>         },
>         {
>           "label": "This week",
>           "description": "Help is needed within a week."
>         },
>         {
>           "label": "Today",
>           "description": "Help is explicitly required today."
>         }
>       ]
>     },
>     {
>       "type": "predicate",
>       "name": "needs_human",
>       "instructions": "Does the customer request a human agent?"
>     }
>   ]
> };
> const response = await fetch("https://api.mixroute.ai/v1/decisions", {
>   method: "POST",
>   headers: {
>     Authorization: "Bearer " + apiKey,
>     "Content-Type": "application/json",
>   },
>   body: JSON.stringify(payload),
>   signal: AbortSignal.timeout(60000),
>   redirect: "error",
> });
> const result = await response.json();
> if (!response.ok) {
>   throw new Error(result.error?.message ?? "HTTP " + response.status);
> }
> if (!Array.isArray(result.answers)) throw new Error("Expected an answers array");
> for (const answer of result.answers) {
>   if (answer.type === "refusal") {
>     console.log(answer.name, "refused");
>     continue;
>   }
>   const field = { predicate: "probability", choice: "choice", score: "score" }[answer.type];
>   if (!field) throw new Error("Unexpected answer type: " + answer.type);
>   console.log(answer.name, answer[field]);
> }
> ```

## レスポンス例

同期 JSON オブジェクトが返ります。Chat Completions の choices 配列や、ポーリングする非同期タスクではありません。確率とトークン使用量はリクエストによって変わります。

```json theme={null}
{
  "model": "gpt-6-luna",
  "answers": [
    {
      "type": "choice",
      "name": "team",
      "choice": "engineering",
      "probabilities": [
        {
          "value": "engineering",
          "probability": 1
        },
        {
          "value": "billing",
          "probability": 0
        }
      ],
      "confidence": 1
    },
    {
      "type": "score",
      "name": "urgency",
      "score": 2,
      "probabilities": [
        {
          "value": 0,
          "label": "No deadline",
          "probability": 0
        },
        {
          "value": 1,
          "label": "This week",
          "probability": 0
        },
        {
          "value": 2,
          "label": "Today",
          "probability": 1
        }
      ],
      "confidence": 1
    },
    {
      "type": "predicate",
      "name": "needs_human",
      "probability": 1
    }
  ],
  "usage": {
    "input_tokens": 416,
    "input_tokens_details": {
      "cached_tokens": 0,
      "cache_write_tokens": 0
    },
    "output_tokens": 0,
    "output_tokens_details": {
      "reasoning_tokens": 0
    },
    "total_tokens": 416
  }
}
```

| フィールド | 説明 |
| - | - |
| `model` | 判断に使用されたモデル。 |
| `answers` | 質問順の配列。各要素の type と name を確認します。 |
| `usage.input_tokens` | リクエストの入力トークン数。 |
| `usage.input_tokens_details` | cached\_tokens と cache\_write\_tokens は input\_tokens に含まれます。重複して加算しないでください。 |
| `usage.output_tokens / usage.output_tokens_details` | 出力使用量と reasoning\_tokens。チャット文章が返ったことを示す値ではありません。 |
| `usage.total_tokens` | 報告された合計トークン使用量。 |

## 構造化データと画像入力

user メッセージの content には input\_text（text）、input\_image（image\_url）、input\_json（data）を指定できます。JSON data はオブジェクトまたはオブジェクトの配列です。内部のキーは通常のデータで、画像取得やメッセージ作成を指示しません。JSON 入力の上限はコンテナー 32 階層、10,000 個の値、コンパクトな UTF-8 JSON で 256 KiB です。

```json theme={null}
{
  "model": "gpt-6-luna",
  "input": [
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Evaluate the ticket record."
        },
        {
          "type": "input_json",
          "data": {
            "ticket": {
              "feature": "CSV export",
              "fails": true,
              "deadline": "today"
            }
          }
        }
      ]
    }
  ],
  "questions": [
    {
      "type": "predicate",
      "name": "deadline_today",
      "instructions": "Does the ticket require action today?"
    }
  ]
}
```

画像には公開 HTTP(S) URL または Base64 data URL を使い、file\_id は使いません。detail は auto、low、high、original を指定できます。developer/system メッセージはテキスト、assistant メッセージは出力テキストまたは拒否項目です。ツール結果は call\_id で呼び出しと対応付けます。このプロトコルはファイル、音声、項目参照を受け付けません。これらはプロトコル上の形式で、拡張入力の利用可否は MixRoute のルートに依存します。

画像 URL を公開アクセス可能な商品画像、または Base64 data URL に置き換えてください。

```json theme={null}
{
  "model": "gpt-6-luna",
  "input": [
    {
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "Inspect this product photo."
        },
        {
          "type": "input_image",
          "image_url": "https://example.com/product.png",
          "detail": "auto"
        }
      ]
    }
  ],
  "questions": [
    {
      "type": "predicate",
      "name": "visible_damage",
      "instructions": "Does the product show a crack, tear, or dent?"
    }
  ]
}
```

## 任意のプロンプトキャッシュ

共有 input のキャッシュには少なくとも 1,024 トークンが必要です。questions は再利用する入力プレフィックスに含まれません。既定では暗黙の区切りを使います。明示的な区切りは共有 input のテキスト・画像項目に `prompt_cache_breakpoint: {"mode": "explicit"}` を設定します。prompt\_cache\_options.mode=explicit で区切りがない場合、キャッシュは無効です。質問の instructions にキャッシュの区切りは指定できません。上流の割引や価格がそのまま MixRoute に適用されるとは限りません。

## エラーと課金

先に HTTP ステータスを確認してください。ゲートウェイのエラーには error.message、error.type、error.code、error.param が含まれる場合があります。param は空の場合もあります。問い合わせには x-oneapi-request-id を保持し、API キー全体をログに残さないでください。

| HTTP | 説明 |
| - | - |
| 400 invalid\_request | input と questions 配列を確認してください。質問オブジェクトのマップは Jev の形式です。 |
| 401 / 403 | 認証とエンドポイント・モデルの権限を確認してください。 |
| 503 model\_not\_found | このキー・グループに選択モデルの利用可能なチャネルがありません。判断結果ではありません。 |
| 429 / その他の 5xx | Retry-After があれば従い、適切な場合のみ回数を制限して再試行します。結果不明のタイムアウト後は自動で重複送信しないでください。 |

```json theme={null}
{
  "error": {
    "message": "questions must be a non-empty array",
    "type": "mixroute_error",
    "param": "",
    "code": "invalid_request"
  }
}
```

usage と現在の[モデルマーケットプレイス](https://console.mixroute.ai/models)で課金を確認してください。Responses や Chat Completions の料金が Decisions に適用されるとは限りません。実際の料金はアカウント倍率とルートの価格設定によって決まります。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.