WebCite API

API documentation for WebCite public API endpoints. Use these endpoints to verify claims, search for sources, and manage citations.

Overview

Base URL
text
https://api.webcite.co/api
Authentication
All endpoints require authentication using an API key. Include your API key in the request headers.
bash
x-api-key: your-api-key-here

You can create and manage API keys from the API Keys page.

Credit System

WebCite uses a credit-based billing system. Each API operation consumes credits from your monthly allocation. Credits are charged per claim, not per citation - each API call verifies 1 claim and returns multiple citations.

What every billable call returns
Each billable endpoint adds two fields to its response, so a call can be reconciled against your ledger.
json
{  "...": "the endpoint's own result",  "operation_id": "op_2f9c...",  "usage": { "credits": 4 }}

operation_id identifies this billed operation. It is null when the operation could not be recorded; the work still ran and the result is still yours, but there is nothing to reconcile against, so it reports no id rather than a fabricated one.

usage.credits is number | null. It is the number of credits actually deducted, or 0 only when the endpoint is genuinely priced at zero.

It is null when the call was not metered — for example a caller with no credits record, or an accounting write that failed after the work completed. Those cases previously reported 0, which told you the call was free when in fact it was simply never counted.

Handle it as credits ?? null rather than credits || 0. Coercing null to zero re-creates exactly the ambiguity this field exists to remove, and a ledger that books zeros for unmetered calls will not reconcile.

Credit Costs
Citation search costs 2 credits. Full verification (default) costs 4 credits total.
OperationCreditsDescription
Citation/Search2Search web sources for a claim. Returns multiple citations.
Stance Analysis1Analyze if citations support or contradict the claim. Optional
Verdict1Generate overall verification verdict. Optional
Full Verification4Citation + Stance + Verdict (default)
Saving Credits
Control which operations run to reduce credit usage.
json
// Citation only (2 credits){  "prompt": "Your claim here",  "include_stance": false,  "include_verdict": false} // Citation + Stance (3 credits){  "prompt": "Your claim here",  "include_verdict": false} // Full verification (3 credits) - default{  "prompt": "Your claim here"}
Plans
PlanCredits/MonthPrice
Free100$0
Builder500$20
EnterpriseCustomCustom
Checking Your Credits
GET/v1/payment/subscription/credits
json
{  "credits": {    "used": 12,    "remaining": 88,    "total": 100  },  "usage_breakdown": {    "citations": 8,    "stances": 3,    "verdicts": 1  },  "allow_overage": true,  "billing_period_start": "2026-01-01T00:00:00.000Z",  "billing_period_end": "2026-01-31T23:59:59.000Z"}
Overage Billing Settings
Paid plans (Builder/Enterprise) can toggle overage billing on or off.

Get Current Setting

GET/v1/payment/subscription/overage-setting
json
{  "allow_overage": true,  "plan_type": "builder",  "can_toggle": true}

Toggle Overage Billing

PUT/v1/payment/subscription/overage-setting
json
// Request{ "allow_overage": false } // Response{  "allow_overage": false,  "message": "Overage billing disabled. Requests will be blocked when credits are exhausted."}

When overage is disabled, API requests return 400 error when credits are exhausted. When enabled, overages are billed at $0.03/credit.

Credit Usage in Responses
Credit usage is included in stream metadata events.
json
// Metadata event in stream response{  "type": "metadata",  "data": {    "thread_id": "...",    "citation_id": "...",    "creditUsage": {      "credits_used": 3,      "credits_remaining": 47    }  }}

Important Notes

  • Credits are charged per claim, not per citation
  • Each API call verifies 1 claim and returns multiple citations
  • All citations for a claim are covered by the credit cost
  • Credits reset at the start of each billing period

Verify Claim

Verify a factual claim against authoritative sources. Returns sources with stance analysis and an overall verdict.

POST/api/v1/verify

Request

curl
curl -X POST 'https://api.webcite.co/api/api/v1/verify' \  -H 'Content-Type: application/json' \  -H 'x-api-key: YOUR_API_KEY' \  -d '{    "claim": "The Eiffel Tower is 330 meters tall",    "include_stance": true,    "include_verdict": true  }'

Parameters

ParameterTypeDescription
claimrequired
string

The factual claim to verify

thread_idoptional
string

Thread ID to continue a conversation

include_stanceoptional
boolean

Include stance analysis for each source (supports/contradicts/neutral). Adds 1 credit.

Default: true

include_verdictoptional
boolean

Generate an overall verdict with confidence score. Adds 1 credit.

Default: true

decompose_claimoptional
boolean

Break complex claims into atomic sub-claims and verify each independently.

Default: false

Response

json
{  "citations": [    {      "title": "TypeScript Official Documentation",      "url": "https://www.typescriptlang.org/docs/",      "snippet": "TypeScript is a strongly typed programming language...",      "id": "1",      "author": "typescriptlang",      "status": "verified",      "source_type": "Article"    }  ],  "totalResults": 5,  "thread_id": "123e4567-e89b-12d3-a456-426614174000"}

Search Sources

Search for authoritative sources related to a query. Returns raw citations without stance analysis or verdict. Use this for cheaper, faster searches when you don't need verification.

POST/api/v1/sources/search
Credits: 2 (search only, no analysis)

Request

curl
curl -X POST 'https://api.webcite.co/api/api/v1/sources/search' \  -H 'Content-Type: application/json' \  -H 'x-api-key: YOUR_API_KEY' \  -d '{    "query": "climate change effects on coral reefs",    "limit": 10  }'

Parameters

ParameterTypeDescription
queryrequired
string

Search query to find sources for

limitoptional
number

Maximum number of sources to return (1-20)

Default: 10

Enhanced Analysis

When useEnhancedAnalysis: true is set, the API returns additional fields that help you understand whether sources support or contradict the claim, and an overall verdict.

Enhanced Citation Fields
Each citation object includes these additional optional fields when enhanced analysis is enabled.
json
{  "title": "Example Source",  "url": "https://example.com/article",  "snippet": "The research confirms that...",  "credibility_score": 92,   // Enhanced Analysis Fields  "stance": "supports",  "stance_confidence": 88,  "stance_explanation": "Source directly confirms the claim with data.",  "highlight_terms": ["research confirms", "data shows"],  "source_metadata": {    "domain": "example.gov",    "domain_category": "government",    "is_primary_source": true,    "is_fact_check_site": false  },   // Verification Stamp (neuro-symbolic)  "verification": {
Verification Stamp
Every citation carries a symbolic verification stamp: the provenance tier it earned, a confidence capped by that tier, and a trust band you can filter on. A model-asserted citation can never present as verified the way a bound one can.

Fields

ParameterTypeDescription
layerrequired
string

Provenance tier: deterministic (exact bind-back to a document page/cell) > bound (normalized bind-back, or exact against a web page) > model (source exists but quote not bound back) > unbound (no source).

bandrequired
string

Trust band to act on: verified / needs_review / unverified.

confidencerequired
number

0–100, capped by layer (deterministic 100, bound 90, model 70, unbound 40).

groundedrequired
boolean

Whether the cited quote was bound back to its source.

binding_methodoptional
string

exact / normalized / fuzzy / unbound.

review_reasonoptional
string

Why the band was capped below verified, when applicable.

Tip: filter on verification.band === "verified" to surface only citations whose quote is bound to a source with sufficient confidence.

Verdict Object
The response includes an overall verdict summarizing how all citations relate to the claim.
json
{  "verdict": {    "claim": "AI is transforming healthcare",    "result": "supported",    "confidence": 85,    "summary": "Based on 4 authoritative sources, the claim is well-supported.",    "stance_breakdown": {      "supports": 3,      "partially_supports": 1,      "contradicts": 0,      "neutral": 1,      "inconclusive": 0,      "irrelevant": 0,      "unknown": 0    },    "origin_count": 4,    "document_count": 5,    "key_findings": [      {        "finding": "AI diagnostic tools show 95% accuracy",

Usage Notes

  • Enhanced analysis adds processing time and token usage
  • All enhanced fields are optional and only present when useEnhancedAnalysis: true
  • If enhanced analysis fails, the API returns basic response

Claim Decomposition

Optional feature. When verifying complex claims containing multiple facts, set useClaimDecomposition: true to automatically break the claim into atomic sub-claims and verify each independently. This provides more accurate verification and identifies exactly which parts of a claim are true or false. Default is false (standard single-claim verification).

Example Request
Complex claim with multiple verifiable facts
json
{  "prompt": "Tesla is the best-selling EV company founded by Elon Musk",  "useEnhancedAnalysis": true,  "useClaimDecomposition": true}
Decomposition Event
First event showing how the claim was broken down
json
{  "type": "decomposition",  "data": {    "original_claim": "Tesla is the best-selling EV company founded by Elon Musk",    "sub_claims": [      {        "id": "sub-1",        "claim": "Tesla is the best-selling EV company",        "status": "pending"      },      {        "id": "sub-2",        "claim": "Elon Musk founded Tesla",        "status": "pending"      }    ],    "decomposition_reasoning": "The claim contains two distinct verifiable facts..."  }}
Sub-Claim Result Event
Result for each verified sub-claim
json
{  "type": "sub-claim-result",  "data": {    "sub_claim_id": "sub-2",    "claim": "Elon Musk founded Tesla",    "result": "contradicted",    "confidence": 68,    "summary": "5 of 8 sources contradict this claim.",    "citation_count": 8,    "supporting_count": 0,    "contradicting_count": 5,    "top_citations": [      {        "id": "1",        "title": "wikipedia.org",        "url": "https://en.wikipedia.org/wiki/Tesla,_Inc.",        "stance": "contradicts",        "credibility_score": 69      }    ]  }}
Overall Verdict with Corrections
Final verdict showing which sub-claims were verified or contradicted
json
{  "type": "verdict",  "data": {    "claim": "Tesla is the best-selling EV company founded by Elon Musk",    "result": "partially_false",    "confidence": 75,    "summary": "Analyzed 2 sub-claims: 1 verified, 1 contradicted.",    "stance_breakdown": {      "supports": 1,      "partially_supports": 0,      "contradicts": 1,      "neutral": 0    },    "corrections": [      {        "claimed": "Elon Musk founded Tesla",        "actual": "Evidence contradicts this claim",        "citation_ids": ["1", "2"]      }    ]  }}

When to Use Claim Decomposition

  • Claims containing multiple facts (e.g., "X was founded by Y in Z")
  • Statements with conjunctions (and, but, while, because)
  • Complex assertions that need granular verification
  • When you need to know exactly which parts are true vs false

Unified Response Structure

All responses use a unified tree structure with claim_groups as the single source of truth. Each claim contains its citations, domain groups, and verdict - no duplication.

Unified Tree Structure
Both single-claim and multi-claim queries use the same structure. Verdicts stream in parallel as each claim's citations complete.
json
{  "claim_groups": [    {      "claim_id": "claim-1",      "claim_index": 1,      "claim": "Tesla was founded by Elon Musk",      "stance_summary": "contradicted",      "citation_count": 5,      "citations": [        {          "id": "1",          "title": "Wikipedia - Tesla, Inc.",          "url": "https://en.wikipedia.org/wiki/Tesla,_Inc.",          "snippet": "Tesla was founded by Martin Eberhard and Marc Tarpenning...",          "stance": "contradicts",          "credibility_score": 85        }      ],      "domain_groups": [        {          "group_id": "group-wikipedia-org",          "domain": "wikipedia.org",          "domain_category": "encyclopedia",          "group_stance": "contradicts",          "citation_ids": ["1"],          "primary_citation_id": "1"        }      ],      "verdict": {        "claim": "Tesla was founded by Elon Musk",        "result": "contradicted",        "confidence": 85,        "summary": "Tesla was founded by Eberhard and Tarpenning, not Musk.",        "stance_breakdown": {          "supports": 0,          "partially_supports": 1,          "contradicts": 4,          "neutral": 0        }      }    }  ],  "totalResults": 5,  "thread_id": "123e4567-e89b-12d3-a456-426614174000",  "generated_prompts": []

Key Benefits

  • No duplication: Citations only appear in their claim_group
  • Parallel verdicts: Each claim's verdict streams as its citations complete
  • Single tree: claim_groups → citations + domain_groups + verdict
  • Consistent structure: Same format for single and multi-claim queries
Legacy Fields (Deprecated)
For backward compatibility, top-level fields are still included but deprecated.

citations → Use claim_groups[n].citations

verdict → Use claim_groups[n].verdict

citation_groups → Use claim_groups[n].domain_groups

List Citations

Retrieves a paginated list of citations generated by the authenticated user.

GET/api/v1/citations

Parameters

ParameterTypeDescription
pageoptional
number

Page number (starts from 1)

Default: 1

limitoptional
number

Number of items per page (max 100)

Default: 20

thread_idoptional
string

Filter citations by thread ID

fieldsoptional
enum

Field set: minimal, basic, detailed, with_relations, all

Default: basic

Response

json
{  "statusCode": 200,  "message": "Citations fetched successfully",  "data": [    {      "id": "123e4567-e89b-12d3-a456-426614174000",      "thread_id": "thread-123",      "citation": "[{\"title\":\"Example\",\"url\":\"https://example.com\"}]",      "prompt": "Latest trends in AI",      "is_active": true,      "created_at": "2024-01-01T00:00:00.000Z"    }  ],  "pagination": {    "total": 100,    "page": 1,    "limit": 20,    "totalPages": 5,    "hasNextPage": true,    "hasPreviousPage": false

Get Citation by ID

Retrieves a specific citation by its ID for the authenticated user.

GET/api/v1/citations/:id

Path Parameters

ParameterTypeDescription
idrequired
string

The unique identifier of the citation

Response

json
{  "statusCode": 200,  "message": "Citation fetched successfully",  "data": {    "prompt": "Latest trends in AI",    "citation": "[{\"title\":\"Example\",\"url\":\"https://example.com\"}]"  }}

Error Response (404)

json
{  "statusCode": 404,  "message": "Citation not found or does not belong to the user"}

Source Preview

Resolve a citation back to its exact source and render it, so you can show the evidence behind a claim. Web sources return a text-fragment deep link that scrolls to the quote; document sources return the cited page's text and a #page=N link.

Every preview includes a bindBack result: whether the cited quote is present in the source (grounded), how it matched (exact, normalized, fuzzy, or unbound), a similarity score, and the best-matching passage (matched_text) returned even when unbound so you always see the closest evidence. A fuzzy (paraphrase) match is never reported as verified; a citation that cannot be bound back is never reported as grounded.

POST/api/v1/citations/source-preview

Body Parameters

Provide either url (web source) or asset_id (uploaded document).

ParameterTypeDescription
urloptional
string

Web source URL to preview. Provide this OR asset_id.

asset_idoptional
string

Uploaded asset ID (from Upload File). Provide this OR url. Also accepts an asset://<id> citation url.

pageoptional
number

1-based page (PDF) or sheet index (spreadsheet). Default: 1

quoteoptional
string

The cited quote. It is bound back against the source text and highlighted.

Request Example

json
{  "asset_id": "123e4567-e89b-12d3-a456-426614174000",  "page": 2,  "quote": "revenue grew 18% year over year"}

Response — document page

json
{  "kind": "page",  "asset_id": "123e4567-e89b-12d3-a456-426614174000",  "page": 2,  "text": "... revenue grew 18% year over year ...",  "quote": "revenue grew 18% year over year",  "deep_link": "https://cdn.webcite.co/doc.pdf#page=2",  "binding": {    "grounded": true,    "method": "exact",    "score": 1,    "matched_quote": "revenue grew 18% year over year",    "matched_text": "revenue grew 18% year over year"  }}

Response — web source

json
{  "kind": "web",  "url": "https://en.wikipedia.org/wiki/Eiffel_Tower",  "quote": "the Eiffel Tower is 330 metres tall",  "deep_link": "https://en.wikipedia.org/wiki/Eiffel_Tower#:~:text=the%20Eiffel%20Tower%20is%20330%20metres%20tall",  "binding": { "grounded": true, "method": "normalized" }}

Error Response (400)

json
{  "statusCode": 400,  "message": "Provide a web url (http/https) or an asset_id to preview."}

Batch Verify

Check every claim in a document in one call. Each item is a quote plus its source (inline text, a url, or an uploaded asset). Per item you get whether the quote is grounded, how it matched, the best-matching passage and a score even when unbound, the verification tier, and a feedback token.

A fuzzy (paraphrase-level) match is capped at needs_review, never verified. A negated claim will not ground against an affirmative passage.

POST/api/v1/verify/batch

Body Parameters

ParameterTypeDescription
itemsrequired
Item[]

Up to 200 items. Each: quote (the claim), plus its source as source_text (inline), url, or asset_id (with optional page), and an optional id echoed back.

Request Example

json
{  "items": [    { "id": "1", "quote": "reduced HbA1c by 1.2%",      "source_text": "A 1.2% reduction in HbA1c was observed versus placebo." }  ]}

Response (per item)

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 },    "feedback_token": "eyJxIjoi..."  }]

Cost: 1 credit per item. The work is per item — a 200-claim batch binds 200 quotes against 200 sources. BindBack is deterministic (no LLM calls), but a batch can be large and url/asset items fetch their source, so this endpoint is rate-limited more strictly than compute-only endpoints.

Feedback

Record a human verdict on a verification result using its feedback_token. The token carries the result summary, so token plus verdict is enough. Feedback is stored so corrections accumulate over time.

POST/api/v1/verify/feedback

Body Parameters

ParameterTypeDescription
tokenrequired
string

The feedback_token from a batch result.

verdictrequired
string

correct, incorrect, or unsure.

noteoptional
string

An optional note or correction.

Response

json
{ "recorded": true }

Cost: 1 credit. No LLM calls; records a single row. Subject to your plan's rate limits.

Conflict Analysis

Verify numbers, not just text. Given figures extracted across one or more documents, the engine recomputes derivable metrics from their primitives, detects cross-document conflicts, flags semantic contradictions, and returns a review flag: whether a human should look, and the concrete reasons (a conflict, a recompute mismatch, or model-read inputs). The findings are deterministic, so this is a flag with reasons, not a probability score.

POST/api/v1/analyze/conflicts

Body Parameters

ParameterTypeDescription
figuresrequired
Figure[]

Extracted figures. Each: metric (dictionary key e.g. gross_margin), value (number), unit (percent|currency|multiple|ratio|count|months), optional entity/period, and provenance { assetId, documentName, page?, sheet?, cell?, method: rule|model }.

Request Example

json
{  "figures": [    { "metric": "revenue", "value": 100, "unit": "currency",      "provenance": { "assetId": "a", "documentName": "Data Room", "cell": "C5", "method": "rule" } },    { "metric": "cogs", "value": 40, "unit": "currency",      "provenance": { "assetId": "a", "documentName": "Data Room", "cell": "C6", "method": "rule" } },    { "metric": "gross_margin", "value": 45, "unit": "percent",      "provenance": { "assetId": "deck", "documentName": "Pitch Deck", "page": 7, "method": "model" } }  ]}

Response

json
{  "conflicts": [ /* cross-source or semantic disagreements */ ],  "recomputations": [    {      "metric": "gross_margin",      "stated": 45,      "computed": 60,      "unit": "percent",      "withinTolerance": false,      "inputs": [        { "key": "revenue", "value": 100, "provenance": { "cell": "C5" } },        { "key": "cogs", "value": 40, "provenance": { "cell": "C6" } }      ]    }  ],  "review": {    "needs_review": true,    "reasons": ["a recomputed value does not match the stated value"]  }}

Deterministic compute, no LLM calls. Cost: 1 credit. Deterministic compute over the figures you send. Still subject to your plan's rate limits, since the request uses server compute.

Analyze Document

Document-in numeric analysis. Give an uploaded asset id; the document is downloaded, its figures are extracted, then recomputed and cross-checked. Returns the extracted figures alongside conflicts, recomputations, and a review flag.

Spreadsheets (xlsx/xls/csv) are extracted deterministically with exact cell provenance; these are rule reads. PDFs use a vision model that reads the printed figures without computing; these are model reads, capped at needs_review and never presented as verified. The value is cross-source: a deck figure that disagrees with the spreadsheet surfaces as a conflict.

POST/api/v1/analyze/document

Body Parameters

ParameterTypeDescription
asset_idrequired
string

An uploaded asset id (from POST /upload). Supported types: xlsx, xls, csv, pdf.

Response

json
{  "figures": [    { "metric": "revenue", "value": 12400000, "unit": "currency",      "provenance": { "sheet": "P&L", "cell": "B1", "method": "rule" } },    { "metric": "gross_margin", "value": 45, "unit": "percent",      "provenance": { "sheet": "P&L", "cell": "B4", "method": "rule" } }  ],  "recomputations": [    { "metric": "gross_margin", "stated": 45, "computed": 60,      "withinTolerance": false }  ],  "conflicts": [],  "review": { "needs_review": true,    "reasons": ["a recomputed value does not match the stated value"] }}

Cost: 3 credits. The document is downloaded, parsed and (for PDFs) read page by page by a vision model.

Extract Figures

Extract every number in a document as a tagged, source-grounded figure. Each figure carries what it means (metric), its unit, an optional period (FY2023 vs FY2024 kept apart) and entity, a confidence band, whether it was confirmed against the cited cell (bound), and full provenance down to the sheet or page and cell.

Fully deterministic (no model calls). Works on spreadsheets (cell-level discovery, header scale, accounting negatives, unit-declaration checks), PDFs with a text layer (grounded and cited per page), and every other text-bearing format (docx, pptx, html, txt). Scanned image-only pages carry no machine-readable text and yield no figures.

POST/api/v1/extract/figures

Body Parameters

ParameterTypeDescription
asset_idoptional
string

An uploaded asset id (from POST /upload). Provide this or asset_url.

asset_urloptional
string

A direct URL to your own file (e.g. a signed storage URL); the engine downloads it. Provide this or asset_id.

Response

json
{  "figures": [    { "metric": "revenue", "value": 12500000, "unit": "currency",      "period": "FY2023", "band": "verified", "bound": true,      "provenance": { "sheet": "P&L", "cell": "B2", "method": "rule" } },    { "metric": "gross_margin", "value": 68, "unit": "percent",      "period": "FY2023", "band": "verified", "bound": true,      "provenance": { "sheet": "P&L", "cell": "B3", "method": "rule" } }  ]}

Cost: 2 credits. Deterministic (no LLM calls); downloads and runs the full figure engine over every sheet and page.

Extract Text

All-formats extraction into a normalized document: whole-doc markdown, per-page or per-sheet units with page/sheet provenance, and (for spreadsheets) sheet names. Deterministic for text-layer documents; an unreadable asset returns empty text rather than failing.

POST/api/v1/extract

Body Parameters

ParameterTypeDescription
asset_idoptional
string

An uploaded asset id (from POST /upload). Provide this or asset_url.

asset_urloptional
string

A direct URL to your own file; the engine downloads it. Provide this or asset_id.

Response

json
{  "format": "pdf",  "markdown": "# Financials\n\nRevenue grew ...",  "extraction_method": "text_layer",  "units": [    { "kind": "page", "index": 1, "text": "...",      "extraction_method": "text_layer",      "provenance": { "page": 1 } }  ],  "operation_id": "op_2f9c...",  "usage": { "credits": 1 }}

extraction_method says how the text was produced: text_layer (read directly from the file), ocr (transcribed from an image), or none (nothing could be extracted). The per-unit value is exact for that page or sheet; the top-level value is the dominant path across the document. A document that mixes both reports ocr on a tie, because calling a half-transcribed document a text-layer read overstates it.

This matters if you store extracted text as evidence: a vision transcription of a scan is a weaker claim than a deterministic text-layer read, and without this field the two are indistinguishable.

Cost: 1 credit. Deterministic for text-layer documents; downloads and parses a file.

Anchored Chunks

The same extraction, cut into retrieval-sized chunks that each carry where they came from. Use this instead of chunking markdown yourself when you intend to cite what you retrieve: a chunk you split client-side has no page, sheet or section to point back at, so a citation built on it cannot be checked.

POST/api/v1/extract/pages

Body Parameters

ParameterTypeDescription
asset_idoptional
string

An uploaded asset id (from POST /upload). Provide this or asset_url.

asset_urloptional
string

A direct URL to your own file; the engine downloads it. Provide this or asset_id.

Response

json
{  "chunks": [    {      "text": "Revenue grew 18% year over year ...",      "page": 4,      "section": "Financial Review",      "ordinal": 0,      "extraction_method": "text_layer"    },    {      "text": "Segment margin by region ...",      "sheet": "Q3 Summary",      "ordinal": 1,      "extraction_method": "text_layer"    }  ],  "operation_id": "op_5a71...",  "usage": { "credits": 1 }}

Each chunk carries the anchors that apply to it: page for paginated documents, sheet for spreadsheets, section for the heading it falls under, and ordinal for its order within the document.

Anchors are omitted rather than guessed. A chunk from a document with no page structure has no page key at all, instead of a placeholder like 0 that would compare equal to every other unknown.

extraction_method is carried from the page the chunk was cut from, so it survives into whatever you store.

Cost: 1 credit.

Classify Document

Deterministic, model-free classification. Returns a coarse category plus the fine multi-type covers the document holds (a bundled workbook covers several). Pass an optional taxonomy preset (vc = venture data room, ma = M&A; default vc).

POST/api/v1/classify

Body Parameters

ParameterTypeDescription
asset_idoptional
string

An uploaded asset id. Provide this or asset_url.

asset_urloptional
string

A direct URL to your own file. Provide this or asset_id.

taxonomyoptional
string

"vc" (default) or "ma".

Response

json
{  "category": "financials",  "covers": ["Financials (P&L)", "Cap table"]}

Cost: 1 credit. Deterministic, no LLM calls (air-gapped safe); downloads and parses a file.

Document Checklist

Given the documents already filed in a category, returns each expected document type flagged present or absent. An item is present when any document matches it by filename, category, or covered type. Advisory and deterministic; no I/O. Pass an optional taxonomy and stage (early/growth) to tailor the list.

POST/api/v1/gaps

Body Parameters

ParameterTypeDescription
categoryrequired
string

The category to build the checklist for (e.g. "financials", "legal").

docsrequired
array

The documents already filed: [{ filename?, category?, covers?[] }]. May be empty.

taxonomyoptional
string

"vc" (default) or "ma".

stageoptional
string

"early" or "growth".

Response

json
{  "items": [    { "name": "P&L / income statement", "present": true },    { "name": "Cap table", "present": true },    { "name": "Balance sheet", "present": false }  ]}

Cost: 1 credit. Pure and deterministic; no LLM calls or I/O.

Accuracy

The engine's measured accuracy against a gold-set corpus: conflict-detection recall and precision, and recompute correctness. Reproducible and gated on every build, so an accuracy regression cannot ship.

GET/api/v1/accuracy

Response

json
{  "deals": [ { "name": "Vantage Retail (Series A)", "pass": true, "conflicts": { "detectionRate": 1, "precision": 1 }, "recompute": { "checked": 1, "correct": 1 } } ],  "totals": {    "conflicts": { "expected": 4, "found": 4, "flagged": 4, "falsePositives": 0, "detectionRate": 1, "precision": 1 },    "recompute": { "checked": 4, "correct": 4 }  },  "pass": true}

Cost: 1 credit. No LLM calls; the report runs the deterministic gold-set eval on the server, so it is subject to your plan's rate limits.

Upload File

Uploads a file to storage and creates an asset record. Files are automatically sanitized and preserved as private evidence; the response includes an asset URL for downstream use.

POST/api/v1/upload
Content-Type: multipart/form-data

Request

bash
curl -X POST 'https://api.webcite.co/api/api/v1/upload' \  -H 'x-api-key: YOUR_API_KEY' \  -F 'file=@/path/to/your/file.pdf'

Response

json
{  "successCode": 200,  "message": "File uploaded successfully",  "data": {    "asset_id": "123e4567-e89b-12d3-a456-426614174000",    "asset_url": "https://storage.googleapis.com/bucket-name/path/to/file.pdf",    "source_version_id": "123e4567-e89b-12d3-a456-426614174001"  }}

Errors

The endpoint mirrors the outcome in the HTTP status, so failures are never served as 2xx. Downstream 4xx errors (for example 400 or 404) are rethrown as-is in Nest's default { statusCode, message } shape, not successCode.

json
{  "successCode": 503,  "message": "Private evidence storage required: set EVIDENCE_STORAGE_ROOT or EVIDENCE_BUCKET_NAME (I1; never public-first)"}

Data Structures

Citation Object
json
{  // Required fields  "title": "TypeScript Official Documentation",  "url": "https://www.typescriptlang.org/docs/",  "snippet": "TypeScript is a strongly typed programming language...",  "id": "1",  "author": "typescriptlang",  "status": "verified",  "credibility_score": 95,   // Optional fields  "source_type": "Article",  "publication_year": 2024,   // Enhanced Analysis fields (only with useEnhancedAnalysis: true)  "stance": "supports",  "stance_confidence": 90,  "stance_explanation": "Source directly confirms the claim"}

source_type can be: Government Document, Dataset, Journal, Report, Trusted Media, Article, Reddit, Social Media

stance can be: supports, contradicts, partially_supports, neutral, inconclusive, irrelevant

In verdict.stance_breakdown these are separate counts. neutral means the neutral stance and nothing else: a source that looked and took no side. It used to also absorb inconclusive (a source that looked and could not tell) and unscored sources, which made three different situations read as one. Those are now inconclusive and unknown. irrelevant is off-topic and is excluded from every verdict denominator. If you were reading neutral as “everything undecided”, sum the three.

credibility_basis says whether credibility_score rests on a measurement (measured) or on nothing (unknown). An unmeasured source previously scored 100, the maximum, which ranked the least-grounded citation highest. If you filter on a credibility threshold, check this field — an unknown basis means the score carries no evidence, not that the source is bad.

snippet_source says where the snippet text came from: fetched (the page was read), grounding (a search-provider segment), or fallback. snippet_extraction reports whether a relevant passage was found at all.

Pagination Object
json
{  "total": 100,  "page": 1,  "limit": 20,  "totalPages": 5,  "hasNextPage": true,  "hasPreviousPage": false}

Integrations

WebCite integrates with popular AI platforms and automation tools. Use these integrations to add fact-verification to your workflows.

ClaudeMCP Server
Connect WebCite to Claude Desktop or Claude Code via Model Context Protocol (MCP).

Install via npm

bash
npm install -g webcite-mcp-server

View on npm: webcite-mcp-server

Claude Desktop Configuration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

json
{  "mcpServers": {    "webcite": {      "command": "npx",      "args": ["-y", "webcite-mcp-server"],      "env": {        "WEBCITE_API_KEY": "webcite_your_api_key_here"      }    }  }}

Claude Code

bash
claude mcp add webcite -- npx -y webcite-mcp-serverexport WEBCITE_API_KEY=webcite_your_api_key_here

Available Tools

verify_claimFull verification with stance analysis and verdict
2-4 credits
verify_claim_streamStreaming verification for long-running claims
2-4 credits
search_sourcesSearch for authoritative sources (citations only)
2 credits
list_citationsList your past verification results
1 credits
get_citationGet details of a specific verification
1 credits
upload_fileUpload a document to use as verification context
1 credits
get_source_previewResolve a citation to its source, with a bindBack check
1 credits
verify_batchCheck up to 200 quotes against their sources in one call
1 / item credits
verify_feedbackAccept, reject or flag a batch result
1 credits
analyze_conflictsRecompute and cross-check figures you already extracted
1 credits
analyze_documentExtract, recompute and cross-check a spreadsheet or PDF
3 credits
classify_documentCategory and covered types for an uploaded document
1 credits
document_gaps“Usually also here” checklist for a category
1 credits
extract_documentAny format to normalized text and units with provenance
1 credits
extract_figuresEvery number as a tagged, source-grounded figure
2 credits
accuracy_reportThe engine’s measured accuracy against its gold set
1 credits

Example Usage

In Claude, say: "Use WebCite to verify: The Eiffel Tower is 330 meters tall"

ChatGPTGPT Actions
Add WebCite fact-checking to any ChatGPT Plus GPT using OpenAI Actions.

Setup Instructions

  1. Go to ChatGPT → Explore GPTs → Create
  2. In the "Configure" tab, scroll to "Actions"
  3. Click "Create new action"
  4. Import the OpenAPI schema below
  5. Add your WebCite API key as authentication

OpenAPI Schema URL

text
https://api.webcite.co/openapi/gpt-actions.yaml

Authentication

In the Actions configuration, set:

  • Authentication type: API Key
  • Auth Type: Custom
  • Custom Header Name: x-api-key

Example Usage

Ask your GPT: "Fact check this: Electric vehicles produce more CO2 than gas cars"

ZapierZapier Integration
Automate fact-checking in your workflows with 6000+ app integrations.

Available Actions

Verify ClaimWhen triggered

Full verification with sources and verdict

Search SourcesWhen triggered

Find authoritative sources for a topic

Batch VerifyWhen triggered

Verify multiple claims from a spreadsheet row

Example Workflows

  • Slack channel → WebCite verify → Post result back
  • Google Sheet row → Batch verify claims → Update sheet
  • Email received → Extract claims → Verify → Reply

Unlock Full Integration Access

Free plan includes 100 credits/month. Upgrade to Builder for 500 credits and higher rate limits.

Rate Limits

API rate limits vary by plan. Exceeding limits returns a 429 error with retry information.

Rate Limits by Plan
PlanRequests/MinRequests/DayConcurrent
Free101002
Builder301,0005
Enterprise100+CustomCustom
Rate Limit Headers
All API responses include rate limit information in headers.
text
X-RateLimit-Limit: 30X-RateLimit-Remaining: 28X-RateLimit-Reset: 1706659200X-Credits-Used: 4X-Credits-Remaining: 496
429 Rate Limit Error
When rate limit is exceeded, the API returns a 429 status with retry information.
json
{  "statusCode": 429,  "message": "Rate limit exceeded. Please wait 45 seconds.",  "error": "Too Many Requests",  "retryAfter": 45}

Best Practices

  • Implement exponential backoff when receiving 429 errors
  • Use batch_verify for multiple claims instead of individual calls
  • Cache verification results to avoid redundant API calls
  • Monitor X-RateLimit-Remaining to proactively manage usage

Need Higher Limits?

Enterprise plans include custom rate limits, dedicated support, and SLA guarantees.

For more information, visit WebCite