AttestPage · Docs · Pricing · OpenAPI · llms.txt

Verify a document

Last updated: 2026-10-10

POST /v1/verify/document takes an answer or report as written, finds every quote in it with its link by fixed rules, and checks each pair on the live page, as Verify citations does: exact, fuzzy or none, score, offsets in your document and on the page, and the verdict on each page, under one signed receipt. Price: US$0.10 per part of up to 10 pairs.

Use it before sending a finished answer or report that quotes web pages. Call the free preview first: it lists the pairs, what was skipped and why, the number of parts and the exact price.

For a part of 1 to 9 pairs, one verify/quote call per pair costs less; the free preview lists each pair and its part.

Request

{
  "document": "WHO says \"Air pollution kills an estimated seven million people every year\" ([WHO](https://www.who.int/health-topics/air-pollution)).",
  "format": "markdown",
  "match": "fuzzy",
  "part": 0
}
FieldRequiredMeaning
documentyesThe answer or report as text, 1 character to 60,000 bytes UTF-8
formatnomarkdown (default) or text (only bare URLs and [n] references are links)
matchnofuzzy (default), exact or passages, as verify/citations; it also chooses what is found (below)
case_sensitivenodefault false; must be false with passages
thresholdno0.5 to 1, default 0.9 (fuzzy only)
min_wordsno1 to 20, default 4: a quoted span with fewer words is skipped as too_short
part_sizeno1 to 10, default 10: pairs per part. A free trial call needs 3 or fewer
partno0-based part to check, default 0. Ignored by the preview

Unknown fields are refused with 400. Every URL in the part is checked before payment, as on verify/citations: a blocked or robots-disallowed URL refuses the call with 400 or 403, details.field naming the pair (for example pairs[3].url), and nothing is charged.

Preview

POST /v1/verify/document/preview is free. Send the same body; nothing is fetched or charged.

{
  "document_sha256": "9f2c…",
  "extractor": "doc-v1",
  "pairs_total": 1,
  "part_size": 10,
  "parts": 1,
  "price": { "usd_per_part": "0.10", "sats_per_part": 100, "usd_total": "0.10", "sats_total": 100 },
  "pairs": [
    { "pair": 0, "part": 0, "quote": "Air pollution kills an estimated seven million people every year", "url": "https://www.who.int/health-topics/air-pollution", "doc_start": 10, "doc_end": 74, "source": "inline_link" }
  ],
  "skipped": [],
  "skipped_truncated": 0,
  "skipped_counts": {},
  "limit_reached": false
}

The preview takes from the same per-address limit as the paid routes and works on the edge server too.

Response

The verify/citations response for this part, plus the document fields:

{
  "document_sha256": "9f2c…",
  "extractor": "doc-v1",
  "part": 0, "parts": 1, "pairs_total": 1,
  "results": [
    { "pair": 0, "quote": "Air pollution kills…", "url": "https://www.who.int/…", "doc_start": 10, "doc_end": 74, "page": 0, "final_url": "…", "http_status": 200, "content_kind": "real", "match": "fuzzy", "score": 0.96, "start": 412, "end": 478, "context": "…", "occurrences": 1 }
  ],
  "pages": [ "as verify/citations" ],
  "summary": { "exact": 0, "fuzzy": 1, "none": 0, "failed": 0 },
  "receipt": "eyJ…",
  "tier": "paid"
}

How pairs are found

The rules are fixed and named by extractor (doc-v1) in every answer and receipt; a change gets a new name.

Fixes to doc-v1

Parts and price

Each paid call checks one part of up to 10 pairs, at US$0.10: the same price as a verify/citations batch.

DocumentCalls
4 quotes1
10 quotes1
23 quotes3

Limits

LimitValue
document60,000 bytes UTF-8 (400 over it)
Pairs per document100 (10 parts of 10); the rest are skipped as beyond_limit
Pairs per partpart_size, at most 10
Places listed per repeated pair20 in doc_spans; the rest counted in doc_spans_truncated
Skipped items listed100 in skipped; the rest counted in skipped_truncated
Quote or claim1,000 characters
Free-trial part3 pairs; a larger part gets the normal 402 offer (details.reason trial_too_large)

Matching shares its slots, queue and failure limit with verify/citations: 6 uncharged failed calls a minute per caller address across both routes, then 429 rate_limited (details.reason uncharged_failures); a full match queue gives 503 over_capacity with Retry-After. See Limits.

Charging

A part is charged when it is checked, including pages that are 404s, bot walls or timeouts, and a pair whose fuzzy work ran out (it carries an error). Never charged: any 400, 422 no_pairs (no quote with a link was found), 422 host_not_found (no URL in the part resolves), 422 match_too_costly (every pair in the part failed), 429, 503, and the edge server's 501 not_on_edge. See Payments.

Errors

See Errors. part past the last part gets 400 with details.parts.