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

# System One API

> Call any decision model on Bud with the System One request format.

```bash cURL theme={null}
curl https://gateway.bud.studio/v1/systemone \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "my-decision-deployment",
    "state": "Customer: I was charged twice for order #1234 and want a refund now!",
    "questions": {
      "is_refund": {
        "type": "noul",
        "instructions": "Is the customer asking for a refund?",
        "criteria": { "true": "they ask for money back" }
      },
      "team": {
        "type": "choice",
        "instructions": "Which team should handle this?",
        "criteria": { "billing": "payments", "shipping": null, "technical": "bugs" }
      },
      "urgency": {
        "type": "score",
        "instructions": "How urgent is this?",
        "criteria": ["low", "medium", "high"]
      }
    }
  }'
```

```python Python theme={null}
import requests

response = requests.post(
    "https://gateway.bud.studio/v1/systemone",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "model": "my-decision-deployment",
        "state": "Customer: I was charged twice for order #1234 and want a refund now!",
        "questions": {
            "is_refund": {"type": "noul", "instructions": "Is the customer asking for a refund?"},
            "team": {
                "type": "choice",
                "instructions": "Which team should handle this?",
                "criteria": {"billing": "payments", "shipping": None, "technical": "bugs"},
            },
            "urgency": {
                "type": "score",
                "instructions": "How urgent is this?",
                "criteria": ["low", "medium", "high"],
            },
        },
    },
)
response.raise_for_status()
for key, answer in response.json()["answers"].items():
    print(key, answer)
```

```json 200 theme={null}
{
  "model": "my-decision-deployment",
  "answers": {
    "is_refund": { "type": "noul", "noul": 0.99 },
    "team": {
      "type": "choice",
      "choice": "billing",
      "confidence": 1.0,
      "probabilities": { "billing": 1.0, "shipping": 0.0, "technical": 0.0 }
    },
    "urgency": {
      "type": "score",
      "score": 1.98,
      "confidence": 0.97,
      "legend": { "0": "low", "1": "medium", "2": "high" },
      "probabilities": { "0": 0.0, "1": 0.02, "2": 0.98 }
    }
  },
  "usage": { "input_tokens": 393, "output_tokens": 71 }
}
```

System One is the decision format TypeSafe introduced and other vendors and engines speak: questions
are keyed by name, and answers come back under the same keys. Bud accepts it on `/v1/systemone` for
**every** decision model, including OpenAI's `gpt-6-luna`: the request is translated to the
[Decisions API](https://docs.budecosystem.com/api-sdk/decisions/create-decision.md) and back. Authentication, rate and usage limits,
guardrails, pricing and tracing are the same on both routes, and so are the
[limits](https://docs.budecosystem.com/api-sdk/decisions/create-decision.md#limits) and
[errors](https://docs.budecosystem.com/api-sdk/decisions/create-decision.md#errors).

## Headers

| Parameter | Type | Required | Description |
| - | - | - | - |
| Authorization | string | Yes | Bearer authentication header |
| Content-Type | string | Yes | `application/json` |

## Body

| Parameter | Type | Required | Description |
| - | - | - | - |
| model | string | Yes | Name of a deployment that serves the Decisions API. |
| state | string, object, array or `{ "messages": [...] }` | Yes | What to decide about; see [State](#state). |
| questions | object | Yes | 1 to 400 questions keyed by name. The key order is kept: answers come back in the same order. |
| assets, images | — | No | Not supported: a non-empty value is refused with `400` `unsupported_input`. |

Other top-level fields are ignored.

## State

| `state` | Sent to the model as |
| - | - |
| A string | The text. |
| A JSON object, or an array of objects | A JSON record. |
| An array of strings | One text part per string. |
| `{ "messages": [{ "role", "content" }] }` | A conversation, one message per entry. `content` is a string or text parts. |

## Questions

| `type` | Fields | Notes |
| - | - | - |
| `noul` | `instructions`, `criteria`: `{ "true": "...", "false": "..." }` (both optional) | A yes/no question. The criteria are appended to the instructions as "Answer yes when …" and "Answer no when …". |
| `choice` | `instructions`, `criteria`: `{ "option": "description or null" }` | 2 to 255 options. |
| `score` | `instructions`, `criteria`: `["level", …]` | 2 to 10 levels, lowest first. |
| `box` | — | Not supported: refused with `400` `unsupported_question_type`. |

Any other field inside a question is refused with `400` `unknown_parameter`.

## Response

| Field | Type | Description |
| - | - | - |
| model | string | The model that answered, as the provider reports it. |
| answers | object | One answer under every question key, in request order. |
| usage | object | `input_tokens` and `output_tokens`. |

| Answer `type` | Fields |
| - | - |
| `noul` | `noul`: the probability of yes. |
| `choice` | `choice`, `confidence`, `probabilities`: option → probability, for every option. |
| `score` | `score` (the expected level index), `confidence`, `legend`: index → level, and `probabilities`: index → probability, for every level. |
| `refusal` | No other fields. Only an OpenAI or Azure deployment can refuse a question; System One has no refusal answer, so Bud returns this type under the question's key rather than leaving the key out. |

`confidence` is the provider's own figure. Probabilities are each model's own estimates and are not
comparable across models or providers.

## Differences from calling a vendor directly

* **Bud's error format.** Errors use the OpenAI-style envelope of the Decisions API
  (`{"error": {"message", "type", "param", "code"}}`), not the vendor's own. A provider's validation
  error keeps its status and message.
* **Choice and level descriptions** reach the model as part of the option text.
* **No images and no `box` questions**, on every provider.
* **Bud's limits apply first**: at most 400 questions, 255 options and 10 levels, then the provider's
  own limits. A request over a limit is refused with `400`, not split.
* **Vendor-specific headers are not forwarded** (for example TypeSafe's long-context or image
  headers).

The provider notes on the [Decisions API page](https://docs.budecosystem.com/api-sdk/decisions/create-decision.md#providers) apply
here too: TypeSafe output tokens are reported but not charged, Embedding Studio is priced per request
and reports no token usage, and its abstention is not returned.


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