# Concepts

> The building blocks of a decision: state, questions, and typed answers.

Canonical: https://platform.uprelic.com/docs/concepts

---

Each request has a **state** and a set of named **questions**. The state can be text or JSON, with up to eight images alongside it. Every question is evaluated against that same state; the response uses your question names as keys.

> **Break broad judgments into smaller ones.** “Should this request be escalated?” depends on several facts. Ask whether a team is blocked, score the urgency, and choose who owns the issue. Combine those answers in your own code, where the decision rule is visible and easy to change.

::: definitions
## State

The content you want to evaluate: a message, document excerpt, structured record, or a description paired with images. Include enough context for the judgment you ask for.

## Noul

A yes or no judgment. The `noul` value is the probability of yes or true, from 0 to 1.

## Choice

A selection from named options you define in `criteria`. The response includes the chosen option, probabilities for all options, and confidence.

## Score

A rating on an ordered list of levels. The response includes a probability-weighted score, the rubric, probabilities, and confidence.

## Box

In beta: where an object is in one of the images. Describe the object in `instructions`, well enough to tell it apart from similar things, and set `image` to the image’s position in `media`, from 0. A box question has no `criteria`.

The answer’s `box` has the edges `left`, `top`, `right` and `bottom` as fractions of the image’s width and height, from its top left corner. Multiply by the image’s size to get pixels.

A detector first proposes up to 8 regions of the image that match the description, and the model picks the one that is the object. The edges fit the region tightly; the usual mistake is picking a similar object next to the right one.

`confidence` is how sure the model is of the box, from 0 to 1. When none of the regions is the object, confidence is close to 0, but a box is still returned, so pair it with a `noul` question when the object may be missing.

To find every match instead of one, set `multiple` to `true`. The model then judges each region on its own, and the answer has `boxes` instead of `box` and `confidence`: a list of every match it is at least 50% sure of, each with its `box` and `probability`, most likely first. The list is empty when nothing matches. When two matches overlap mostly, only the more likely one is kept.

When the request has more than one image, a box question also sees the others, in their order in `media`, so the description can compare them. For example, with a car’s pickup photo first and its return photo second, a box question on image 1 with `multiple` set to `true` and the instructions “damage that isn’t in the first image” finds new damage.

## Models

Set `model` to a model name or its alias. An alias always points to the latest version of that model; the response names the version that answered.

- `strom-1.0.7`, alias `strom-fast`: fast and cheap, with calibrated probabilities. Use it unless you have a reason not to.
- `strom-base-1.0`, alias `strom-base`, in beta: strom-fast that reasons before it answers. Slower (a few seconds per question) and more expensive, and its probabilities are not calibrated.

`GET /v1/models` lists the names and aliases.

## Confidence and review

Use probabilities and confidence to decide what your software can handle automatically and what should go to a person. Ask one narrow question at a time, then combine answers in your code.

**Calibrated since 1 October 2026.** The probabilities of `strom-fast` (`strom-1.0.7`) now match how often an answer is right: on our held-out evaluation, answers given at 90% are right about 90% of the time. Before, the model was slightly overconfident, so fewer answers clear a threshold you set earlier. If you automate above a threshold, check it. The chosen option is unchanged. The probabilities of `strom-base` are not calibrated.

## Repeatability

Strom doesn’t sample a reply; it scores your options. Sent again to `strom-fast`, the same request gets the same chosen option almost every time: 99.4 to 99.6% for text and 98.7 to 99% for images in our tests on a copy of production (October 2026). When the choice does change, the model was nearly undecided, with the top options at or next to a tie. The probabilities themselves can move slightly between calls, on average by 0.01 or less, because your questions are computed together with other work on the GPU. Treat answers close to your threshold as uncertain and send them to review.
:::

## Example

One request that uses every question type: `noul`, `choice`, `score` and `box`.

```bash Request
curl https://api.uprelic.com/v1/systemone \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "strom-base",
    "state": {
      "site": "Riverside Block B",
      "area": "Foundations, east wing",
      "report": "Morning photo from the site camera. Concrete pour for the east footings starts at 10:00.",
      "reported_by": "Site camera 3"
    },
    "media": [{"type": "image", "url": "https://example.com/riverside-b/camera-3.jpg"}],
    "questions": {
      "missing_hard_hat": {
        "type": "noul",
        "instructions": "Is anyone in the photo working missing a hard hat?"
      },
      "worker_without_hard_hat": {
        "type": "box",
        "instructions": "the worker missing a hard hat",
        "image": 0
      },
      "excavator": {
        "type": "box",
        "instructions": "the mini excavator",
        "image": 0
      },
      "stage": {
        "type": "choice",
        "instructions": "Which stage of construction does the photo show?",
        "criteria": {
          "excavation": "Digging and leveling the ground",
          "foundations": "Rebar, formwork or concrete for footings and foundation walls",
          "structure": "Columns, floors and walls above ground",
          "finishing": "Facade, roof, windows or interior work"
        }
      },
      "hazard": {
        "type": "score",
        "instructions": "How serious is the most visible safety hazard in the photo?",
        "criteria": [
          "None",
          "Minor: worth mentioning at the next briefing",
          "Serious: fix today",
          "Critical: stop work now"
        ]
      }
    }
  }'
```

```json Response
{
  "model": "strom-base-1.0",
  "answers": {
    "missing_hard_hat": {"type": "noul", "noul": 0.915},
    "worker_without_hard_hat": {
      "type": "box",
      "box": {"left": 0.513, "top": 0.601, "right": 0.646, "bottom": 0.947},
      "confidence": 0.769
    },
    "excavator": {
      "type": "box",
      "box": {"left": 0.594, "top": 0.355, "right": 0.859, "bottom": 0.649},
      "confidence": 0.857
    },
    "stage": {
      "type": "choice",
      "choice": "foundations",
      "confidence": 0.989,
      "probabilities": {"excavation": 0.002, "foundations": 0.993, "structure": 0.004, "finishing": 0.0}
    },
    "hazard": {
      "type": "score",
      "score": 1.507,
      "confidence": 0.185,
      "legend": {
        "0": "None",
        "1": "Minor: worth mentioning at the next briefing",
        "2": "Serious: fix today",
        "3": "Critical: stop work now"
      },
      "probabilities": {"0": 0.108, "1": 0.356, "2": 0.457, "3": 0.079}
    }
  },
  "usage": {
    "input_tokens": 3328,
    "output_tokens": 11,
    "cached_input_tokens": 0,
    "cost": 0.00079872,
    "currency": "usd"
  },
  "metadata": {"server_processing_time_ms": 3767}
}
```
