VeriVeri API
Multi-agent consensus fact-verification. Send grounding context and AI-generated text — receive a confidence-scored verdict backed by multiple independent AI models, tested on large datasets with domain-specific data. When not verified, returns actionable issues pointing to specific claims not supported by the grounding context.
All requests and responses use JSON. Every response includes an X-Request-ID header for tracing.
#Quick Start
Get a verification result in three steps.
vv_live_.
02
Send a POST to /v1/verify-lite with your context and text.
03
Read the verdict, confidence, and issues from the response.
curl -X POST https://api.veriveri.io/v1/verify-lite \ -H "Authorization: Bearer vv_live_your_key" \ -H "Content-Type: application/json" \ -d '{ "context": "StarRewards T&C: 1 pt per EUR 1 spent. 2x bonus on Electronics during promos only. Gold tier: 10,000 pts/year, free standard shipping, 5% discount. No cash withdrawal.", "text": "Gold members earn double points on all purchases and get a 10% discount." }'
import requests response = requests.post( "https://api.veriveri.io/v1/verify-lite", headers={"Authorization": "Bearer vv_live_your_key"}, json={ "context": "StarRewards T&C: 1 pt per EUR 1 spent. 2x bonus on Electronics during promos only. Gold tier: 10,000 pts/year, free standard shipping, 5% discount.", "text": "Gold members earn double points on all purchases and get a 10% discount.", }, ) print(response.json())
const response = await fetch("https://api.veriveri.io/v1/verify-lite", { method: "POST", headers: { "Authorization": "Bearer vv_live_your_key", "Content-Type": "application/json", }, body: JSON.stringify({ context: "StarRewards T&C: 1 pt per EUR 1 spent. 2x bonus on Electronics during promos only. Gold tier: 10,000 pts/year, free standard shipping, 5% discount.", text: "Gold members earn double points on all purchases and get a 10% discount.", }), }); console.log(await response.json());
Both /v1/verify and /v1/verify-lite return the same response shape: request_id, verdict, confidence, and issues. The difference is tier access and domain support.
#Authentication
All endpoints except /v1/health require a Bearer token. API keys are provisioned through the dashboard and begin with vv_live_.
Authorization: Bearer vv_live_your_api_key_here
Required Headers
| Header | Value | |
|---|---|---|
| Authorization | Bearer vv_live_<key> |
Required |
| Content-Type | application/json |
Required |
#Verify
Full verification with domain-specific prompts and multi-LLM consensus. Multiple independent models evaluate the text against your grounding context. When issues are found, they are consolidated and returned as actionable items.
Available domains: general and finance. Coming soon: banking WIP and pharma WIP.
Request Body
| Field | Type | Description | |
|---|---|---|---|
| context | string | Required | Source-of-truth grounding text (max 100 KB) |
| text | string | Required | AI-generated text to verify (max 10 KB) |
| domain | string | Optional | general | finance — defaults to general. Soon: banking, pharma |
Request Example
{ "context": "P&L Summary Q3 2025 (USD millions): Revenue: 842 (Prior Year: 780, Annual Target: 850). COGS: 512 (PY: 468, AT: 500). Gross Profit: 330 (PY: 312, AT: 350). OpEx: 185 (PY: 162, AT: 178). EBITDA: 145 (PY: 150, AT: 172).", "text": "Q3 2025 CFO Narrative: Revenue reached $842M, up 8% vs prior year and tracking close to the $850M annual target. The largest deviation was in EBITDA, which declined 3% year-over-year to $145M and fell 16% short of the $172M annual target, driven by a 14% increase in operating expenses.", "domain": "finance" }
Response Body
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique UUID for this request |
| verdict | string | VERIFIED or NOT_VERIFIED |
| confidence | string | high, medium, or low |
| issues | array<string> | Empty when verified. Specific issues when not verified |
Response — Verified
{ "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "verdict": "VERIFIED", "confidence": "high", "issues": [] }
Response — Not Verified
{ "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "verdict": "NOT_VERIFIED", "confidence": "high", "issues": [ "The narrative states OpEx increased 14% YoY, but the P&L data shows OpEx went from $162M to $185M, which is a 14.2% increase — materially correct but imprecise.", "EBITDA shortfall vs annual target is stated as 16%, but ($172M - $145M) / $172M = 15.7%, which rounds to 16%. However, the narrative omits that gross profit also missed target by $20M." ] }
Code Examples
curl -X POST https://api.veriveri.io/v1/verify \ -H "Authorization: Bearer vv_live_your_key" \ -H "Content-Type: application/json" \ -d '{ "context": "P&L Q3 2025 (USD M): Revenue 842 (PY 780), COGS 512 (PY 468), Gross Profit 330 (PY 312), OpEx 185 (PY 162), EBITDA 145 (PY 150, Target 172).", "text": "Revenue grew 8% YoY to $842M. EBITDA declined 3% to $145M, missing the annual target of $172M by 16%, primarily due to a 14% rise in operating expenses.", "domain": "finance" }'
import requests # P&L data as context, AI-generated CFO narrative as text pnl_context = ( "P&L Summary Q3 2025 (USD millions): " "Revenue: 842 (Prior Year: 780, Annual Target: 850). " "COGS: 512 (PY: 468, AT: 500). " "Gross Profit: 330 (PY: 312, AT: 350). " "OpEx: 185 (PY: 162, AT: 178). " "EBITDA: 145 (PY: 150, AT: 172)." ) cfo_narrative = ( "Q3 2025: Revenue reached $842M, up 8% vs prior year. " "The largest deviation was in EBITDA, which declined 3% " "year-over-year to $145M and fell 16% short of the $172M " "annual target, driven by a 14% increase in operating expenses." ) response = requests.post( "https://api.veriveri.io/v1/verify", headers={"Authorization": "Bearer vv_live_your_key"}, json={ "context": pnl_context, "text": cfo_narrative, "domain": "finance", }, ) data = response.json() if data["verdict"] == "NOT_VERIFIED": for issue in data["issues"]: print(f" - {issue}")
const pnlContext = [ "P&L Summary Q3 2025 (USD millions):", "Revenue: 842 (Prior Year: 780, Annual Target: 850).", "COGS: 512 (PY: 468, AT: 500).", "Gross Profit: 330 (PY: 312, AT: 350).", "OpEx: 185 (PY: 162, AT: 178).", "EBITDA: 145 (PY: 150, AT: 172).", ].join(" "); const cfoNarrative = "Q3 2025: Revenue reached $842M, up 8% vs prior year. " + "The largest deviation was in EBITDA, which declined 3% " + "year-over-year to $145M and fell 16% short of the $172M " + "annual target, driven by a 14% increase in operating expenses."; const response = await fetch("https://api.veriveri.io/v1/verify", { method: "POST", headers: { "Authorization": "Bearer vv_live_your_key", "Content-Type": "application/json", }, body: JSON.stringify({ context: pnlContext, text: cfoNarrative, domain: "finance", }), }); const data = await response.json(); console.log(data.verdict, data.confidence); if (data.issues.length) data.issues.forEach(i => console.log(` - ${i}`));
Errors
| Status | Body | Reason |
|---|---|---|
| 400 | {"error": "Request body too large"} |
Payload exceeds size limits |
| 401 | {"error": "Invalid or missing API key"} |
Missing or invalid Bearer token |
| 403 | {"error": "You do not have access to this endpoint."} |
Tier does not include this endpoint |
| 429 | {"error": "Rate limit exceeded"} |
Too many requests |
#Verify Lite
Lightweight verification that returns a verdict, confidence level, and actionable issues. Available to both self-serve and enterprise tiers. Domain is fixed to general.
Request Body
| Field | Type | Description | |
|---|---|---|---|
| context | string | Required | Source-of-truth grounding text (max 100 KB) |
| text | string | Required | AI-generated text to verify (max 10 KB) |
Request Example
{ "context": "StarRewards Loyalty Programme Terms & Conditions (v4.2, effective 1 Jan 2026). Section 3 — Points Earning: Members earn 1 point per EUR 1 spent on eligible purchases. Bonus multiplier of 2x applies to purchases in the Electronics category during promotional periods only. Points expire 24 months after the transaction date. Section 5 — Redemption: Minimum redemption threshold is 500 points. Points may be redeemed for store credit at a rate of 100 points = EUR 1. Cash withdrawal of points is not permitted. Section 7 — Tier Status: Gold tier requires 10,000 points earned within a calendar year. Gold members receive free standard shipping and a 5% discount on all orders.", "text": "As a StarRewards Gold member, you earn 2x points on all purchases and can redeem points for store credit or cash back. Gold status requires 10,000 points per year and includes free shipping plus a 10% member discount." }
Response Body
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique UUID for this request |
| verdict | string | VERIFIED or NOT_VERIFIED |
| confidence | string | high, medium, or low |
| issues | array<string> | Empty when verified. Specific issues when not verified |
Response — Verified
{ "request_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012", "verdict": "VERIFIED", "confidence": "high", "issues": [] }
Response — Not Verified
{ "request_id": "c3d4e5f6-a7b8-9012-cdef-345678901234", "verdict": "NOT_VERIFIED", "confidence": "high", "issues": [ "The 2x bonus multiplier applies to Electronics category during promotional periods only, not to all purchases as stated.", "Cash back redemption is not permitted — points can only be redeemed for store credit.", "The Gold member discount is 5%, not 10% as claimed." ] }
Code Examples
curl -X POST https://api.veriveri.io/v1/verify-lite \ -H "Authorization: Bearer vv_live_your_key" \ -H "Content-Type: application/json" \ -d '{ "context": "StarRewards Loyalty Programme T&C (v4.2). Points earn rate: 1 pt per EUR 1. Bonus 2x on Electronics during promos only. Points expire after 24 months. Minimum redemption: 500 pts. Redemption rate: 100 pts = EUR 1 store credit. No cash withdrawal. Gold tier: 10,000 pts/year, free standard shipping, 5% discount.", "text": "Gold members earn 2x points on all purchases and enjoy a 10% discount with free shipping. Points can be redeemed for cash or store credit." }'
import requests # Verify chatbot response against loyalty programme T&Cs response = requests.post( "https://api.veriveri.io/v1/verify-lite", headers={"Authorization": "Bearer vv_live_your_key"}, json={ "context": ( "StarRewards Loyalty Programme T&C (v4.2). " "Points earn rate: 1 pt per EUR 1. Bonus 2x on Electronics " "during promos only. Points expire after 24 months. " "Min redemption: 500 pts. Rate: 100 pts = EUR 1 store credit. " "No cash withdrawal. Gold: 10,000 pts/year, free shipping, 5% discount." ), "text": ( "Gold members earn 2x points on all purchases and enjoy a " "10% discount with free shipping. Points can be redeemed " "for cash or store credit." ), }, ) data = response.json() if data["verdict"] == "NOT_VERIFIED": for issue in data["issues"]: print("⚠", issue)
// Verify chatbot response against loyalty programme T&Cs const response = await fetch("https://api.veriveri.io/v1/verify-lite", { method: "POST", headers: { "Authorization": "Bearer vv_live_your_key", "Content-Type": "application/json", }, body: JSON.stringify({ context: "StarRewards Loyalty Programme T&C (v4.2). Points earn rate: 1 pt per EUR 1. Bonus 2x on Electronics during promos only. Points expire after 24 months. Min redemption: 500 pts. Rate: 100 pts = EUR 1 store credit. No cash withdrawal. Gold: 10,000 pts/year, free shipping, 5% discount.", text: "Gold members earn 2x points on all purchases and enjoy a 10% discount with free shipping. Points can be redeemed for cash or store credit.", }), }); const { verdict, issues } = await response.json(); if (verdict === "NOT_VERIFIED") { issues.forEach((i) => console.warn("⚠", i)); }
Errors
| Status | Body | Reason |
|---|---|---|
| 400 | {"error": "Request body too large"} |
Payload exceeds size limits |
| 401 | {"error": "Invalid or missing API key"} |
Missing or invalid Bearer token |
| 403 | {"error": "You do not have access to this endpoint."} |
Tier does not include this endpoint |
| 429 | {"error": "Rate limit exceeded"} |
Too many requests |
#Health Check
Public health check. No authentication required.
Response
{ "status": "ok", "version": "v1" }
Code Examples
curl https://api.veriveri.io/v1/healthimport requests response = requests.get("https://api.veriveri.io/v1/health") print(response.json())
const response = await fetch("https://api.veriveri.io/v1/health"); const data = await response.json(); console.log(data);
#Schemas
Verdicts
| Verdict | Meaning |
|---|---|
| VERIFIED | The text is supported by the provided context. Consensus of providers agrees the claims are accurate. |
| NOT_VERIFIED | The text contains claims not supported by or contradicting the provided context. |
Verdicts are determined via weighted consensus across multiple independent providers.
Confidence Levels
| Level | Description |
|---|---|
| high | Unanimous agreement among all providers. |
| medium | Strong majority agreement. |
| low | Weak agreement or provider failures. Treat with caution. |
Issues Array
The issues field on both endpoints provides human-readable descriptions of discrepancies between the text and context. Empty when the verdict is VERIFIED. Each string describes one specific factual issue when NOT_VERIFIED.
#Errors
All errors return JSON with an error field. Every response includes an X-Request-ID header.
Format
{ "error": "Description of what went wrong" }
Error Codes
| Status | Error | Description |
|---|---|---|
| 400 | Bad Request | Invalid JSON, missing required fields, or payload exceeds size limits. |
| 401 | Unauthorized | Missing header, invalid key format, or key not found. |
| 403 | Forbidden | Valid key but insufficient permissions for the endpoint or domain. |
| 429 | Too Many Requests | Rate limit exceeded. Back off and retry. |
#Tiers
Access depends on your API key's tier.
Self-Serve
/v1/verify-liteendpoint only- Domain fixed to
general - Verdict, confidence, and issues
Enterprise
- Both
/v1/verifyand/v1/verify-lite - All domains:
general,finance— coming soon:bankingWIP,pharmaWIP - Domain-specific verification prompts
- Higher size limits and rate limits