Skip to main content

Citations & Verification

Every ask answer carries per-claim citations with exact source spans, app deep links, and a post-answer verification verdict: supported, issues, or unverifiable.

An answer you cannot check is an answer you cannot ship. Every completed ask therefore carries two trust layers: citations, which bind each load-bearing claim in the answer to an exact span in a source document, and verification, a post-answer pass that re-checks the answer's claims against the evidence the turn itself collected and ships a verdict alongside the answer. Together they turn "the model said so" into "this document says so, and a second pass agrees".

The citations array

Citations appear twice in the completed payload, and they always agree: inline in the answer markdown as links, and structured in the citations array, which is parsed from those same links. Each entry binds one quoted claim to one source document.

Citation fields

quotestringThe claim text the citation grounds, as it appears in the answer.
document_iduuidThe source document. Resolvable via GET /v1/documents/:id, and its extracted fields via GET /v1/documents/:id/fields.
kindstringfield or quote. field cites a captured field's provenance span; quote cites a verbatim passage of document text.
referencestringFor kind field: the cited field key. For kind quote: the quoted search text.
app_urlstringAbsolute deep link into the Talonic app that opens the document with the cited span highlighted.

The two kind values reflect the two evidence planes an ask draws from. A field citation points at a captured field: a value that was extracted at ingestion, bound to a canonical concept in the field registry, and carries provenance back to the exact span it was read from. A quote citation points at verbatim document text the agent found through the chunk index, for claims that live in prose rather than in a structured value. A well-grounded answer about contract terms typically mixes both: field citations for amounts and dates, quote citations for clause language.

A mixed citations array

"citations": [
  {
    "quote": "EUR 96,000",
    "document_id": "1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
    "kind": "field",
    "reference": "contract_value",
    "app_url": "https://app.talonic.com/documents/1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d?cite=contract_value"
  },
  {
    "quote": "either party may terminate with ninety (90) days written notice",
    "document_id": "1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
    "kind": "quote",
    "reference": "either party may terminate with ninety (90) days written notice",
    "app_url": "https://app.talonic.com/documents/1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d?citeq=either%20party%20may%20terminate%20with%20ninety%20(90)%20days%20written%20notice"
  }
]

The app_url is built for human review handoff: opening it lands a reviewer inside the Talonic document viewer with the cited span highlighted, so "check this claim" is one click, not a search. If you are building your own UI, render quote as the visible citation text and use app_url as its href; users signed in to the workspace get the highlighted source instantly. For programmatic verification, document_id plus reference lets you re-fetch the same evidence over the API: [GET /v1/documents/:id/fields](get-document-fields) returns the captured field with its value and confidence for field citations.

Verification verdicts

After the answer is written, a separate verification pass decomposes it into individual claims and re-checks each one against the tool evidence the turn actually gathered: the SQL results, the retrieved spans, the coverage numbers. The result ships as the verification object with a three-value verdict, the check counts, and, when the pass found a fixable discrepancy, a suggested correction.

Verification object

verdictstringsupported: every checked claim is backed by the turn's evidence. issues: at least one claim did not match the evidence. unverifiable: the claims could not be checked against the gathered evidence.
checks_totalintegerHow many claims the pass checked.
checks_unsupportedintegerHow many of them it could not support.
correctionstringPresent only when the pass produced a corrected statement for the unsupported claims.

Treat the verdict as routing signal, not as ground truth. supported means the answer and the evidence agree, which is the normal case and safe to pass through automatically. issues is a review pointer: it does not prove the answer wrong, it flags that a second reading of the evidence disagreed with at least one claim, so route the answer to a human, show the correction if present, and lean on the citation deep links for the check. unverifiable usually means the answer is analytic or aggregative in a way the claim-checker could not bind to specific evidence; weigh it by how much your use case tolerates unreviewed synthesis. verification can also be null when no verdict was produced; treat that like unverifiable.

The verification pass checks the answer against the evidence this turn collected, not against the whole corpus from scratch. It catches the model contradicting its own sources, which is the dominant hallucination mode, but it is a safety net, not a substitute for the citations themselves.

Coverage statements: evidence-backed absence

The hardest answer for a retrieval system is "it is not there": plain RAG cannot distinguish "not in the top-k chunks" from "not in the corpus". Talonic's coverage plane can, because ingestion structures every document. When the agent answers "none of the 421 agreements in the workspace contains an exclusivity clause", the denominator comes from real corpus coverage and the absence claim is checked over the structured plane plus full-text search, not over a retrieval sample. Negative answers therefore arrive with the same confidence machinery as positive ones, and the verification pass checks them the same way.

Handling verdicts in code