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

# include_scores

> The switch that controls whether the probe runs, what it changes in the response, and what it costs.

Source: https://telluvian.ai/docs/include-scores

`include_scores` decides whether [verification](https://telluvian.ai/docs/scores.md) runs for a
request. It is a boolean and **defaults to `false`**. Use `probes` to specify
exactly which response probes to run when you opt in.

```json
{
  "model": "google/gemma-4-31b-it",
  "messages": [{"role": "user", "content": "Hello"}],
  "include_scores": true
}
```

Leave it out, or send `false`, and the request is an ordinary unscored
completion.

## What it changes

| | `true` (opt-in) | `false` (default) |
| --- | --- | --- |
| `choices[0].message.content` | the model's answer | the model's answer |
| `usage`, `finish_reason` | unchanged | unchanged |
| `scores`, the probe's output | present | `null` |
| `tokens`, the array those scores align to | present | `null` |
| `scores` on stream chunks | present | absent |
| Verification fee | $1.00 / 1M completion tokens | not charged |
| Latency | probe pass included | no probe pass |

**You always get the answer.** Only the two probe extensions go away.
`include_scores: false` is a request for an unscored completion, not for a
shorter one. The generation settings are unchanged, although separate sampled
requests can produce different answers.

`tokens` is the one to read carefully. It is not the completion: it is the
decoded text of each generated token, in order, such that joining it reproduces
`content` exactly. It exists so a score has something to point at, so it is
`null` when there are no scores. The text itself is in `content`, as always.

## Sending it

```bash
curl https://api.telluvian.ai/v1/chat/completions \
  -H "Authorization: Bearer $TELLUVIAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-31b-it",
    "messages": [{"role": "user", "content": "Hello"}],
    "include_scores": true
  }'
```

```python
# Must go through extra_body: the Python SDK validates arguments against the
# OpenAI schema and rejects unknown keyword arguments before sending.
response = client.chat.completions.create(
    model="google/gemma-4-31b-it",
    messages=[{"role": "user", "content": "Hello"}],
    extra_body={"include_scores": True},
)
```

```typescript
// Goes inline: the JS SDK forwards unknown top-level keys as-is.
const response = await client.chat.completions.create({
  model: 'google/gemma-4-31b-it',
  messages: [{ role: 'user', content: 'Hello' }],
  include_scores: true,
} as OpenAI.ChatCompletionCreateParamsNonStreaming & { include_scores: boolean });
```

> **A dropped opt-in means no verification**
>
> If `include_scores: true` does not reach the API, verification stays off.
> In Python use `extra_body`; check the response for scores rather than assuming
> a framework forwarded the field. A missing token score is not a score of zero.

## When to turn it on

Turn it on for anything a user reads as a factual claim.

Leave it off where the score would not change what you do:

- **Cheap intermediate steps** in a chain: dispatch, classification,
  reformatting, where nothing factual is being asserted.
- **Re-running a prompt you have already verified**, e.g. regenerating output
  from a template with the same facts.

## Choosing probes

Discover the probes loaded by the backend:

```bash
curl -sS https://api.telluvian.ai/v1/probes \
  -H "Authorization: Bearer $TELLUVIAN_API_KEY"
```

Use IDs from the response's `data` array in `probes`. This works with both a
named generation model and `telluvian/gallery-1`, on Chat Completions and the
Responses API:

```json
{
  "model": "telluvian/gallery-1",
  "messages": [{"role": "user", "content": "When was the Eiffel Tower built?"}],
  "include_scores": true,
  "probes": ["hallucination"]
}
```

With probing enabled, omitting `probes` runs all loaded probes. A non-empty
list selects only those probes; unknown names return `400`. An empty list
disables probing and its surcharge. Supplying names alone does not enable
probing: `include_scores: true` is still required.

| Request fields | Response probes run |
| --- | --- |
| `include_scores` omitted or `false` | None, even if `probes` names a probe |
| `include_scores: true`, `probes: ["hallucination"]` | Only `hallucination`, if available |
| `include_scores: true`, `probes` omitted or `null` | All currently loaded response probes |
| `probes: []` | None; no verification surcharge |
| `include_scores: true`, an unknown probe ID | Request rejected with `400` |

**Use an explicit list when you want a fixed set of probes.** The set selected
by omitting `probes` can change as probes are loaded. `GET /v1/probes` lists
available probes, not probes automatically enabled for your requests. Read
each entry's `id` and `description`; do not assume that a name shown in an
example is available on every deployment.

Gallery's routing probe selects the generation model. It is separate from
these optional response probes: using `telluvian/gallery-1` does not enable
hallucination detection or add response probe scores.

Each selected probe's ID is also its key in `scores`. In the Python SDK, pass
both controls through `extra_body`, for example
`extra_body={"include_scores": True, "probes": ["hallucination"]}`.
The older `probe_path` selector is deprecated and only accepts an already
loaded probe; it cannot load arbitrary files or be combined with `probes`.

## Per-request, not per-key

There is no account-level setting. Each request decides for itself, so a single
API key can serve both scored and unscored traffic. One client can verify
user-facing answers while another skips the probe for internal bookkeeping.

## Verifying what you got

The honest check is the response itself, not the request you think you sent:

```python
response = client.chat.completions.create(
    model="google/gemma-4-31b-it",
    messages=[{"role": "user", "content": "Hello"}],
    extra_body={"include_scores": True},
)

assert response.scores is not None, "the opt-in was dropped: no verification ran"
```

Your usage records also carry the per-request cost, so a scored request is
visible in [the dashboard](https://telluvian.ai/dashboard) as a higher `cost_micros` than an
unscored one with the same token counts.
