Skip to content
Verification & evidenceVerify API

Verification & evidence

On this page
POST/api/v1/verify

Verify

Check data you already have against the page it claims to come from, field by field. The data can come from anywhere — another vendor’s extractor, your own scrape, a stored record. This is the same grounding check that runs inside every Contrie extraction, offered on its own. With html, pass baseUrl so relative links resolve as an extraction of that page would resolve them.

The same supplied data and the same source bytes produce the same verdict. Authentication (an API key or an OAuth sign-in) is required, and the call is rate-limited like any other.

What this answers, exactly

Verify answers is this value present in this page. It does not answer does the page say this about that. A value that is real but belongs to a different field still reads as grounded — a half-life copied from the wrong isotope row is on the page, so it passes.

It bounds invention, not correctness. Grounded means this value's text was located in the page text, and nothing more: strings are matched case-insensitive, with whitespace runs collapsed, links as the same URL, and numbers by value, so 31.0 matches 31. Ungrounded means this check did not locate it — usually because it is absent, but a value the page presents differently, or splits across elements, can also be missed. Unconfirmed is not proven wrong.

Parameters

Exactly one of url, html or text must be given; sending none or two is a 400.

ParameterTypeRequiredDescription
dataany JSONRequiredThe extracted data to check. Every leaf value is looked for in the source; objects and arrays are walked recursively.
urlstringOptionalPage to fetch and check the data against. Same fetch path and SSRF guard as /api/v1/scrape, redirects included.
htmlstringOptionalSource HTML, when you already have it. Checked against the supplied content. Without baseUrl, relative links stay relative: a relative href cannot ground an absolute URL value. Keep the whole request body under 4.5 MB (the hosting platform refuses larger bodies with HTTP 413).
baseUrlstringOptionalWith html only: the page the HTML came from. Resolves relative links the way an extraction of that page would. Never fetched.
textstringOptionalSource text, when you already have it. Used as-is. Keep the whole request body under 4.5 MB.
options.timeoutintegerOptionalFetch timeout in milliseconds, 1,000 to 30,000. Default 15,000. Only used with url.

Request

curl -X POST https://www.contrie.com/api/v1/verify \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $CONTRIE_API_KEY" \
  -d '{
    "url": "https://example.com/widget",
    "data": { "name": "Acme Widget", "sku": "XJ-9910-B", "inStock": true }
  }'

Response

200 OK
{
  "success": true,
  "grounding": 0.5,
  "verdict": "ungrounded-values",
  "coverage": { "total": 3, "checkable": 2, "grounded": 1, "ungrounded": 1 },
  "fields": [
    { "path": "$.sku", "value": "XJ-9910-B", "grounded": false },
    { "path": "$.name", "value": "Acme Widget", "grounded": true,
      "excerpt": "...acme widget — $24.99 in stock..." }
  ],
  "metadata": {
    "url": "https://example.com/widget",
    "source": "fetched",
    "credits": 0,
    "latencyMs": 310
  }
}

coverage is how much of the data the ratio speaks for. total counts every value that asserts something (nulls excluded), checkable how many of those carried enough text to look for. In the example above inStock: true is a claim no page text can confirm or deny, so it counts toward total but not toward the ratio. Coverage is counted over all values, so it is unaffected by the 50-entry cap on fields.

Verdicts

all-groundedEvery checkable value was found in the source.
ungrounded-valuesAt least one checkable value was not in the source. The offending values come first in fields.
nothing-checkableNo value carried enough evidence to check — booleans, nulls and very short strings. grounding is null, not 0.

A nothing-checkable verdict returns grounding: null rather than 0, because a zero there would read as “every value was invented” when it means “no evidence either way”.

Cost

Verify currently charges no customer credits — only the per-account rate limit applies. See Rate Limits.

The same check is available to agents over MCP as contrie_verify — see MCP. Extractions run through /api/v1/scrape carry the same evidence inline as metadata.groundingFields and metadata.groundingCoverage. That inline evidence shows local text support. You still need to check attribution, field meaning and freshness for consequential use.