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

# System One

> Typed, calibrated decisions over text, JSON, and images

```http theme={"theme":{"light":"github-light","dark":"dark-plus"}}
POST https://gateway.vlm.run/typesafe/v1/systemone
```

Answers named questions about a state and returns a calibrated probability for every
answer. Nothing is generated and nothing is parsed. See
[System One](/gateway/system-one) for the concepts and
[TypeSafe SDK Compatibility](/gateway/jev-compatibility) for migrating an existing client.

Authentication is optional for the VLM Run Gateway (at the moment). See
[Authentication](/gateway/authentication) for tiers and
[Rate Limits](/gateway/rate-limits) for per-tier quotas.

## Request body

| Field              | Type                            | Required | Description                                                                                                                                                                                          |
| ------------------ | ------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state`            | `string` \| `object` \| `array` | Yes      | What the questions are about. Objects and arrays are sent as JSON.                                                                                                                                   |
| `questions`        | `object`                        | Yes      | Map of question id to question object, at least one entry. Ids key the answers and never reach the model.                                                                                            |
| `model`            | `string`                        | Yes      | A served id, or one of its aliases. An id the deployment does not serve is a `404`. See [Models](/gateway/typesafe-models).                                                                          |
| `content`          | `array` \| `string`             | No       | This request's media, as content parts. A bare string is one text part. See [Inputs](#inputs).                                                                                                       |
| `reasoning_effort` | `string`                        | No       | Generative engines only: `none` (default), `minimal`, or `low`, for 0, 32, or 64 tokens of reasoning. `medium` and `high` are declared but `422` until served; a diffusion engine rejects any value. |
| `steps`            | `integer`                       | No       | Diffusion engines only: denoise steps per read, 1 to 8. Default `1`.                                                                                                                                 |
| `samples`          | `integer`                       | No       | Noise draws to average, 1 to 32. Every draw is billed. Default: one read.                                                                                                                            |

Unknown top-level fields return a `422`.

### Question object

| Field          | Type                                | Description                                                       |
| -------------- | ----------------------------------- | ----------------------------------------------------------------- |
| `type`         | `"noul"` \| `"choice"` \| `"score"` | Question category. Discriminates `criteria` and the answer shape. |
| `instructions` | `string` \| `object` \| `array`     | Optional. What the question is asking.                            |
| `criteria`     | `object` \| `array`                 | Type-dependent, see below.                                        |

| `type`   | `criteria`                                               | Required |
| -------- | -------------------------------------------------------- | -------- |
| `noul`   | `{"true": description, "false": description}`            | No       |
| `choice` | Map of label to description or `null`, 2 to 128 entries. | Yes      |
| `score`  | Ordered array of 2 to 10 level descriptions.             | Yes      |

<h3 id="inputs">
  Inputs
</h3>

`content` is a list of content parts, with no message wrapper and no roles: a read
denoises one canvas over one state, so there is no turn to address and no history to
carry. A bare string is treated as one `text` part. Media leads, the `state` follows.

| Part           | Shape                                                                                                                   | Limit                                                                 |
| -------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `image_url`    | `{"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,…", "detail": "high"}}`                             | 8 per request, 5 MB each                                              |
| `file`         | `{"type": "file", "file": {"filename": "invoice.pdf", "file_data": "data:application/pdf;base64,…", "detail": "high"}}` | 1 document per request                                                |
| `document_url` | `{"type": "document_url", "document_url": {"url": "…", "detail": "high"}}`                                              | The same PDF as a `file` part, for callers already sending this shape |
| `text`         | `{"type": "text", "text": "…"}`                                                                                         | Read after the `state`                                                |

<Warning>
  **Images or one document, never both.** A document's pages *are* the read's images, so
  the two compete for the same 8 slots and you could not tell which pages were dropped.
  Sending both is a `422`.
</Warning>

An **image URL must be a `data:` URL**; `http(s)` is rejected. **`file_data` accepts
either** a `data:application/pdf;base64,` URL or `http(s)`. A PDF's first 8 pages are
rasterised at 96 DPI and read as the request's images.

`filename` is optional.

| `detail`         | Vision tokens per image or page |
| ---------------- | ------------------------------- |
| `auto` (default) | 280, the same as `high`         |
| `high`           | 280                             |
| `low`            | 70                              |

A part with no `detail` gets `auto`, which reads at full fidelity. `low` is the explicit
way to trade detail for tokens. The cap applies **per request**: one `high` or `auto`
part lifts every image and page in that request to 280.

## Response

| Field                        | Type      | Description                                                                                                               |
| ---------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------- |
| `model`                      | `string`  | The model that answered, for example `google/diffusiongemma-26b-a4b-it`.                                                  |
| `answers`                    | `object`  | Answers keyed by question id.                                                                                             |
| `usage.input_tokens`         | `integer` | Prompt tokens across every read. Counts toward your quota.                                                                |
| `usage.output_tokens`        | `integer` | `0` on a diffusion read, which generates nothing. Non-zero on a generative read, which writes the answer under a grammar. |
| `usage.input_tokens_details` | `object`  | `cached_tokens`, `image_tokens`, and `text_tokens`. Gateway extension.                                                    |
| `usage.reads`                | `integer` | Engine calls made: one per question group, times `samples`. Gateway extension.                                            |
| `usage.cost`                 | `number`  | USD at the model's published rate, cached tokens at the cache rate. Gateway extension.                                    |

Responses carry `x-typesafe-request-id`, which mirrors the Gateway's `x-request-id`.

`input_tokens_details`, `reads`, and `cost` are this Gateway's additions. TypeSafe's
decoder ignores fields it does not model,
so the official SDK still parses the response and a client reading the raw JSON can price
the call. `image_tokens` is derived from the budget the request applied, 70 or 280 an
image, because the engine reports no image/text split.

A decision is billed per read. A rejected request bills nothing. See
[Pricing](/gateway/pricing).

### Answer shapes

| `type`   | Fields                                                                             |
| -------- | ---------------------------------------------------------------------------------- |
| `noul`   | `noul`: P(yes), from 0 to 1.                                                       |
| `choice` | `choice` (winning label), `probabilities` (label to probability), `confidence`.    |
| `score`  | `score` (expected level, `sum(i * p_i)`), `legend`, `probabilities`, `confidence`. |

`confidence` is `1 - H(p) / ln(K)`: 1 when all mass is on one label, 0 when the
distribution is uniform.

```json Response theme={"theme":{"light":"github-light","dark":"dark-plus"}}
{
  "model": "google/diffusiongemma-26b-a4b-it",
  "answers": {
    "kind": {
      "type": "choice",
      "choice": "invoice",
      "probabilities": { "invoice": 0.88, "receipt": 0.07, "contract": 0.02, "other": 0.03 },
      "confidence": 0.64
    },
    "legibility": {
      "type": "score",
      "score": 1.74,
      "legend": { "0": "unreadable", "1": "partly legible", "2": "clear" },
      "probabilities": { "0": 0.02, "1": 0.22, "2": 0.76 },
      "confidence": 0.47
    },
    "has_total": { "type": "noul", "noul": 0.91 }
  },
  "usage": {
    "input_tokens": 486,
    "output_tokens": 0,
    "input_tokens_details": { "cached_tokens": 0, "image_tokens": 280, "text_tokens": 206 },
    "reads": 1,
    "cost": 0.000129
  }
}
```

## Errors

| Status | `error_type`       | When                                                                                                                                 |
| ------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `422`  | validation list    | An invalid body, an unknown field, or a schema the model cannot answer. The body is `{"detail": [{"type", "loc", "msg", "input"}]}`. |
| `404`  | `not_found_error`  | `model` is not served on this route.                                                                                                 |
| `429`  | rate limit         | Per-tier quota exceeded. See [Rate Limits](/gateway/rate-limits).                                                                    |
| `503`  | `api_error`        | Engine unreachable or failed. Sent with `retry-after: 2`.                                                                            |
| `529`  | `overloaded_error` | Too many reads queued. Sent with `retry-after: 1`.                                                                                   |

See [Error Codes](/gateway/error-codes) for the Gateway-wide envelope.

<RequestExample>
  ```python Python theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  import base64, pathlib
  from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

  client = TypeSafeClient(
      api_key="<VLMRUN_API_KEY>",
      base_url="https://gateway.vlm.run/typesafe",
  )

  page = base64.b64encode(pathlib.Path("invoice-page.jpg").read_bytes()).decode()

  result = client.system_one(
      "Answer about the attached page.",
      {
          "kind": Choice(
              instructions="What kind of document is this page from?",
              criteria={"invoice": None, "receipt": None, "contract": None, "other": None},
          ),
          "has_total": Noul(instructions="Is a total amount due visible on the page?"),
          "legibility": Score(
              instructions="How legible is the text?",
              criteria=["unreadable", "partly legible", "clear"],
          ),
      },
      extra_body={
          "content": [
              {
                  "type": "image_url",
                  "image_url": {
                      "url": f"data:image/jpeg;base64,{page}",
                      "detail": "high",
                  },
              }
          ]
      },
      model="google/diffusiongemma-26b-a4b-it",
  )

  print(result.choices["kind"].choice, result.usage.input_tokens)
  ```

  ```typescript Node.js theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  import { readFileSync } from "node:fs";
  import { choice, noul, score, TypeSafeClient } from "@typesafe-ai/sdk";

  const client = new TypeSafeClient({
    apiKey: process.env.VLMRUN_API_KEY,
    baseURL: "https://gateway.vlm.run/typesafe",
    defaultModel: "google/diffusiongemma-26b-a4b-it",
  });

  const page = readFileSync("invoice-page.jpg").toString("base64");

  const request = {
    state: "Answer about the attached page.",
    questions: {
      kind: choice("What kind of document is this page from?", {
        invoice: null,
        receipt: null,
        contract: null,
        other: null,
      }),
      has_total: noul("Is a total amount due visible on the page?"),
      legibility: score("How legible is the text?", [
        "unreadable",
        "partly legible",
        "clear",
      ]),
    },
    content: [
      { type: "image_url",
        image_url: { url: `data:image/jpeg;base64,${page}`, detail: "high" } },
    ],
  };

  const { answers, usage } = await client.systemOne(request);
  console.log(answers.kind.choice, usage.input_tokens);
  ```

  ```bash CLI theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  vlmrun gw s1 -s "Answer about the attached page." invoice-page.jpg --detail high \
    -m google/diffusiongemma-26b-a4b-it \
    --choice kind="invoice|receipt|contract|other" \
    --noul has_total="Is a total amount due visible on the page?" \
    --score legibility="unreadable|partly legible|clear" --json
  ```

  ```bash cURL theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  IMAGE=$(base64 -w0 invoice-page.jpg)

  curl https://gateway.vlm.run/typesafe/v1/systemone \
    -H "Authorization: Bearer $VLMRUN_API_KEY" \
    -H "Content-Type: application/json" \
    -d @- <<JSON
  {
    "model": "google/diffusiongemma-26b-a4b-it",
    "state": "Answer about the attached page.",
    "content": [
      {"type": "image_url",
       "image_url": {"url": "data:image/jpeg;base64,$IMAGE", "detail": "high"}}
    ],
    "questions": {
      "kind": {
        "type": "choice",
        "instructions": "What kind of document is this page from?",
        "criteria": {"invoice": null, "receipt": null, "contract": null, "other": null}
      },
      "has_total": {"type": "noul", "instructions": "Is a total amount due visible on the page?"},
      "legibility": {
        "type": "score",
        "instructions": "How legible is the text?",
        "criteria": ["unreadable", "partly legible", "clear"]
      }
    }
  }
  JSON
  ```
</RequestExample>

## Related

<CardGroup cols={2}>
  <Card title="System One" icon="scale-balanced" href="/gateway/system-one">
    Question types, images, confidence, and cost levers.
  </Card>

  <Card title="TypeSafe SDK Compatibility" icon="arrow-right-arrow-left" href="/gateway/jev-compatibility">
    Compatibility matrix and migration steps.
  </Card>

  <Card title="List Models" icon="table-list" href="/gateway/api-reference/get-typesafe-models">
    The current TypeSafe-compatible models on the `/typesafe` route.
  </Card>

  <Card title="Chat Completions" icon="comments" href="/gateway/api-reference/post-chat-completions">
    OCR, VQA, and document inference when you need generated text.
  </Card>
</CardGroup>
