---
title: "Cancel a review"
method: POST
path: "/api/v1/reviews/{review_id}/cancel"
tags: ["Review"]
---

# Cancel a review

`POST /api/v1/reviews/{review_id}/cancel`

## Request

- Base URL: `https://lenz.io`
- URL: `https://lenz.io/api/v1/reviews/{review_id}/cancel`
- Auth: HTTP bearer

Stop a review: its quick checks, its deep checks and its citation
checks. Returns the review as it stands afterwards, `status: cancelled`.

You are charged only for what it delivered before the cancel: quick
checks it served, deep checks that finished, citations it checked. The
rest is refunded or never charged. A review that had already finished is
returned unchanged (`completed` or `failed`), so the body always says
what happened; cancelling again is safe. A review's deep check cannot be
cancelled on its own (`POST /verify/{task_id}/cancel` answers 409
`use_review_cancel`): cancel the review.

**Versions.** 200: `2026-10-11` receives `ReviewFullOut`, `2026-05-13` receives `ReviewFullOutLegacy`; 403: `2026-10-11` receives `ReviewErrorOut`, `2026-05-13` receives `ReviewErrorOutLegacy`; 404: `2026-10-11` receives `ReviewErrorOut`, `2026-05-13` receives `ReviewErrorOutLegacy`; 410: `2026-10-11` receives `ReviewErrorOut`, `2026-05-13` receives `ReviewErrorOutLegacy`; default: `2026-10-11` receives `ErrorOut`, `2026-05-13` receives `ErrorOutLegacy`.

## Path parameters

- `review_id` string, required

## Headers

- `X-Lenz-API-Version` string

## Response `200`

OK

- ReviewFullOut
  - `review_id` string, required
  - `status` 'queued' | 'assessing' | 'verifying' | 'completed' | 'failed' | 'cancelled', required: verifying: deep checks or citation checks are running. cancelled: you cancelled it (POST /reviews/{review_id}/cancel); only what it delivered before that is charged.
  - `outcome` 'clean' | 'issues_found' | 'incomplete' | 'unchecked', nullable, required: Null until terminal. clean covers the selected claims at the policy's chosen depth. issues_found with an empty issues[] means the rows are in citation_issues[]. A deep check that reads "No Public Record" is an issue (not on the public record).
  - `created_at` string, required
  - `completed_at` string, nullable, required
  - `language` string, required: The language the review is written in, as an ISO 639-1 code. `auto` only while a review sent with `language: "auto"` on a draft that is one URL has not read its page yet; then the detected code, or `en` when the page could not be read.
  - `policy` ReviewPolicyOut, required
    - `verdicts` string[], required
    - `confidence` string[], required
    - `max_verifications` integer, required
    - `max_assessments` integer, required
    - `depth` 'standard' | 'low', required
    - `max_citations` integer
    - `suggest_edits` boolean
  - `summary` ReviewSummaryOut, required
    - `claims_found` integer, nullable, required: Claims found in the draft and traced back to it; null until the draft is read.
    - `claims_selected` integer, nullable, required: Claims this review works on; null until the draft is read.
    - `claim_limit` integer, required: The resolved max_assessments.
    - `claim_limit_exceeded` boolean, nullable, required: True when claims_found is more than claim_limit: the rest are in more_claims, found and not checked. False when every claim found was selected. Null until the draft is read.
    - `input_truncated` boolean, required
    - `assessments` ReviewAssessmentCountsOut, required
      - `completed` integer, required
      - `failed` integer, required
    - `verifications` ReviewVerificationCountsOut, required
      - `planned` integer, required
      - `completed` integer, required
      - `failed` integer, required
    - `issues` integer, required
    - `citations_found` integer, nullable: Citations with a URL or DOI in the text the review read (after the 50,000 character cut); null until the draft is read, or when the check was not asked.
    - `citations_selected` integer, nullable: The ones this review works on: the first in the draft's order.
    - `citation_limit` integer, nullable: The resolved cap.
    - `citation_limit_exceeded` boolean, nullable: True when citations_found is more than citation_limit: the rest are in more_citations, found and not checked. False when every citation found was selected, exactly citation_limit included. Null until the text is read.
    - `citation_checks` ReviewCitationCountsOut: Three disjoint counts; once every check has ended they add up to citations_selected.
      - `checked` integer, required: A finding other than unchecked.
      - `unchecked` integer, required: Could not be checked, for a reason of the page or the draft.
      - `failed` integer, required: No finding, for a reason of ours.
    - `citation_issues` integer: Rows in citation_issues[]; 0 when the check was not asked.
    - `citations_skipped` 'url_input' | 'switched_off' | 'insufficient_credits', nullable: Why the check was asked for and did not run.
    - `claim_limit_reached` boolean, nullable: Sent only to callers on `2026-05-13`; use `claim_limit_exceeded`. It was true when `claims_found` was at least `claim_limit`, not more than it.
    - `citation_limit_reached` boolean, nullable: Sent only to callers on `2026-05-13`; use `citation_limit_exceeded`.
  - `credits` ReviewCreditsOut, required
    - `charged` integer, required: Net credits this review cost the account, read from the ledger. Authoritative once no deep check is running.
  - `poll_after_seconds` integer, nullable, required
  - `issues` ReviewIssueOut[], required
    - `claim_index` integer, required
    - `claim` string, nullable, required
    - `verified_claim` string, nullable, required
    - `verdict` 'True' | 'Mostly True' | 'Mixed' | 'Mostly False' | 'False' | 'No Public Record', required
    - `confidence` 'low' | 'medium' | 'high', nullable, required
    - `source` 'assessment' | 'verification', required
    - `verification_id` string, nullable, required
    - `verification_status` 'processing' | 'completed' | 'failed' | 'cancelled', nullable, required
    - `verification_url` string, nullable, required
    - `url` string, nullable, required
    - `escalation` ReviewEscalationOut, required
      - `matched_rules` string[], required
      - `disposition` 'not_selected' | 'planned' | 'cap' | 'credits' | 'account_cap', required
    - `key_finding` string, nullable, required
    - `rationale` string, nullable, required
    - `suggested_rewrite` string, nullable, required: The rewrite the row's edits come from: its completed deep check's, else (with `escalate.suggest_edits`) its quick check's; `source` says which. A suggestion, not itself verified.
    - `failure` FailureOut, required: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
      - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
      - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
      - `hint` string, nullable: What to send next; null when there is nothing to change.
      - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
      - `retryable` boolean, required
      - `docs_url` string, nullable, required
    - `suggested_edits` ReviewSuggestedEditsOut: The smallest edits to the draft that make it say what the claim's deep check rewrite says, in the draft's language. Review content, never part of the verification: a verification is shared, your draft is not.
      - `status` 'pending' | 'completed', required: `pending` while they are computed (poll the review); `completed` once SETTLED, which includes settling on no edit (`edits: []`).
      - `edits` SuggestedEditOut[], nullable, required: `null` while pending; `[]` when settled with no edit (the passage could not be edited safely, no edit passed the checks, or computing it failed on our side). Not itself verified: review it before you use it.
        - `start` integer, required: Where the replaced span starts in `text` as you sent it, in Unicode code points. Half-open with `end`, inside `positions[position]`.
        - `end` integer, required: Where the replaced span ends, exclusive.
        - `text` string, required: Exactly the slice of `text` at `start`..`end`, as you sent it.
        - `position` integer, required: Which of the claim row's `positions` the edit sits in (index); a grouping hint.
        - `replacement` string, required: What replaces it; '' deletes it.
  - `failures` ReviewFailedRowOut[], required
    - `claim_index` integer, required
    - `claim` string, nullable, required
    - `stage` 'assessment' | 'verification', required
    - `failure` FailureOut, required: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
      - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
      - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
      - `hint` string, nullable: What to send next; null when there is nothing to change.
      - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
      - `retryable` boolean, required
      - `docs_url` string, nullable, required
  - `citation_issues` ReviewCitationIssueOut[]: Citations whose source does not say what the draft says, the most serious first; partly_supported rows are not issues and are only in citations[]. [] when the check was not asked.
    - `citation_index` integer, required
    - `reference` string, nullable, required
    - `cited_url` string, nullable, required
    - `doi` string, nullable, required
    - `statement` string, nullable, required
    - `quotes` string[]
    - `position` PositionOut, required
      - `start` integer, nullable, required: Where the passage starts in `text` as you sent it, in Unicode code points (not UTF-16 units or bytes). Half-open with `end`. `null` when `text` was a URL: the page is not returned, so there is nothing to index, and `text` carries the passage instead.
      - `end` integer, nullable, required: Where the passage ends, exclusive; `null` as for `start`.
      - `text` string, nullable, required: The passage itself, as it appears in the text. `null` on a citation position, whose row already carries the statement.
    - `finding` 'doi_not_found' | 'page_not_found' | 'contradicted' | 'quote_not_in_source' | 'not_in_source' | 'partly_supported' | 'metadata_mismatch' | 'supported' | 'unchecked', required
    - `source` 'doi' | 'page' | 'support' | 'quote' | 'metadata', nullable, required
    - `snippet` string, nullable, required: Set only when source is support.
    - `rationale` string, nullable, required: Set only when source is support.
    - `metadata_differences` ReviewMetadataDifferenceOut[]
      - `field` 'title' | 'authors' | 'year' | 'journal', required
      - `cited` string, nullable
      - `registered` string, nullable
    - `missing_quote` string, nullable: Set only when finding is quote_not_in_source.
    - `page_title` string, nullable, required
    - `failure` FailureOut, required: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
      - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
      - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
      - `hint` string, nullable: What to send next; null when there is nothing to change.
      - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
      - `retryable` boolean, required
      - `docs_url` string, nullable, required
  - `citation_failures` ReviewCitationFailedRowOut[]
    - `citation_index` integer, required
    - `reference` string, nullable, required
    - `cited_url` string, nullable, required
    - `doi` string, nullable, required
    - `failure` FailureOut, required: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
      - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
      - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
      - `hint` string, nullable: What to send next; null when there is nothing to change.
      - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
      - `retryable` boolean, required
      - `docs_url` string, nullable, required
  - `more_claims` string[], nullable: Claims found past max_assessments, in the draft's order: found but not checked; send them in a later request to check them. Null until the draft is read.
  - `more_claim_locations` ClaimLocationOut[], nullable: Where the draft makes each of `more_claims`, in the same order: `{claim, positions}`, the shape `/extract` returns with `locate: true` (see a claim row's `positions`). Null until the draft is read.
    - `claim` string, required: The claim, exactly as it appears in the claim list it belongs to.
    - `positions` PositionOut[], nullable, required: Every place the text makes the claim, in text order, at most 10. `null` only when this claim could not be placed (on /extract every returned claim was placed).
      - `start` integer, nullable, required: Where the passage starts in `text` as you sent it, in Unicode code points (not UTF-16 units or bytes). Half-open with `end`. `null` when `text` was a URL: the page is not returned, so there is nothing to index, and `text` carries the passage instead.
      - `end` integer, nullable, required: Where the passage ends, exclusive; `null` as for `start`.
      - `text` string, nullable, required: The passage itself, as it appears in the text. `null` on a citation position, whose row already carries the statement.
  - `more_citations` ReviewMoreCitationOut[], nullable: Citations found past the ones selected (up to 100): found but not checked; send them in a later request to check them. Null until the draft is read.
    - `index` integer, required
    - `reference` string, nullable
    - `cited_url` string, nullable
    - `doi` string, nullable
    - `sentence` string, required: The draft sentence around the citation, at most 1,000 characters.
    - `position` PositionOut
      - `start` integer, nullable, required: Where the passage starts in `text` as you sent it, in Unicode code points (not UTF-16 units or bytes). Half-open with `end`. `null` when `text` was a URL: the page is not returned, so there is nothing to index, and `text` carries the passage instead.
      - `end` integer, nullable, required: Where the passage ends, exclusive; `null` as for `start`.
      - `text` string, nullable, required: The passage itself, as it appears in the text. `null` on a citation position, whose row already carries the statement.
  - `failure` FailureOut, required: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
    - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
    - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
    - `hint` string, nullable: What to send next; null when there is nothing to change.
    - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
    - `retryable` boolean, required
    - `docs_url` string, nullable, required
  - `view` 'full', required
  - `claims` ReviewClaimOut[], required
    - `index` integer, required
    - `claim` string, nullable, required
    - `positions` PositionOut[], nullable: Where the draft makes this claim: every place, in text order, at most 10, in the same shape as a citation's `position`: `start` / `end` in Unicode code points of `text` as you sent it, half-open, and the passage in `text`. For a URL draft `start` / `end` are `null` and `text` carries the passage. Only claims traced back to the draft are listed at all. `null` when the claim could not be placed, or once a zero-retention draft is gone.
      - `start` integer, nullable, required: Where the passage starts in `text` as you sent it, in Unicode code points (not UTF-16 units or bytes). Half-open with `end`. `null` when `text` was a URL: the page is not returned, so there is nothing to index, and `text` carries the passage instead.
      - `end` integer, nullable, required: Where the passage ends, exclusive; `null` as for `start`.
      - `text` string, nullable, required: The passage itself, as it appears in the text. `null` on a citation position, whose row already carries the statement.
    - `result` ReviewResultOut, required
      - `verdict` 'True' | 'Mostly True' | 'Mixed' | 'Mostly False' | 'False' | 'No Public Record', required
      - `confidence` 'low' | 'medium' | 'high', nullable, required
      - `source` 'assessment' | 'verification', required
      - `is_issue` boolean, required
    - `assessment` ReviewAssessmentOut, required
      - `status` 'pending' | 'running' | 'completed' | 'failed', required
      - `verdict` 'True' | 'Mostly True' | 'Mixed' | 'Mostly False' | 'False' | 'No Public Record', nullable
      - `confidence` 'low' | 'medium' | 'high', nullable
      - `rationale` string, nullable
      - `dissent` string, nullable: Deprecated: always null.
      - `searched_pages` SearchedPageOut[]: Pages looked at while assessing this claim, as title and link.
        - `title` string, required
        - `url` string, required
      - `verification_url` string, nullable
      - `suggested_rewrite` string, nullable: With `escalate.suggest_edits`: the claim with its wrong part corrected, from the quick check's reasoning, when it found the claim False or Mostly False with high confidence. Not itself verified. `null` otherwise.
      - `more_claims` string[]: Further claims found inside this one, not checked.
      - `failure` FailureOut: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
        - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
        - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
        - `hint` string, nullable: What to send next; null when there is nothing to change.
        - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
        - `retryable` boolean, required
        - `docs_url` string, nullable, required
      - `identified_claims` string[]: Sent only to callers on `2026-05-13`; use `more_claims`.
    - `escalation` ReviewEscalationOut, required
      - `matched_rules` string[], required
      - `disposition` 'not_selected' | 'planned' | 'cap' | 'credits' | 'account_cap', required
    - `verification` ReviewVerificationOut, required
      - `status` 'processing' | 'completed' | 'failed' | 'cancelled', required
      - `content_status` 'available' | 'purged', required
      - `verification_id` string, nullable
      - `task_id` string, nullable
      - `claim` string, nullable
      - `language` string, nullable
      - `visibility` string, nullable: EFFECTIVE: a same-account cache hit keeps its own.
      - `depth` string, nullable: EFFECTIVE: a cache hit may serve standard for a low request.
      - `domain` string, nullable
      - `entities` ReviewEntityOut[]
        - `name` string, nullable
        - `qid` string, nullable
      - `verdict` 'True' | 'Mostly True' | 'Mixed' | 'Mostly False' | 'False' | 'No Public Record', nullable: The deep check's verdict. `"No Public Record"` (with `lenz_score: null`): not on the public record. It is an issue (in `issues[]`, with no suggested edit).
      - `confidence` 'low' | 'medium' | 'high', nullable
      - `lenz_score` number, nullable
      - `key_finding` string, nullable
      - `executive_summary` string, nullable
      - `suggested_rewrite` string, nullable
      - `warnings` string[]
      - `created_at` string, nullable
      - `completed_at` string, nullable: When the verification finished; null until it has.
      - `verification_url` string, nullable
      - `url` string, nullable
      - `failure` FailureOut: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
        - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
        - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
        - `hint` string, nullable: What to send next; null when there is nothing to change.
        - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
        - `retryable` boolean, required
        - `docs_url` string, nullable, required
    - `suggested_edits` ReviewSuggestedEditsOut: The smallest edits to the draft that make it say what the claim's deep check rewrite says, in the draft's language. Review content, never part of the verification: a verification is shared, your draft is not.
      - `status` 'pending' | 'completed', required: `pending` while they are computed (poll the review); `completed` once SETTLED, which includes settling on no edit (`edits: []`).
      - `edits` SuggestedEditOut[], nullable, required: `null` while pending; `[]` when settled with no edit (the passage could not be edited safely, no edit passed the checks, or computing it failed on our side). Not itself verified: review it before you use it.
        - `start` integer, required: Where the replaced span starts in `text` as you sent it, in Unicode code points. Half-open with `end`, inside `positions[position]`.
        - `end` integer, required: Where the replaced span ends, exclusive.
        - `text` string, required: Exactly the slice of `text` at `start`..`end`, as you sent it.
        - `position` integer, required: Which of the claim row's `positions` the edit sits in (index); a grouping hint.
        - `replacement` string, required: What replaces it; '' deletes it.
  - `citations` ReviewCitationOut[]
    - `index` integer, required
    - `reference` string, nullable, required
    - `cited_url` string, nullable, required
    - `doi` string, nullable, required
    - `statement` string, nullable, required
    - `quotes` string[]
    - `position` PositionOut, required
      - `start` integer, nullable, required: Where the passage starts in `text` as you sent it, in Unicode code points (not UTF-16 units or bytes). Half-open with `end`. `null` when `text` was a URL: the page is not returned, so there is nothing to index, and `text` carries the passage instead.
      - `end` integer, nullable, required: Where the passage ends, exclusive; `null` as for `start`.
      - `text` string, nullable, required: The passage itself, as it appears in the text. `null` on a citation position, whose row already carries the statement.
    - `result` ReviewCitationResultOut, required
      - `finding` 'doi_not_found' | 'page_not_found' | 'contradicted' | 'quote_not_in_source' | 'not_in_source' | 'partly_supported' | 'metadata_mismatch' | 'supported' | 'unchecked', required
      - `source` 'doi' | 'page' | 'support' | 'quote' | 'metadata', nullable, required
      - `is_issue` boolean, required: True for every finding except partly_supported, supported and unchecked. partly_supported is reported, with its snippet, but is not an issue.
    - `check` ReviewCitationCheckOut, required
      - `status` 'pending' | 'running' | 'completed' | 'failed', required
      - `page_read` 'full' | 'partial' | 'not_found' | 'none', nullable: What reading the source gave: full, partial (cut short, a teaser or an abstract alone), not_found, none.
      - `page_title` string, nullable
      - `page_published_date` string, nullable
      - `page_language` string, nullable: The language of the page that was read, as an ISO 639-1 code (e.g. `en`, `uk`); null when unknown.
      - `source_url` string, nullable: Where the text was actually read from.
      - `source_version` 'published' | 'accepted' | 'submitted', nullable
      - `support` 'supported' | 'partly_supported' | 'contradicted' | 'not_in_source' | 'unchecked', nullable
      - `snippet` string, nullable: The passage from the source the support answer rests on, checked against the page text.
      - `rationale` string, nullable: The reviewer's sentence: reasoning, not a checked source.
      - `quote` 'matched' | 'not_in_source' | 'unchecked', nullable
      - `missing_quote` string, nullable: The first of quotes the source does not contain; null unless quote is not_in_source.
      - `doi_registered` boolean, nullable
      - `metadata` 'consistent' | 'mismatch' | 'unchecked', nullable
      - `metadata_differences` ReviewMetadataDifferenceOut[]
        - `field` 'title' | 'authors' | 'year' | 'journal', required
        - `cited` string, nullable
        - `registered` string, nullable
      - `registered` ReviewRegisteredOut
        - `title` string, nullable
        - `authors` string[]
        - `year` integer, nullable
        - `journal` string, nullable
      - `unchecked_reason` string, nullable: Why the finding is unchecked; an extensible string.
      - `hint` string, nullable
      - `failure` FailureOut: Why an item failed, and what to do next. The same block everywhere an item fails: a verification, an /assess row, a review, a review's claim rows and citation checks. ``code`` is what failed, ``detail`` one sentence on it (the same sentence for the same code on every endpoint), ``hint`` what to send next (null when there is nothing to change), ``failure_class`` why, ``retryable`` whether sending the same request again can succeed, ``docs_url`` where that class is explained. API version ``2026-05-13`` sends each endpoint's earlier fields instead (flat ``error`` / ``failure_reason`` on a verification, ``error_code`` / ``hint`` on an /assess row, ``failure.failure_reason`` on a review).
        - `code` string, required: What failed, one vocabulary everywhere: `no_checkable_claim`, `page_unreadable`, `upstream_unavailable`, `internal`, `cancelled`, `no_citations`, `insufficient_credits` (a verification only ever says the first, the third, the fourth and `cancelled`). Branch on `retryable` for whether to resend, and on the input codes for what to say; fall through on a value you do not know. `no_checkable_claim`: no claim in the input could be checked against public evidence (an opinion, a forecast, a claim about a private person, a statement whose only source is unidentified; on a review, also claims found that could not be traced back to the text); `hint` says which. `page_unreadable`: the link /review was sent could not be read. Version `2026-05-13` spells `no_checkable_claim` as `no_claim` (/assess, /review) or `not_a_claim` (/extract, a verification), and keeps the earlier causes as codes (`timeout`, `framing_failed`, `assessment_failed`, `citation_check_failed`, `invalid_input`).
        - `detail` string, required: The cause, in one sentence (out of time, no row could be assessed, ...); the same sentence for the same cause everywhere.
        - `hint` string, nullable: What to send next; null when there is nothing to change.
        - `failure_class` 'upstream_unavailable' | 'invalid_input' | 'cancelled' | 'internal', required
        - `retryable` boolean, required
        - `docs_url` string, nullable, required

## Other responses

- `403`: Forbidden
- `404`: Not Found
- `410`: Gone
- `default`: An error

---

[API](https://skmtc.dev/lenz/apis/lenz-ai-fact-checking-api.md) · [All operations](https://skmtc.dev/lenz/apis/lenz-ai-fact-checking-api/llms.txt) · [OpenAPI document](https://skmtc.dev/lenz/apis/lenz-ai-fact-checking-api/revisions/6150947324bf?raw)
