SerpGuard API live

Verify AI claims against the live web.

For developers checking AI-written code and docs before they ship. Claude extracts the checkable claims from your text, SerpApi fetches live Google results for each one, and each claim comes back with a verdict and a source you can open.

0 / 50,000
⌘/Ctrl + Enter to submit
Try

How it works

One POST · three upstream calls per unseen claim, at most seven

01ExtractClaude → claims
02SearchSerpApi → Google
03Rank sourcesdirect answers, then authority
04JudgeClaude → verdict
05CacheMongoDB

Claims, not vibes

Claude splits the text into discrete claims and restates each one so it stands alone as a search query.

Typed fact, code_api or statistic. Versions and figures are copied verbatim — correcting them would defeat the point.

Judged on sources only

The verdict prompt rules against the returned snippets, not the model's own knowledge.

A model checking a model agrees when both are wrong. The live search is the source of truth; Claude is the reader.

Google's own answers

The answer_box and knowledge_graph from the same response are read as evidence and ranked above the organic results.

No extra search — both arrive with it. An item with no link is still shown to the model, but can never be the cited source_url. Each claim reports its source_type: answer_box, knowledge_graph, organic or null.

Claims that expire

A claim that only holds for now is searched inside Google's past year (tbs=qdr:y) and tagged fresh results.

A window that is too thin, or that only yields unconfirmed, buys one unfiltered search of the same query. Worst case per claim: 3 searches, 4 Claude calls. Its verdict is cached for 7 days, not forever.

Unreadable ≠ unconfirmed

unconfirmed means the evidence was thin. A reply that could not be parsed is an error instead.

Raises verification_failed (500). No code path turns an unreadable answer into a verdict.

Cited or dropped

A source URL is kept only if it matches a result we actually sent to the model.

An invented link is dropped and logged rather than shown. The verdict still stands on the snippets.

A method that isn't there

For a code_api claim whose method name appears in no result, the verdict is contradicted.

A real method name returns something for a search of its own name. Never fires on zero results — that means the query failed, so the one rewrite searches the library without the name and judges the silence on its results.

Verdicts are cached

Each claim is keyed by a SHA256 of its normalized text, unique-indexed in MongoDB.

A hit returns cached: true with zero upstream calls. Normalization collapses case and spacing, not paraphrase. Time-sensitive verdicts expire after 7 days; the rest are kept.

Retries, once

Timeouts, connection resets, 429s and 5xx get exactly one retry, shared by both API clients. A query whose results come back about a different subject gets one rewrite; a past-year window that is too thin, or that produced unconfirmed, gets one unfiltered search — and none of them can stack.

A 4xx that cannot succeed on a second identical attempt is never sent twice. 5s connect / 30s read; Retry-After honoured but capped at 2s.

API

One JSON error envelope for every failure

POST/api/v1/checkskey200 · 400 · 401 · 413 · 422 · 429 · 500
GET/api/v1/health200 · liveness, no key
GET/api/v1200 · service description
GET/200 · this page

Authenticate with an X-API-Key header. This page uses the public key demo-key, rate limited to 30 checks per minute.

curl -X POST https://serpguard.onrender.com/api/v1/checks \
  -H 'content-type: application/json' \
  -H 'X-API-Key: demo-key' \
  -d '{"text":"The Eiffel Tower is located in London."}'
Sample response — captured from the live API