API reference

Fact Check API

Post a claim, get a verdict with the evidence that produced it. One synchronous call, JSON in and out. Three rails share one meter: 8 Ounie credits per claim on REST and MCP, $0.096 USDC per claim keyless over x402.

Quickstart

curl -X POST https://factcheck.ounie.com/api/checks \
  -H "Authorization: Bearer fct_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "claim": "The Eiffel Tower was completed in 1889.",
    "strictness": "high"
  }'

The verdict comes back on the same request — typically in 5–12 seconds, since the check runs a live search and reads the pages it finds. There is no job to poll.

Authentication

Three credentials are accepted, in this order:

  • Your app keyAuthorization: Bearer fct_live_…, minted at /dashboard/api-keys. Up to 5 active. Only the sha256 hash is stored; the raw token is shown once.
  • The fleet master key — your ounie.com developer key (ounie_live_…) works here too, once you enable “Use across Ounie apps” in your ounie.com settings.
  • The shared session cookie — the dashboard uses it. Any signed-in .ounie.com browser session works.

Hosts that can't set a header (the Ounie AI Team's manual MCP entries, for one) may pass the key as ?api_key=fct_live_… on any endpoint.

A key can only ever spend its owner's credits, and reserve happens before any upstream work. An agent that runs out gets a 402 with the exact shortfall — it cannot overdraw and cannot run up a balance.

POST /api/checks

FieldTypeNotes
claimstring, requiredOne assertion. Max 2000 chars.
contextstringWho said it, where, what it answered. Max 1200 chars.
recency_daysintegerOnly weigh sources published in this window. 1–1825.
strictness"normal" | "high"high requires two independent domains for a decisive verdict. Default "normal".

The response

{
  "ok": true,
  "check": {
    "id": "…",
    "claim": "The Eiffel Tower was completed in 1889.",
    "strictness": "high",
    "status": "succeeded",
    "verdict": "supported",
    "confidence": 1,
    "reasoning": "Multiple independent sources confirm…",
    "evidence": [
      {
        "stance": "supports",
        "quote": "On March 31, 1889, the Eiffel Tower is dedicated in Paris…",
        "url": "https://www.history.com/this-day-in-history/march-31/eiffel-tower-opens",
        "title": "Eiffel Tower opens in Paris | March 31, 1889",
        "publishedAt": "2009-11-24"
      }
    ],
    "sources_searched": 11,
    "domains_cited": 3,
    "thin": false,
    "credits_spent": 8
  }
}

quote is verbatim from the page and url is a page we actually fetched — those two together are the contract. Evidence citing a URL the adjudicator was not shown is dropped before it reaches you, and title and publishedAt are filled in from our record of the page rather than from the model, so a real quote can never appear beside an invented date.

sources_searched is how many candidate pages the search returned; domains_cited is how many independent publishers survived into the evidence. When the two diverge sharply, the claim is popular but poorly sourced — which is worth knowing.

Verdicts & strictness

VerdictMeaning
SupportedIndependent published evidence backs the claim as written.
ContradictedPublished evidence directly conflicts with the claim.
MixedReal evidence on both sides, or a single uncorroborated source.
UnverifiableNothing published settles it either way.

With strictness: "high", supported and contradicted require agreeing evidence from at least two independent registrable domains. Fall short and the verdict degrades to mixed, with downgraded_from naming what it would otherwise have been. Two pages on one site count once.

One rule applies at every strictness: a decisive verdict with no agreeing evidence at all is never returned. It degrades regardless of what you asked for.

Thin results & refunds

A thin result is an unverifiable verdict with zero surviving evidence: we looked and there is nothing to show you. It is a non-answer, so it is never billed.

  • Credit rails (REST, MCP) — the full reserve is refunded pool for pool and no ledger entry is written. credits_spent is 0.
  • x402 — the payment is never settled. Verification happens before the check runs and settlement only after there is a verdict, because an on-chain settlement is final and there is no refund path. You get a 402 thin_result.
An unverifiablethat DID weigh evidence is not thin. “People have written about this and none of it establishes the claim” is a real finding, it comes with the sources we weighed, and it bills normally.

Reading past checks

Free, forever — reading work you already paid for never costs anything.

GET /api/checks?limit=20&verdict=contradicted
GET /api/checks/<id>
GET /api/credits          # your spendable balance
GET /api/pricing          # public: price, verdicts, x402 terms

MCP

A Streamable-HTTP MCP server, plus legacy SSE. Works with Claude, Cursor, ChatGPT, the AI SDK and the Ounie AI Team.

Endpoint  https://factcheck.ounie.com/api/mcp   (legacy SSE: /api/sse)
Auth      Authorization: Bearer fct_live_…

# For hosts that can't set static headers (Ounie AI Team):
https://factcheck.ounie.com/api/mcp?api_key=fct_live_…
ToolCostWhat it does
check_claim8 crAdjudicate one claim. Thin results refund in full.
get_checkfreeRe-read a check by id, with its full evidence.
list_checksfreeYour history, newest first, filterable by verdict.
get_verdict_taxonomyfree · publicThe four verdicts and the rules behind them.
get_credit_balancefreeSpendable Ounie credits.
get_pricingfree · publicCredit price and x402 terms.
whoamifreeThe authenticated key's owner.

x402 — keyless, pay per call

For agents with no Ounie account. USDC on Base; the 402 quotes the terms, you sign and retry.

curl -X POST https://factcheck.ounie.com/api/x402/check \
  -H "Content-Type: application/json" \
  -d '{"claim":"…","strictness":"high"}'

# → 402
{ "x402Version": 1,
  "accepts": [{ "scheme": "exact",
                "network": "base",
                "maxAmountRequired": "96000",
                "payTo": "0x…",
                "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }] }

curl -X POST https://factcheck.ounie.com/api/x402/check \
  -H "X-Payment: <base64 signed payload>" \
  -H "Content-Type: application/json" \
  -d '{"claim":"…","strictness":"high"}'

$0.096 per claim. The order is verify → check → settle: your signature is checked off-chain first (so a bad header cannot burn search budget), the check runs, and money only moves once there is a verdict with evidence to hand back.

Errors

StatusBodyMeaning
400claim_required · claim_too_long · strictness_invalidFix the payload.
401unauthorizedMissing or bad credential. Never a redirect — agent-safe.
402insufficient_creditsCarries required_credits, balance_credits and buy_credits_url. Nothing was charged.
402thin_result (x402 only)No evidence found; the payment was NOT settled.
429too_many_runningMax 5 checks in flight per account.
502check_failedAn upstream failed. Your credits were refunded.
503service_unavailableChecking is temporarily off. Nothing was charged.

Limits

LimitValue
Claim length2000 characters
Context length1200 characters
Recency window1–1825 days
Concurrent checks5 per account
Active API keys5 per account
Price8 credits · $0.096 on x402

Credits are shared across every Ounie app and bought at ounie.com. There is no subscription here and no per-app balance.