Catch AI hallucinations before they ship.
Lenz is a fact-checking API for model-generated text. It checks factual statements against independent public sources, not against the model that produced them, and returns structured results.
Example: a chatbot answer
“Python 3.12 was released on 2 October 2023. It removed the distutils package from the standard library. On the official benchmark suite it runs about 20% faster than Python 3.11.”
Full verification
- Python 3.12 was released on October 2, 2023. True high confidence 10/10 python.orgmail.python.orgdiscuss.python.org+8 more
- Python 3.12 removed the distutils package from the Python standard library. True high confidence 10/10 peps.python.orgdocs.python.orggithub.com+7 more
- Python 3.12 runs about 20% faster than Python 3.11 on the official Python benchmark suite. False high confidence 1/10 python.orgdiscuss.python.orgdocs.python.org+11 more Official benchmarks do not support a 20% speedup. Python 3.12 was reported as roughly 4–5% faster overall than Python 3.11, with results varying by workload and platform. The larger figure appears to confuse this comparison with Python 3.11’s performance gain over Python 3.10.
Checked 7 September 2026. Open a row for the sources it used and the reasoning that weighed them.
Hallucination detection against public sources.
Send Lenz an answer your model produced. It pulls out the factual statements in it and checks each against independent public sources, using models from multiple vendors. For a full verification, models argue for and against each statement on the evidence, three automated reviewers assess it, and the result ships with the trace.
A model grading its own output is not an outside check. Lenz sits outside the model vendor and outside your own team, and the evidence it cites is public, so a customer or an auditor can follow it.
The API: two different checks, one sequence.
Lenz supplies the verdicts. Your gate applies your thresholds.
-
An answer is drafted
A support reply, a RAG answer, a summary — anything a model wrote that a customer is about to read.
-
Extract the statements
POST /extractsplits the answer into single factual statements, up to 20, each self-contained enough to check on its own. Opinions, recommendations, predictions and questions are left out. It costs no credits, capped at 1,000 calls a day per account. -
Sort them, then establish the ones that matter
POST /assessis a judgement: a panel of models returns a verdict and a confidence level per statement, synchronously in about 10 seconds, up to 20 statements a call — no score and no sources. Send the negative and low-confidence ones toPOST /verify, an investigation that searches independent public sources, has models argue both sides and three automated reviewers assess the arguments — about 90 seconds a statement, asynchronous, with a webhook when it lands. -
Your gate decides
Your thresholds and your routing: what clears them ships, and what does not goes to your reviewer with the verdict, the sources and the reasoning already attached. Lenz returns results — it never holds, edits or publishes your text.
-
Ship, with the record
A full verification keeps its trace: the statement as framed, every source with its date, the arguments on both sides and the reasoning that weighed them. Submissions through the API are private by default;
visibility: "unlisted"returns a link you can pass to whoever asks.
The sequence is extract → assess in bulk → verify the uncertain results → ask follow-up questions about a verification. Assess to sort; verify to establish.
Fact-checking RAG answers.
Retrieval narrows what the model says; it does not make it true. Lenz checks the factual statements in the generated answer against public sources. It does not compare the answer with your retrieved documents: faithfulness to your own context is a different check, and not this one.
Check LLM output with Python.
Python pip install lenz-io
# model output in — the statements your policy holds back, out from lenz_io import Lenz client = Lenz(api_key="lenz_...") extracted = client.extract(text=model_output) # identified_claims is empty when the text yields a single statement claims = extracted.identified_claims or [extracted.claim] r = client.assess(claims=claims) # one row per statement, same order # your routing policy. "Error" means the item was not checked — never ship it as clean for c in r.claims: if c.verdict in ("False", "Mostly False", "Mixed", "Error") or c.confidence == "low": print("HOLD:", c.claim, c.verdict, c.confidence) # HOLD: Python 3.12 runs about 20% faster than Python 3.11 ... False high
TypeScript SDK: npm install lenz-io, with the same example on the developer page. Webhooks replace the wait on /verify.
What comes back.
Selected fields from the recorded responses for the example above, which Lenz wrote and published. Your API submissions are private to your account.
Selected fields from an /assess response r.claims[i]
{
"claim": "Python 3.12 runs about 20% faster than Python 3.11 on the official Python benchmark suite.",
"language": "en",
"verdict": "False",
"confidence": "high",
"verification_url": "https://lenz.io/api/v1/verifications/b5968a41"
}
verification_url is set when a full verification of that statement already exists and your key can read it — treat null as “not available to you”, not as “not verified”. No score and no sources at this depth.
Selected fields from a completed /verify response GET /verify/status/{task_id}
{
"status": "completed",
"result": {
"verification_id": "b5968a41",
"claim": "Python 3.12 runs about 20% faster than Python 3.11 on the official Python benchmark suite.",
"depth": "standard",
"verdict": "False",
"confidence": "high",
"lenz_score": 1,
"key_finding": "Python 3.12 averages roughly 4–5% faster than Python 3.11.",
"sources": [
{ "url": "https://docs.python.org/3/whatsnew/3.12.html" }
]
}
}
The full object also carries executive_summary, warnings, each source’s title, snippet and date, and the audit block with the debate and the panel reasoning. Branch on verdict and confidence from either endpoint; lenz_score, key_finding, sources and audit exist only on a full verification.
A full verification returns the fields your code branches on — verdict, confidence, lenz_score, key_finding and sources — so the routing decision is yours to make in code: publish, hold, or send it to your reviewers.
Lenz checks factual statements in text against public sources.
Pricing
Free tier, no card: 100 assessments or 10 full verifications a month, in any combination. Developer is $99 a month for 5,000 assessments or 500 full verifications, the same way, and Scale is $399 a month for production volumes. Every plan includes 1,000 extractions a day, an extraction being one call however long the text.
Frequently asked questions
A content detector guesses who wrote a text. Lenz checks whether what the text says is true: it takes an answer you already know came from a model and checks each factual statement against independent public sources.
For the facts, yes: Lenz checks the factual statements in the generated answer against public sources. For faithfulness to your own retrieved context, no; that is a different check, and Lenz does not compare the answer with your documents.
They answer different questions, so budget for them differently. /assess is a synchronous judgement, about 10 seconds per call. /verify is an asynchronous investigation against public sources, about 90 seconds per statement, with a webhook on completion. An assessment fits inside a chat completion; a full verification does not, which is why it returns on a webhook.