# Request options

Options on `POST /v1/systemone` beyond `state`, `questions`, `model` and `subject`. Each says what it costs.

## `method`: how choice questions are answered

```json
{"method": "auto"}      // the default: choices of more than 20 options are matched, the rest go to the engine
{"method": "engine"}    // the engine reads every option; above 20 options in two rounds
{"method": "match"}     // every choice question is matched, whatever its size
```

Matching turns the state (with its memory lines first) and each option's description into vectors and picks the closest option; the options are turned into vectors once and cached. Each answer says which method produced it (`"method": "match"` or `"engine"`), matched answers carry `similarity` (the best and second-best cosine), and `usage.match_questions` counts them. Scores and yes/no questions always go to the engine, and `"method": "match"` on a request without a choice question is a 422. Measured on 2026-09-26 on BANKING77 (600 bank messages, 77 intents): matching 65.2% right in a median of 2 ms and 23 tokens billed; the engine reading all 77 options 62.2% in 209 ms and 812 tokens (see Choice). A matched question is billed for the tokens it read: the state and memory lines, not the options.

## `robust`: answers that do not depend on the option order

```json
{"robust": true}                 // three orders
{"robust": {"orders": 5}}        // one to five
```

The engine's answer to a choice moves when its options are reordered (the engine's authors report 15 to 23% of answers changing when the options of a 20-option choice are reordered). With `robust`, Jepela asks each choice in fixed orders built from the sorted option names and averages them, so your order no longer matters. The answer has `orders` and `agreement`, the share of orders that picked the winner; a low agreement is a question to look at. A 2-option choice has 2 orders. Scores, yes/no questions and choices of more than 20 options (matched, or answered in two rounds with `method: "engine"`) are not reordered and are billed once. Billed per order used. Measured: six caller orders of the same options gave one answer every time, agreement 1.0 (`measurements/jepela-gateway-live-2026-09-23.txt`, item 5).

## `windows`: long states

```json
{"windows": true}
{"windows": {"combine": {"fraud": "max", "tone": "mean"}}}
```

The engine reads about 475 tokens of state on the English checkpoint (see State). With `windows`, a state that is cut is read in overlapping windows (neighbours share 32 tokens), at most 16; a longer state is read up to the 16th window, `windows.covered_all` is false and the `state_cut` warning stays. Answers are combined per question: by default the highest yes for a noul, the highest level for a score, and the most confident window for a choice (`min` does the same for a choice; `mean` averages). A state that is not cut is read once, as without `windows`. The answer's `windows` has `count`, `covered_all`, `state_tokens` and `tokens_per_window`, and each answer's `window` names the window it came from (null with `mean`). Measured: a card number past the cut moved a yes/no answer from 0.00 to 1.00 (3 windows, `measurements/jepela-gateway-live-2026-09-23.txt`, item 6). Billed per window.

## `derive` and `values`: facts computed in code

The engine does not do arithmetic or dates. Compute them in code and show the engine the result:

```json
{"state": {"pump": "pump-13", "reading": {"bearing_temperature_c": 78}},
 "values": {"limit": 75},
 "derive": {"over": "reading.bearing_temperature_c > limit",
            "limit": {"when": "reading.bearing_temperature_c > limit",
                      "fact": "Pump-13 is above its bearing temperature limit right now; a technician must look at pump-13 today and a maintenance ticket is required."}}}
```

Expressions read `values` and the state's fields and may use comparisons, `and`/`or`/`not`, arithmetic and the functions `days_since`, `days_between`, `len`, `lower`, `contains`, `number`, `abs`, `min`, `max`, `round`; nothing else runs. `days_since` counts from `values.today` when it is sent, otherwise from the server's date. A plain expression adds a line such as `over is true: reading.bearing_temperature_c > limit, where reading.bearing_temperature_c is 78, limit is 75.`; a `when` form adds its `fact` (or `else`) only as the condition says. The lines are placed first: under `Computed by the system:` in a text or array state, as a `computed_facts` key in an object state; `derived` in the answer lists every value. Measured with the `when` form above and a choice ignore / log / ticket / stop: at 78 °C p(ticket) went from 0.09 to 0.81 on the English checkpoint (0.19 to 0.52 on typed-decisions); at 70 °C the condition is false, no fact is added, and the answer stays at 0.09 (`measurements/jepela-gateway-live-2026-09-23.txt`, item 2). The same expressions drive memory rules (see Rules in memory). Free.

Limits: at most 20 `derive` names, each starting with a letter, with at most 40 letters, digits or underscores; an expression has at most 300 characters, a `fact` or `else` at most 500; `values` is an object of at most 50 fields.

## `cache`: identical requests

```json
{"cache": true}
```

An identical request (same state, questions, model and options) that does not use a subject's memory returns the stored answers without new engine work; `usage.cached` says so. The cache keeps the gateway's 2,000 most recently used responses and is emptied when it restarts. Billed like the first call.

## `memory`

`use`, `top_k`, `min_share`, `names`, `question_words`, `focus`, `compare`, `explain` and `placebo`: see Memory. Only the answer you asked for is billed; the extra passes of `compare`, `explain` and `placebo` are free.

## Not accepted

`context` is refused with a 422: Jepela builds the context from the subject's memory and `derive`; send those instead.

## The limit per request

A request may need at most 400 engine questions, counting one per question, one per option order of a robust choice, and for a choice of more than 20 options read by the engine one per group of 20 plus one for the final round; a matched choice is not an engine question. Above that the request is refused with a 422 that says how many it needed.
