> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://respan.ai/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://respan.ai/docs/_mcp/server.

# Question types

Each question in `questions` has a `type`. One request can mix all four. Every example below is a full request body for `POST https://api.respan.ai/api/v1/decisions` and the response it returned on 2026-10-15.

## Choice

Pick one option. `criteria` maps each option key to a description; the answer comes back as a key.

**`Request`**

```json Request
{
  "model": "span-02",
  "state": "Customer: I was charged twice for my subscription this month.",
  "questions": {
    "team": {
      "type": "choice",
      "instructions": "Which team should handle this ticket?",
      "criteria": {
        "billing": "Charges, invoices, refunds",
        "technical": "Bugs, errors, outages",
        "sales": "Plans, upgrades, pricing questions"
      }
    }
  }
}
```

**`Response`**

```json Response
{
  "model": "span-02",
  "answers": {
    "team": {
      "type": "choice",
      "choice": "billing",
      "confidence": 0.9935783,
      "probabilities": {
        "billing": 0.9957189,
        "technical": 0.0005935695,
        "sales": 0.0036875624
      }
    }
  },
  "usage": {
    "input_tokens": 129,
    "output_tokens": 0
  }
}
```

| Field           | Meaning                                                            |
| --------------- | ------------------------------------------------------------------ |
| `choice`        | The most likely option key.                                        |
| `probabilities` | Every option's probability. They sum to 1.                         |
| `confidence`    | `(p_max − 1/n) / (1 − 1/n)`: 0 for an even split, 1 for certainty. |

A choice question takes 1 to 679 options.

## Yes/no (`noul`)

A yes/no question. `criteria` is optional: describe what counts as `true` and `false` when the line is fuzzy.

**`Request`**

```json Request
{
  "model": "span-02",
  "state": "Customer: I was charged twice for my subscription this month. Please refund the duplicate charge.",
  "questions": {
    "wants_refund": {
      "type": "noul",
      "instructions": "Does the customer want money back?",
      "criteria": {
        "true": "They ask for a refund or a reversed charge",
        "false": "They only ask a question or report a problem"
      }
    }
  }
}
```

**`Response`**

```json Response
{
  "model": "span-02",
  "answers": {
    "wants_refund": {
      "type": "noul",
      "noul": 0.99992687
    }
  },
  "usage": {
    "input_tokens": 134,
    "output_tokens": 0
  }
}
```

`noul` is the probability of yes, from 0 to 1. Pick your own cutoff, for example act when it's above 0.8.

## Score

Rate the state on a scale. `criteria` is a list of 2 to 10 levels, from low to high.

**`Request`**

```json Request
{
  "model": "span-02",
  "state": "Customer: This is the third time I've been charged twice. Fix it today or I'm cancelling.",
  "questions": {
    "urgency": {
      "type": "score",
      "instructions": "How urgent is this ticket?",
      "criteria": [
        "Low: can wait a few days",
        "Medium: answer today",
        "High: answer within the hour",
        "Critical: risk of losing the customer now"
      ]
    }
  }
}
```

**`Response`**

```json Response
{
  "model": "span-02",
  "answers": {
    "urgency": {
      "type": "score",
      "score": 2.9874902,
      "legend": {
        "0": "Low: can wait a few days",
        "1": "Medium: answer today",
        "2": "High: answer within the hour",
        "3": "Critical: risk of losing the customer now"
      },
      "probabilities": {
        "0": 4.360538e-05,
        "1": 0.00084280537,
        "2": 0.0106933145,
        "3": 0.98842025
      },
      "confidence": 0.98749024
    }
  },
  "usage": {
    "input_tokens": 151,
    "output_tokens": 0
  }
}
```

| Field           | Meaning                                                                                                     |
| --------------- | ----------------------------------------------------------------------------------------------------------- |
| `score`         | The probability-weighted level, `Σ level × p`. It can be fractional: 2.99 here is almost certainly level 3. |
| `legend`        | Each level's index and its text from `criteria`.                                                            |
| `probabilities` | Each level's probability.                                                                                   |
| `confidence`    | How concentrated the probabilities are around the most likely level: 0 for an even spread, 1 for one level. |

## Number

Ask for a number. There's no `criteria`: span-02 answers with the number itself, so you don't list candidate values.

**`Request`**

```json Request
{
  "model": "span-02",
  "state": {
    "order": {
      "items": [
        { "name": "Notebook", "qty": 3, "unit_price": 4.5 },
        { "name": "Pen", "qty": 10, "unit_price": 1.2 }
      ]
    }
  },
  "questions": {
    "total": { "type": "number", "instructions": "What is the order total in dollars?" }
  }
}
```

**`Response`**

```json Response
{
  "model": "span-02",
  "answers": {
    "total": {
      "type": "number",
      "number": 25.5,
      "text": "25.5",
      "confidence": 0.9990448
    }
  },
  "usage": {
    "input_tokens": 139,
    "output_tokens": 4
  }
}
```

| Field        | Meaning                                                                                                          |
| ------------ | ---------------------------------------------------------------------------------------------------------------- |
| `number`     | The answer as a number, or `null` if the model's text isn't a number.                                            |
| `text`       | The answer as the model wrote it.                                                                                |
| `confidence` | How sure span-02 is of the answer text: the average probability of its tokens (the geometric mean), from 0 to 1. |

A number answer is at most 32 tokens. A number question thinks only with `"mode": "on"` in `reasoning`; `auto` answers it without thinking.

## Mixing types

Put several questions in one request, of any types. They share the state, and the answers come back under your ids:

```json
"questions": {
  "team": { "type": "choice", "instructions": "Which team should handle this ticket?", "criteria": { "billing": "Billing", "technical": "Technical" } },
  "wants_refund": { "type": "noul", "instructions": "Does the customer want money back?" },
  "urgency": { "type": "score", "instructions": "How urgent is this ticket?", "criteria": ["Low", "Medium", "High"] },
  "charges": { "type": "number", "instructions": "How many charges does the customer mention?" }
}
```