Verify API
Audit a claim against live web evidence or citations you supply: claim in, four-label verdict out — with span-level quotes, machine-readable reason codes and source authority. Typically takes 5–15 seconds.
/v1/verify
Generally available. A deployment with the endpoint switched off answers 404. Legacy alias: POST https://searchpipe.tech/verify.
Authorize
Authenticate with your sp- API key in the Authorization: Bearer sp-YOUR_KEY header; X-API-Key: sp-YOUR_KEY is also accepted. Verification uses the same key and credit balance as /v1/search.
Request
Send Content-Type: application/json. Only claim is required. Input moderation applies: rejected content returns 400 without a charge.
Body parameters
| Parameter | Type | Description |
|---|---|---|
claim | string · required | The claim (statement or citation) to verify — max 2000 characters. |
mode | string · default auto | Evidence route: paper (DOI/arXiv), web, or auto — a DOI or arXiv signal picks the paper route. |
evidence_urls | string[] · optional | Up to 5 caller-supplied citations to verify; URLs are SSRF-checked. |
max_evidence | integer · default 5 | Maximum number of evidence items to return (1-10). |
Request example
curl -X POST https://searchpipe.tech/verify \
-H "Authorization: Bearer sp-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"claim": "Attention Is All You Need introduced the transformer architecture"}'import httpx
resp = httpx.post(
"https://searchpipe.tech/verify",
headers={"Authorization": "Bearer sp-YOUR_KEY"},
json={"claim": "Attention Is All You Need introduced the transformer architecture"},
timeout=60,
)
data = resp.json()
print(data["verdict"], data["reason_code"], data["confidence"])
for ev in data["evidences"]:
print(ev["per_evidence_verdict"], ev["url"])const resp = await fetch("https://searchpipe.tech/verify", {
method: "POST",
headers: {
"Authorization": "Bearer sp-YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ claim: "Attention Is All You Need introduced the transformer architecture" }),
});
const data = await resp.json();
console.log(data.verdict, data.reason_code, data.confidence);
for (const ev of data.evidences) console.log(ev.per_evidence_verdict, ev.url);package main
import (
"bytes"
"fmt"
"io"
"net/http"
"time"
)
func main() {
payload := []byte(`{"claim":"Attention Is All You Need introduced the transformer architecture"}`)
req, _ := http.NewRequest("POST", "https://searchpipe.tech/verify", bytes.NewReader(payload))
req.Header.Set("Authorization", "Bearer sp-YOUR_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 60 * time.Second}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}import java.net.URI;
import java.net.http.*;
import java.time.Duration;
public class SearchPipeVerify {
public static void main(String[] args) throws Exception {
String json = "{\"claim\":\"Attention Is All You Need introduced the transformer architecture\"}";
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://searchpipe.tech/verify"))
.timeout(Duration.ofSeconds(60))
.header("Authorization", "Bearer sp-YOUR_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> resp =
client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
}
}using System.Net.Http.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "sp-YOUR_KEY");
var payload = new
{
claim = "Attention Is All You Need introduced the transformer architecture",
};
HttpResponseMessage resp = await client.PostAsJsonAsync("https://searchpipe.tech/verify", payload);
resp.EnsureSuccessStatusCode();
Console.WriteLine(await resp.Content.ReadAsStringAsync());Response
Every verdict carries a machine-readable reason_code from a fixed whitelist, and every evidence item carries a verbatim quote span — never a free-form generated explanation. This illustrative response shows the shape; values are examples, not a live verification.
{
"verdict": "supported",
"confidence": 0.93,
"reason_code": "quote_span_found",
"evidences": [
{
"url": "https://arxiv.org/abs/1706.03762",
"title": "Attention Is All You Need",
"source_tier": "preprint",
"quote": "We propose a new simple network architecture, the Transformer, based solely on attention mechanisms",
"span_start": 0,
"span_end": 103,
"per_evidence_verdict": "supported",
"confidence": 0.95,
"url_health": {
"status_code": 200,
"redirected": false,
"wayback_snapshot": null,
"fetched_at": "2026-10-30T09:00:00Z"
}
}
],
"timing": {"v_prepare": 0.4, "v_evidence": 3.1, "v_judge": 6.2, "v_health": 0.8}
}Verdict labels
| verdict | Meaning |
|---|---|
supported | Fetched evidence whose text explicitly supports the claim. |
partial | The evidence supports part of the claim, or the support is weak. |
unsupported | Reachable evidence does not support the claim — catches misattributed or hallucinated citations. |
inconclusive | No verdict possible: fetch failures, paywalls or insufficient checkable evidence. A valid deliverable, billed like any other verdict. |
reason_code whitelist
| reason_code | Meaning |
|---|---|
doi_match | The claim resolved to a DOI that points to a real paper. |
title_match | The claim matched a known paper title (fuzzy). |
quote_span_found | A verbatim span supporting the claim was located in a fetched source. |
no_supporting_evidence | Sources were reachable but none of them supports the claim. |
fetch_failed | Candidate sources could not be fetched. |
paywall | Candidate sources sit behind a paywall. |
low_authority | Only low-authority sources were available, so confidence stays low. |
conflicting_evidence | The evidence points in more than one direction. |
Response fields
| Field | Type | Description |
|---|---|---|
verdict | string | One of supported, partial, unsupported, inconclusive (table above). |
confidence | number | 0-1 confidence in the verdict. |
reason_code | string | Machine-readable reason from the whitelist above — template phrases, never free-form text. |
evidences | array | Evidence items, each with url, title, source_tier (official/press/academic/preprint/community/unknown), quote, span_start, span_end, per_evidence_verdict, confidence and url_health (status_code, redirected, wayback_snapshot, fetched_at). |
timing | object | Per-stage wall time in seconds (v_prepare, v_evidence, v_judge, v_health). |
Verify a batch of claims
/v1/verify/batchCheck up to 20 claims in one synchronous request and handle each result independently. Partial failures do not fail the whole batch.
| Parameter | Description |
|---|---|
claims | Required array of 1–20 statements; each is limited to 2,000 characters. |
mode | auto (default), paper, or web; applied to the entire batch. |
max_evidence | 1–10 evidence items per claim; default 5. This endpoint does not accept evidence_urls. |
| Field | Meaning |
|---|---|
results[] | Matches the order of claims. Each item has the single-claim response shape, or null when that item fails. |
failed[] | Each failure includes index (zero-based position in claims) and error. Partial failures do not fail the whole batch. |
curl -X POST "https://searchpipe.tech/v1/verify/batch" \
-H "Authorization: Bearer sp-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"claims": [
"FastAPI is a Python web framework.",
"Python was created by Guido van Rossum."
],
"mode": "web",
"max_evidence": 5
}'The batch is charged before execution. Failed items are refunded; completed inconclusive verdicts are charged. The batch is a synchronous REST endpoint, not a background job — there is no separate MCP batch tool.
Billing and error handling
- 1 credit per claim. An
inconclusiveverdict is a completed verification and is charged; overall pipeline failures return503and are refunded automatically. - Input moderation rejections return
400without a charge. - Verdicts are not cached — a verdict depends on the live state of the cited pages.
- A deployment with the endpoint switched off answers
404.