Skip to content
Documentation/Verification

Check quotes in a batch

Check whether each quote appears in the source you provide.

Markdown
POST/api/v1/verify/batchhttps://api.webcite.co

When to use it

This checks source grounding. It does not independently search for evidence that the quoted assertion is true. Provide source_text, url, or asset_id for each quote. For retained evidence, supply all three immutable IDs: source_version_id, representation_id, and source_unit_id.

fuzzy and reflowed matches remain needs_review. Omit meaning when no assessment is available; the result reports not_checked. Caller-supplied meaning accepts only changed or ambiguous, never a self-certified faithful.

Per-item response example

Illustrative response, not a recorded API result.

json
[
  {
    "id": "1",
    "quote": "reduced HbA1c by 1.2%",
    "binding": {
      "grounded": true,
      "method": "fuzzy",
      "score": 0.67,
      "matched_text": "A 1.2% reduction in HbA1c was observed versus placebo."
    },
    "verification": {
      "layer": "bound",
      "band": "needs_review",
      "confidence": 80,
      "grounded": true,
      "meaning": "not_checked"
    },
    "feedback_token": "eyJxIjoi..."
  }
]

Prepared OCR example

Illustrative response, not a recorded API result.

json
[
  {
    "id": "ocr-example",
    "quote": "Revenue increased by 18 percent.",
    "binding": {
      "grounded": true,
      "method": "reflowed",
      "reading": "body",
      "score": 1,
      "matched_text": "Revenue increased\nAnnual report\nby 18 percent.",
      "rescue": {
        "attempted": true,
        "rescued": true,
        "reading": "Revenue increased by 18 percent.",
        "transformations": [
          {
            "kind": "drop",
            "atLine": 1,
            "line": "Annual report",
            "source": "element_label"
          },
          {
            "kind": "join",
            "afterLine": 0
          }
        ],
        "droppedLines": [
          "Annual report"
        ],
        "retainedSpans": [
          {
            "page": 1,
            "fromLine": 0,
            "toLine": 0
          },
          {
            "page": 1,
            "fromLine": 2,
            "toLine": 2
          }
        ],
        "calibrationKey": "illustrative-prepared-artifact-key",
        "basis": "code",
        "model": null,
        "decidedAt": "2026-09-19T00:00:00.000Z"
      }
    },
    "verification": {
      "layer": "bound",
      "band": "needs_review",
      "confidence": 80,
      "grounded": true,
      "meaning": "not_checked"
    },
    "feedback_token": "illustrative-token"
  }
]

Request

1 credit per item, up to 200 items.

Examples run on your server. Set WEBCITE_API_KEY first. Python examples use the requests package.

curl
curl --fail-with-body -X POST 'https://api.webcite.co/api/v1/verify/batch' \
  -H "x-api-key: $WEBCITE_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "items": [
    {
      "id": "revenue-2025",
      "quote": "Revenue was $12 million.",
      "source_text": "The annual report states: Revenue was $12 million."
    }
  ]
}'

Request body

itemsobject[]required

Claims to verify, each against its source. Bound back per item; a fuzzy match is capped at needs_review, never verified.

Show items fields
asset_idstring

An uploaded asset id to check against.

idstring

Caller id echoed back on the result.

meaningstring

A meaning-preservation problem you have already found, from an assessment such as POST /api/v2/context/assess-meaning. Only the cautious states are accepted: "changed" and "ambiguous" stop a citation presenting as verified. "faithful" is deliberately NOT accepted here , a clearance asserted by the party asking for the check is not a check, and this field exists precisely so that "nobody assessed this" cannot be mistaken for "an assessor cleared this". Omit it when you found no problem; the result then reports meaning "not_checked", which is what absence honestly means.

Values: "changed""ambiguous"

pagenumber

1-based page for an asset source.

quotestringrequired

The claim or quote to check.

representation_idstring
source_textstring

The source text to check the quote against. Provide this, or url, or asset_id.

source_unit_idstring
source_version_idstring

Immutable source version. Requires exact representation and unit IDs.

urlstring

A web source URL to resolve and check.

Response

An array of results, one per item. Each result includes binding, verification, and feedback_token. This endpoint returns an array, not an object with a top-level usage receipt.

200 response

application/json

Array of results:

bindingobjectrequired
Show binding fields
groundedbooleanrequired

True when the quote was found in the resolved source.

matched_quotestring

The matched substring, when grounded verbatim.

matched_textstring

The best-matching passage found in the source , present even when unbound, so a reviewer sees the closest evidence.

methodstringrequired

How the quote matched: exact/normalized substring, fuzzy passage match, reflowed OCR reading, or unbound.

Values: "exact""normalized""fuzzy""reflowed""unbound"

readingstring

Derived body reading with page furniture removed; absent for stored text.

Values: "body"

rescueobject

OCR rescue outcome: attempted=false with code/reason, attempted=true and rescued=false (optionally ambiguous), or rescued=true with transformations, raw dropped lines and retained spans. Unknown or unattempted is never a failed rescue.

Show rescue fields
Variant 1
attemptedbooleanrequired

Values: false

codestringrequired

Values: "not_ocr""labels_not_available""judge_unavailable""not_prepared""disabled""resource_limit"

reasonstringrequired
Variant 2
ambiguousboolean

Values: true

attemptedbooleanrequired

Values: true

rescuedbooleanrequired

Values: false

Variant 3
attemptedbooleanrequired

Values: true

basisstringrequired

Values: "code""measured"

calibrationKeystringrequired
decidedAtstringrequired
droppedLinesstring[]required
modelstring | nullrequired
readingstringrequired

Derived matching text; display the raw preview text instead.

rescuedbooleanrequired

Values: true

retainedSpansobject[]required
Show retainedSpans fields
fromLineintegerrequired
pageintegerrequired
toLineintegerrequired
transformationsobject[]required
Show transformations fields
afterLineinteger
atLineinteger
kindstringrequired

Values: "dehyphenate""join""drop"

linestring
sourcestring

Values: "element_label""repetition""page_number""margin_band"

scorenumber

Similarity of the best match, 0..1.

enginestring

Values: "context_graph"

errorstring
feedback_tokenstringrequired
idstring

Caller id echoed from the request.

judgmentobject
quotestringrequired
source_checkstring

Values: "read""not_read"

verificationobjectrequired
Show verification fields
bandstringrequired

Values: "verified""needs_review""unverified"

binding_methodstring

Values: "exact""normalized""fuzzy""reflowed""unbound"

confidencenumber | nullrequired
minimum: 0maximum: 100
groundedbooleanrequired
layerstringrequired

Values: "deterministic""bound""model""unbound"

meaningstringrequired

Values: "not_checked""faithful""changed""ambiguous"

review_reasonstring

Errors

For 400, check the request fields and source identifiers. For 401, check your API key. For 429, wait for the retry interval. See the errors guide before retrying a billable request.

401
Unauthorized - API key required
429
Rate limit exceeded
Error handling and retry guidance