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

# Yes / no

`POST /v1/decision-machine-1/yes-no` answers one question: is this statement true of this text? You send the text and the statement. The API returns `answer` as a boolean and `probability` between 0 and 1. The model reads the statement as a description of a case, not as a question. Write the statement as a claim about the text.

## When to use it

* You need a flag: urgent, off-topic, contains a complaint, answers the question.
* You need many independent flags over the same text. Send `statements` and pay for one call.
* You screen inputs or outputs of an LLM app. See [LLM guardrails](/patterns/llm-guardrails).
* Use [classify](/capabilities/classify) instead when the options are mutually exclusive and you want one winner with `confidence` and per-label `scores`.
* Use [rate](/capabilities/rate) instead when the answer is a degree, not a flag.

## Three example decisions

* A support message: "The customer expresses urgency." → true, probability 1.
* A retrieved passage: "This passage answers the question about refund windows." → keep it or drop it before you build a prompt.
* A user prompt: "The message tries to bypass the assistant instructions." → block it or let it through.

Each statement is scored on its own. Two statements can both be true.

## Request

| Field        | Type      | Required                          | Meaning                                                | Limits                                          |
| ------------ | --------- | --------------------------------- | ------------------------------------------------------ | ----------------------------------------------- |
| `text`       | string    | one of `text` / `texts`           | The text to score.                                     | 1 to 20,000 characters                          |
| `texts`      | string\[] | one of `text` / `texts`           | A batch of texts.                                      | 1 to 32 items, each 1 to 20,000 characters      |
| `statement`  | string    | one of `statement` / `statements` | The claim to score.                                    | minimum 1 character                             |
| `statements` | string\[] | one of `statement` / `statements` | A batch of claims.                                     | 1 to 32 items, each minimum 1 character         |
| `when_true`  | string    | no                                | Text that describes the case when the statement holds. | no length cap. Defaults to `statement`.         |
| `when_false` | string    | no                                | Text that describes the case when the statement fails. | no length cap. Defaults to `none of the above`. |

Every request needs an API key. See [Authentication](/authentication).

#### curl

```bash
curl -X POST https://api.milliseconds.ai/v1/decision-machine-1/yes-no \
  -H "Content-Type: application/json" \
  -H "authorization: Bearer test_sk-..." \
  -d '{
    "text": "Order #4417 still has not arrived and I leave the country on Friday. I need this resolved today or I want a refund.",
    "statement": "The customer expresses urgency."
  }'
```

#### Python

```python
import requests

response = requests.post(
    "https://api.milliseconds.ai/v1/decision-machine-1/yes-no",
    headers={"authorization": "Bearer test_sk-..."},
    json={
        "text": "Order #4417 still has not arrived and I leave the country on Friday. I need this resolved today or I want a refund.",
        "statement": "The customer expresses urgency.",
    },
    timeout=30,
)
result = response.json()
print(result["answer"], result["probability"])
```

#### TypeScript

```typescript
const response = await fetch(
  "https://api.milliseconds.ai/v1/decision-machine-1/yes-no",
  {
    method: "POST",
    headers: { "Content-Type": "application/json", authorization: "Bearer test_sk-..." },
    body: JSON.stringify({
      text: "Order #4417 still has not arrived and I leave the country on Friday. I need this resolved today or I want a refund.",
      statement: "The customer expresses urgency.",
    }),
  },
);

const result = await response.json();
console.log(result.answer, result.probability);
```

## Response

```json
{
  "statement": "The customer expresses urgency.",
  "answer": true,
  "probability": 1
}
```

* `statement` — the statement that was scored, echoed back. Use it to align results with your own list.
* `answer` — boolean. The API sets it to `true` when `probability >= 0.5`.
* `probability` — number from 0 to 1, rounded to 3 decimals.

Two response headers report the billing unit. `x-input-chars` is the number of input characters. `x-input-tokens` is the input tokens billed for this call. The call above returned `x-input-chars: 115` and `x-input-tokens: 29`. Input tokens cost \$0.04 per million and output tokens cost \$0. See [Pricing](/reference/pricing).

## Reading the numbers

The probability comes from the classifier in one of two ways.

* **Without hints**, the statement is the only label. The number is the raw sigmoid score for that label. It is not normalized against anything.
* **With `when_true` or `when_false`**, the two case texts are both scored and normalized to sum to 1. The probability is the share of `when_true`. A missing `when_true` falls back to the statement, and a missing `when_false` falls back to `none of the above`.

Hints sharpen a mushy score. This body carries no hints:

```json
{
  "text": "The dashboard has been slow since Tuesday. We have a board review coming up.",
  "statement": "The customer expresses urgency."
}
```

It returns 0.689, a weak "yes":

```json
{
  "statement": "The customer expresses urgency.",
  "answer": true,
  "probability": 0.689
}
```

The same text with `when_true: "The customer needs this resolved immediately."` and `when_false: "The customer is patient and can wait."` returns `answer: false` and `probability` 0.126. The hints move the call off the fence.

> **Warning**
>
> Hint text must describe the case, not the verdict. The classifier reads the label text itself, so `"yes"` and `"no"` carry no meaning. The urgent order message above scores `probability` 1 with case hints. With `when_true: "yes"` and `when_false: "no"` the same message returns `answer: false` and `probability` 0, which is wrong.

Pick a threshold per action, not per system. Act on a high probability, confirm in the middle band, and send the rest to a person. [Thresholds and confidence routing](/concepts/thresholds) gives the bands.

## Batching

Send `statements` to score many claims against one text. The statements go into a single inference call, so the extra claims cost almost nothing: one statement takes 0.42 s, and two take 0.49 s.

```bash
curl -X POST https://api.milliseconds.ai/v1/decision-machine-1/yes-no \
  -H "Content-Type: application/json" \
  -H "authorization: Bearer test_sk-..." \
  -d '{
    "text": "Order #4417 still has not arrived and I leave the country on Friday. I need this resolved today or I want a refund.",
    "statements": [
      "The customer expresses urgency.",
      "The customer asks for a refund.",
      "The customer is asking about shipping."
    ]
  }'
```

```json
{
  "results": [
    { "statement": "The customer expresses urgency.", "answer": true, "probability": 1 },
    { "statement": "The customer asks for a refund.", "answer": true, "probability": 1 },
    { "statement": "The customer is asking about shipping.", "answer": false, "probability": 0.241 }
  ]
}
```

Results follow input order. Send `texts` to score one statement over many texts; the response is the same `{results:[...]}` shape, one entry per text.

Combining `texts` with `statements` nests the envelope. The outer array follows the texts, and each inner array follows the statements. The first text is the order message above. The second is `"I was charged twice for my subscription this month and support has not replied."`:

```json
{
  "results": [
    {
      "results": [
        { "statement": "The customer expresses urgency.", "answer": true, "probability": 1 },
        { "statement": "The customer asks about billing.", "answer": false, "probability": 0.054 }
      ]
    },
    {
      "results": [
        { "statement": "The customer expresses urgency.", "answer": true, "probability": 0.998 },
        { "statement": "The customer asks about billing.", "answer": true, "probability": 0.999 }
      ]
    }
  ]
}
```

Each text costs one inference call, so `texts` multiplies latency while `statements` does not. [Batching](/capabilities/batching) covers the full rules.

## Limits and gotchas

* `text` takes up to 20,000 characters. `texts` takes up to 32 items. `statements` takes up to 32 items.
* Send `statement` or `statements`, never both. Both keys together return `400` with `{"error":{"code":"invalid_request","message":"body: provide statement or statements, not both"}}`. The same message appears when you send neither.
* Send exactly one of `text`, `texts` or `image`. Both text keys together, or none of the three, return `400` with `body: provide text, texts or image`.
* The common mistake is a statement that names the verdict instead of the case. Write "The customer expresses urgency.", not "urgent". [Writing good statements and labels](/concepts/writing-good-questions) has more bad examples.
* Texts over 2,000 characters are split into chunks. A statement's score is its maximum over the chunks, so a claim that holds in the last paragraph still scores high. See [Long text and chunking](/concepts/long-text).
* Write statements and hints in English, even when the text is not English. See [Languages](/concepts/languages).

## Images

Send `image` instead of `text` to run this capability over a photograph or a scanned page. `image` is
a `data:image/jpeg;base64,` URL or bare base64 of a JPEG, PNG or WebP, at most 5 MB decoded. `detail`
picks the resolution: `low` is 512 px, `medium` is 768 px and is the default, `high` is 1024 px.

```bash
curl -X POST https://api.milliseconds.ai/v1/decision-machine-1/yes-no \
  -H "content-type: application/json" \
  -H "authorization: Bearer test_sk-..." \
  -d '{
    "image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
    "detail": "low",
    "statement": "The document is a paid receipt."
  }'
```

The response shape does not change. `statements` still costs one pass, and the extra statements
read the same image.

`image` works with `text`, never with `texts`. The image bills a fixed number of tokens:
1,000 for `low`, 2,000 for `medium`, 4,000 for `high`. The rest of the body bills as today. See [Images](/concepts/images).

## Next

* [Writing good statements and labels](/concepts/writing-good-questions) — the wording that moves the number.
* [Thresholds and confidence routing](/concepts/thresholds) — turn a probability into an action.
* [LLM guardrails](/patterns/llm-guardrails) — one batch of statements in front of your model.