---
title: "Check one claim"
summary: "Check a single claim against evidence sent in the request or against a loaded batch, and get a verdict with the spans it rests on."
category: "developer"
tags: ["attest", "reference", "claim", "verdict", "evidence", "batch"]
updated: "2026-09-14T04:25:09.790Z"
url: "https://support.quorumtech.ch/articles/attest-check-claim"
markdown: "https://support.quorumtech.ch/articles/attest-check-claim.md"
---

# Check one claim

`POST https://api.quorumtech.ch/attest/v1/attest`

Checks a single claim against evidence passed inline, or against a batch loaded earlier with
`POST /attest/v1/batch` or `POST /attest/v1/batches`. Provide one or the other.

Spends one claim of the key's daily budget.

This is the call to start with. Send one assertion and the passages it was written from, and read the verdict, the supporting and contradicting span ids, the explanation and the provenance block. Send one assertion at a time: a compound sentence gets one verdict for the whole, which cannot say which half failed.

Provide `evidence` or `batchId`, never both. With `evidence`, one model call reads exactly what you sent. With a `batchId` from an earlier upload, Attest searches the batch for the passages that bear on the claim and returns them in `cited` with their text, so the citation needs no document on your side.

`kind` tells Attest what sort of statement it is checking. An `assertion` is checked against the evidence. A `synthesis` combines several facts. A `judgement` is an opinion, which evidence can inform but not settle. `glossary` defines what the draft means by a term and can never assert that anything is true. `reviewDate` fixes the date a claim about elapsed time is judged as of, so the answer is reproducible later.

```json
{
  "claim": "Revenue rose to CHF 94m and operating margin improved.",
  "evidence": [
    {
      "id": "ev_1",
      "content": "Group revenue for FY2025 was CHF 94.0m, up from CHF 82.0m in the prior year.",
      "source": { "title": "FY2025 Annual Report" }
    }
  ]
}
```

That example returns `PARTIALLY_SUPPORTED`: the revenue half holds on `ev_1:0`, and the margin half is unverified because the evidence says nothing about it. Change the claim to "Revenue rose to CHF 94m." for `SUPPORTED`.

## Request

Provide either `evidence` or `batchId`. Attest never retrieves, so with neither there is nothing to judge against.

A JSON body with these fields:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `claim` | string | yes | The statement to check. One assertion reads best; split compound sentences. 1 to 4,000 characters. |
| `evidence` | Evidence[] | no | The documents to check against, inline. Ids must be unique. At most 50 items. |
| `evidence[].id` | string | no | Your identifier for this item, unique within the request. Spans are cited as `<id>:<ordinal>`, for example `ev_1:0`. Assigned as `ev_<n>` when omitted. 1 to 64 characters. Pattern `^[A-Za-z0-9_.-]+$`. |
| `evidence[].content` | string | yes | The evidence text. Total across all items is capped at 200,000 characters. |
| `evidence[].source` | EvidenceSource | no | Where a piece of evidence came from. Shown in citations; never used to retrieve anything. |
| `evidence[].source.title` | string | no | At most 500 characters. |
| `evidence[].source.uri` | string | no | At most 2,000 characters. |
| `evidence[].source.author` | string | no | At most 200 characters. |
| `evidence[].source.publishedAt` | string | no | When the source was published, in any recognisable date form. At most 64 characters. |
| `evidence[].source.retrievedAt` | string | no | At most 64 characters. |
| `batchId` | string | no | Check against a batch loaded earlier instead of inline evidence. |
| `kind` | `assertion` or `synthesis` or `judgement` | no | What kind of statement this is, which decides how it is checked. An assertion is checked against the evidence; a synthesis combines several facts; a judgement is an opinion, which evidence can inform but not settle. Default `"assertion"`. |
| `glossary` | object of string | no | What the draft means by particular words. Definitions only; a glossary cannot assert that anything is true. |
| `reviewDate` | string | no | The date the review is taken as of, so a claim about elapsed time is reproducible. At most 40 characters. |
| `config` | object | no |  |
| `config.explain` | boolean | no | Include the span-cited explanation and the audit block. Off returns the verdict alone; the spans come from the reading, so they are empty too. Default `true`. |

## Example request

```bash
curl -X POST "https://api.quorumtech.ch/attest/v1/attest" \
  -H "Authorization: Bearer $QUORUM_API_KEY" \
  -H "content-type: application/json" \
  -d '{
  "claim": "Revenue rose to CHF 94m and operating margin improved.",
  "evidence": [
    {
      "id": "ev_1",
      "content": "Group revenue for FY2025 was CHF 94.0m, up from CHF 82.0m in the prior year.",
      "source": {
        "title": "FY2025 Annual Report"
      }
    }
  ]
}'
```

## Responses

### 200

A verdict was produced.

Every shape below carries these fields:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | This verification's id. |
| `verdict` | `SUPPORTED` or `PARTIALLY_SUPPORTED` or `INSUFFICIENT_EVIDENCE` or `CONTRADICTED` or `DISPUTED` or `INDETERMINATE` | Always relative to the supplied evidence. `SUPPORTED`: consistent with the documents. `PARTIALLY_SUPPORTED`: part of the claim is established and part is not; the one to watch. `INSUFFICIENT_EVIDENCE`: the documents do not speak to it. `CONTRADICTED`: the documents say otherwise. `DISPUTED`: the documents disagree with each other. `INDETERMINATE`: Attest could not measure; returned with 503, never as a finding. |
| `usage` | Usage | What this response cost at the model provider. Zeros for a replay. |
| `usage.calls` | integer | Completions made. |
| `usage.promptTokens` | integer | Tokens sent. |
| `usage.completionTokens` | integer | Tokens returned. |
| `usage.cachedTokens` | integer | Prompt tokens served from the provider's cache. |
| `usage.latencyMs` | integer | Wall time waiting on the provider. |
| `usage.fellBack` | integer | Calls the preferred tier shed to the fallback. |
| `claim` | string |  |
| `supportingSpans` | string[] | Span ids (`<evidence id>:<ordinal>`) that support the claim. |
| `contradictingSpans` | string[] |  |
| `degraded` | string[] | Anything that could not run as designed, named. Empty on a clean run. |
| `provenance` | Provenance | Every version and hash that produced the answer, so it can be replayed and audited. |
| `provenance.measurementHash` | string | SHA-256 over the canonical claim, the evidence and the measurements. |
| `provenance.policyHash` | string | SHA-256 over the deterministic decision policy that produced the verdict. |
| `provenance.rulesApplied` | string[] | The reading rules routed to this claim. |
| `provenance.promptVersion` | string |  |
| `provenance.scoringVersion` | string |  |
| `provenance.serviceVersion` | string |  |
| `provenance.model` | string |  |
| `provenance.createdAt` | string (date-time) |  |
| `provenance.mode` | `evidence` or `batch-agent` |  |
| `provenance.cachedFrom` | string | The id of the response whose measurement this one replays; `createdAt` is that measurement's time. A replay runs no models and costs nothing. |
| `audit.findings` | string[] |  |

#### Evidence mode result

The result of checking against inline evidence.

| Field | Type | Description |
| --- | --- | --- |
| `mode` | `evidence` |  |
| `explanation` | object | The span-cited explanation. Null when `config.explain` was false. May be null. |
| `explanation.axes` | object of any | Per validation axis, the propositions of the claim and how each was marked, citing span ids. |
| `explanation.citedSpans` | string[] |  |
| `explanation.availableSpans` | integer |  |
| `explanation.axesRun` | string[] |  |
| `explanation.axesExpected` | string[] |  |
| `audit` | object | Deterministic checks over the explanation. May be null. |
| `audit.referentialIntegrity` | number | Share of citations that name real spans, from 0 to 1. |
| `audit.explanationTrust` | number |  |
| `audit.explanationDisagrees` | boolean | True when the explanation and the verdict point different ways; the verdict stands, the explanation is flagged. |

#### Batch mode result

The result of checking against a loaded batch, where Attest searched the documents itself.

| Field | Type | Description |
| --- | --- | --- |
| `mode` | `batch` |  |
| `cited` | object[] | The spans the verdict rests on, with their text and which way each cuts. |
| `cited[].id` | string |  |
| `cited[].section` | string | The heading the span sits under, when the document had one. May be null. |
| `cited[].text` | string |  |
| `cited[].role` | `supports` or `contradicts` |  |
| `explanation` | object |  |
| `explanation.reasoning` | string |  |
| `explanation.unverifiedAssertions` | string[] | The parts of the claim nothing in the batch establishes. The actionable output. |
| `explanation.searchedThoroughly` | boolean |  |
| `explanation.trace` | object[] | What was searched and read, in order. |
| `explanation.trace[].tool` | string |  |
| `explanation.trace[].input` | string |  |
| `explanation.trace[].resultSummary` | string |  |
| `explanation.steps` | integer |  |
| `audit` | object |  |
| `audit.referentialIntegrity` | number |  |
| `batch` | object |  |
| `batch.id` | string |  |
| `batch.batchHash` | string |  |
| `batch.documents` | integer |  |
| `batch.spans` | integer |  |

## Errors

The body is `{ "error": { "code", "message" } }`; the full catalogue with what to do about each code is on the Errors page.

| Status | Codes | When |
| --- | --- | --- |
| 400 |  | The request does not match the schema. `error.issues` names each failing field. |
| 401 |  | The key is missing, not recognised, or revoked. |
| 402 | `payment_required`, `credits_exhausted`, `remaining`, `needed` | The workspace has no active API subscription (`payment_required`), or is prepaid and has no credits left for this request (`credits_exhausted`, with `remaining` and `needed`). Manage billing and add credits at https://developer.quorumtech.ch/billing. |
| 403 |  | The key is not scoped to Attest. |
| 404 |  | The `batchId` names no loaded batch. Batches age out; upload again. |
| 429 | `rate_limited`, `claims_rate_limited`, `claim_budget_exhausted`, `monthly_cap_reached`, `cap` | Over the key's requests-per-minute limit (`rate_limited`), its claims-per-minute ceiling (`claims_rate_limited`), its claims-per-day budget (`claim_budget_exhausted`), or, for a postpaid workspace, its monthly credit cap (`monthly_cap_reached`, with `cap` and `resetsAt`). `Retry-After` says when to try again; the daily budget resets at midnight UTC and the cap on the first of the month. |
| 502 |  | The model provider behind Attest failed. Retry. |
| 503 |  | Attest could not measure (`INDETERMINATE`), which is a server-side failure rather than a finding about the claim, or the evaluator is not configured. Never read this as a verdict. |

## Cost

One credit ($0.01) with the evidence in the request, two ($0.02) against a loaded batch, explained or not. A refused or failed request charges nothing.
