Developer documentation

Integrate a complete evidence check.

Submit a claim, transcript, audio file, or image. FactLens runs the appropriate checking pipeline and returns one structured result with its evidence and usage details.

Quickstart

The production base URL is https://api.factlens.pro. This request checks a single claim through retrieval and evaluation.

cURL
curl --request POST "https://api.factlens.pro/v1/check" \
  --header "Authorization: Bearer fl_live_YOUR_KEY" \
  --header "Content-Type: application/json" \
  --header "X-Request-ID: 01914f52-79f6-7d4f-b456-426614174000" \
  --data '{
    "mode": "audio_video",
    "claim": "The International Space Station circles Earth about every 90 minutes."
  }'
Keep API keys on your server. Never embed a live FactLens key in a public webpage, mobile bundle, or browser extension you do not control.

Authentication

Every API request uses a server-issued key in the bearer authorization header.

Authorization: Bearer fl_live_YOUR_KEY

A missing, invalid, revoked, or expired key returns 401. API keys are only shown when issued, so store them in your deployment platform’s secret manager.

Check a claim

POST/v1/check

Use audio_video for spoken or written claims and image_post when visual context is part of the check.

FieldTypePurpose
modestringaudio_video or image_post.
claimstringThe specific claim to check. Required unless a transcript is provided.
transcriptstringSource transcript. FactLens extracts a checkable claim when claim is omitted.
audio_base64stringBase64-encoded audio for transcription. Do not include a data URL prefix.
image_base64stringBase64-encoded image used with image_post.
content_typestringMedia MIME type such as audio/mpeg or image/webp.
languagestringOptional language hint, such as en or bn.
search_querystringAn optional retrieval query. FactLens creates one when omitted.
results_per_searchintegerRequested search results, from 1 to 100.
verdictsarrayOptional custom verdict identifiers and selection rules.
instructionsstringAdditional task guidance applied without changing the response contract.

JavaScript

Node.js 18+ / server runtime
const response = await fetch('https://api.factlens.pro/v1/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.FACTLENS_API_KEY}`,
    'Content-Type': 'application/json',
    'X-Request-ID': crypto.randomUUID(),
  },
  body: JSON.stringify({
    mode: 'audio_video',
    transcript: 'The ISS circles Earth roughly once every 90 minutes.',
    results_per_search: 10,
  }),
});

if (!response.ok) throw new Error(await response.text());
const result = await response.json();
console.log(result.verdictId, result.sources);

PowerShell

Invoke-RestMethod
$headers = @{
  Authorization = "Bearer $env:FACTLENS_API_KEY"
  "X-Request-ID" = [guid]::NewGuid().ToString()
}
$body = @{
  mode = "audio_video"
  claim = "The ISS circles Earth roughly once every 90 minutes."
} | ConvertTo-Json

$result = Invoke-RestMethod `
  -Method Post `
  -Uri "https://api.factlens.pro/v1/check" `
  -Headers $headers `
  -ContentType "application/json" `
  -Body $body

$result.verdictId

Python

requests
import os
import uuid
import requests

response = requests.post(
    "https://api.factlens.pro/v1/check",
    headers={
        "Authorization": f"Bearer {os.environ['FACTLENS_API_KEY']}",
        "X-Request-ID": str(uuid.uuid4()),
    },
    json={
        "mode": "audio_video",
        "claim": "The ISS circles Earth roughly once every 90 minutes.",
    },
    timeout=120,
)
response.raise_for_status()
print(response.json()["verdictId"])

Audio and images

Send files as base64 when your application does not already have a transcript or written claim. The API accepts one media input per request.

Audio file

Node.js
import { readFile } from 'node:fs/promises';

const audio = await readFile('./interview.mp3');
const response = await fetch('https://api.factlens.pro/v1/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.FACTLENS_API_KEY}`,
    'Content-Type': 'application/json',
    'X-Request-ID': crypto.randomUUID(),
  },
  body: JSON.stringify({
    mode: 'audio_video',
    audio_base64: audio.toString('base64'),
    content_type: 'audio/mpeg',
    language: 'en',
  }),
});
console.log(await response.json());

Image or post

Python
import base64
import os
import uuid
import requests

with open("post.webp", "rb") as image:
    encoded = base64.b64encode(image.read()).decode("ascii")

result = requests.post(
    "https://api.factlens.pro/v1/check",
    headers={
        "Authorization": f"Bearer {os.environ['FACTLENS_API_KEY']}",
        "X-Request-ID": str(uuid.uuid4()),
    },
    json={
        "mode": "image_post",
        "image_base64": encoded,
        "content_type": "image/webp",
        "claim": "The caption says this image was taken in London in 2026.",
    },
    timeout=120,
).json()
print(result)

Custom verdicts

Pass the verdict catalog your product uses. FactLens returns exactly one enabled verdict identifier from that catalog.

{
  "mode": "image_post",
  "claim": "This photograph shows the stated event.",
  "verdicts": [
    { "id": "confirmed", "rule": "Reliable evidence directly confirms the claim." },
    { "id": "contradicted", "rule": "Reliable evidence directly contradicts the claim." },
    { "id": "unresolved", "rule": "Available evidence cannot establish or reject the claim." }
  ],
  "instructions": "Prefer primary sources when they are available."
}
Use stable identifiers. Display labels and colors belong in your application. Treat the returned verdictId as the durable integration value.

Response

A successful check returns the normalized claim, verdict, explanation, evidence strength, sources, provider trace, and current usage.

{
  "request_id": "01914f52-79f6-7d4f-b456-426614174000",
  "mode": "audio_video",
  "transcript": null,
  "claim": "The International Space Station circles Earth about every 90 minutes.",
  "verdictId": "confirmed",
  "explanation": "Multiple authoritative sources describe an orbital period of roughly 90 minutes.",
  "confidence": "high",
  "evidenceStrength": "strong",
  "sources": [
    { "title": "International Space Station facts", "url": "https://www.nasa.gov/international-space-station/" }
  ],
  "provider": { "ai": "managed", "search": "managed" },
  "usage": { "used": 41, "limit": 10000, "remaining": 9959 }
}

Usage

GET/v1/usage

Read the current allowance for an API key. This endpoint does not consume a claim check.

cURL
curl "https://api.factlens.pro/v1/usage" \
  --header "Authorization: Bearer fl_live_YOUR_KEY"
{
  "used": 41,
  "limit": 10000,
  "remaining": 9959
}

Pricing is based on accepted complete claim checks: 1,000 claims per $1, with a $3 minimum starting budget.

Errors and retries

StatusMeaningAction
400The request body is incomplete or invalid.Correct the named field before retrying.
401The API key is missing, invalid, revoked, or expired.Check the bearer key or request a replacement.
402The key has no remaining claim allowance.Increase the API budget before sending another check.
405The endpoint does not accept this HTTP method.Use POST for checks and GET for usage.
502A configured evidence provider did not complete the request.Retry with the same request ID after a short delay.
503The managed checking service is temporarily unavailable.Retry with exponential backoff and the same request ID.

Idempotent retries

Generate one UUID for each logical check and send it as X-Request-ID. If a connection closes before you receive the response, retry with the same value so FactLens can recognize the request.

X-Request-ID: 01914f52-79f6-7d4f-b456-426614174000