NEW/search/lite is live at $0.25 / 1k reqs, beating Parallel turbo 91/100See the battle →
Research · September 22, 2026

Deep search on SimpleQA

1,000 seeded questions from OpenAI's SimpleQA, run through the Keiro deep search pipeline. One mechanical check per question: the gold answer must appear in the snippets or page content we return. No reader model, no LLM judge. 953 of 1,000 passed.1

Keirolabs Research · n = 1,000 · seed 42 · retrieval-only

The leaderboard

SimpleQA accuracy (%)
707580859095100Keiro deep search95.3Firecrawl94.7Tavily93.3you.com92.1Exa91.9Parallel91.0Claude Search90.5Perplexity85.9Google82.2Brave76.1
Fig. 1 — Best published SimpleQA run per provider, each under its own harness (refs 2–5). Third-party scores are answering pipelines: an LLM reads each provider's results and writes the final answer, graded by a judge model. Keiro's number is retrieval-only — the gold answer text must appear in the returned data. Cross-harness scores are directional, not apples-to-apples.

The result

The headline number is 95.3%: 953 of 1,000 seeded SimpleQA questions had the gold answer present in the data the pipeline returned. The raw normalized substring score is 87.9%; a hand audit of every raw miss — date and comma variants, abbreviations, transliterations, split compounds — rescues 7.6 points. 43 misses stay misses.

Every question in the sample is deterministic: seed 42, a Fisher–Yates shuffle over OpenAI's 4,326-question SimpleQA set.6 Every returned payload — snippets and crawled page text — is preserved in results.json in the repo, so any judged call can be re-audited by hand.1

Where the score comes from

Accuracy (%) by stage
025507510072.4SERP snippets onlyreturned snippets+15.3+ full-page fetch+ crawled content+7.6+ variant judging+ audited misses95.3Judged accuracyof 1,000 questions
Fig. 2 — The same questions measured at three stages. Snippets alone reach 72.4%. Full-page fetching adds 15.3 points — the stage most search APIs skip. 175 questions pass only through crawled content, never snippets. Top-1 accuracy after re-ranking is 73.7% vs 66.9% in raw SERP order.

Stages 1–2 measured on the merged run of 1,141 records across 32 result files; stage 3 on the curated 1,000-question sample (seed 42), where the raw score is 87.9%.


The inversion

A normal search API returns the same artifact every time: ranked links with two-line snippets. Crawling, parsing and answer-finding stay your problem. Keiro's deep search moves that work server-side — the response carries the answer's context, not a list of places to look for it.

Standard search APIKeiro deep search
1Query matches a prebuilt index1Query fans out to the top 10 live results
2Ten links with two-line snippets return2Every candidate is fetched and read in full
3You crawl the pages yourself3Pages are scored for answer likelihood and re-ranked
4You parse and extract the answer yourself4The response carries ranked snippets plus full content
5The API's job ends at the URL5The API's job ends at the answer

On this benchmark the inversion is worth 22.9 points: 72.4% when the gold answer has to appear in SERP snippets alone, 95.3% with the fetch and re-rank stages behind it.


Four stages between query and answer

One POST to /v1/search in, one ranked payload out. Everything between — fanout, fetch, scoring, re-rank — runs server-side. No reader model anywhere in the path.

01
PROSPECTlive retrieval sweep. Fans the query across the live index and returns the strongest ten candidates. No static database — every search sees the web as it is right now.
10 candidates
02
HARVESTfull-page fetch fabric. Every candidate is fetched in parallel headless lanes — browser-grade rendering for JS-heavy pages — and parsed down to clean text.
7.9 avg fetched
03
CALIPERanswer-likelihood scoring. A scoring model reads each page end-to-end and assigns an answer-likelihood score. Ranking signal only — nothing is answered, nothing rewritten.
1 score / page
04
MERIDIANre-rank and assembly. Results are re-ordered by likelihood; snippets and full page content are assembled into a single payload.
p50 14.7 s

Consistency

Accuracy (%) per chunk of 50
859095100median 96Chunk 100: 92% judgedChunk 150: 98% judgedChunk 200: 94% judgedChunk 250: 96% judgedChunk 300: 96% judgedChunk 350: 96% judgedChunk 400: 98% judgedChunk 450: 98% judgedChunk 500: 92% judgedChunk 550: 86% judgedChunk 600: 94% judgedChunk 650: 96% judgedChunk 700: 94% judgedChunk 750: 94% judgedChunk 800: 100% judgedChunk 850: 98% judgedChunk 900: 90% judgedChunk 950: 98% judgedChunk 1000: 96% judgedChunk 1050: 100% judged1005501050
Fig. 3 — The 1,000 questions ran as 20 seeded chunks of 50. Judged scores range from 86% to 100%, median 96%, two chunks at a perfect 50/50 — the score is not carried by an easy slice. Chunk 1050 is excluded: it ran during a Keiro credit outage, and its records remain in results.json for audit.

What counts as a hit

The raw check is mechanical: a normalized substring test over everything returned. The judged pass adds a hand audit of every miss, and it is deliberately stingy about rescues.

VerdictRule
Counts as a hitVariant forms of the same fact: date-order and comma variants · abbreviations (km/kilometers, TX/Texas) · transliterations (Jung/Jang) · numerals vs words · ordinal suffixes · non-English date renderings · split compounds where every element appears verbatim in one page.
Stays a missDeliberately strict — no credit for almost: derived answers (durations or conversions the page lets you compute but never states) · paywalled numerics · half-missing compounds · contested golds where sources contradict SimpleQA's answer.

Benchmarks

Each provider's strongest published SimpleQA result we could find, with the harness that produced it. The harnesses differ — answer models, judges, question counts — so treat the gaps as directional. The structural difference that favors Keiro: every other score gets a reader LLM to repair retrieval mistakes; ours does not.

ProviderSimpleQA (%)Δ vs KeiroHarnessRef
Keiro deep search95.30Own harness · retrieval-only judged check · n=1,000, seed 42[1]
Firecrawl94.7−0.6GPT-5.4 agent, high reasoning, ≤20 search/extraction calls, official grader[2]
Tavily93.3−2.0GPT-4.1 answers from retrieved docs, official SimpleQA classifier · full 4,326-question set · self-published[3]
you.com92.09−3.2GPT-5.4 nano synthesis + GPT-5.4 mini judge · open-source harness[4]
Exa91.9−3.4GPT-5.4 agent (also 90.06% on you.com's harness)[2]
Parallel91.0−4.3GPT-5.4 agent (also 89.78% on you.com's harness)[2]
Claude Search90.5−4.8GPT-5.4 agent, native search tool[2]
Perplexity85.92−9.4GPT-4.1 answers, official SimpleQA classifier[5]
Google82.15−13.2SERP via Serper, GPT-4.1 answers (80.17% on you.com's harness)[5]
Brave Search76.05−19.3GPT-4.1 answers, official SimpleQA classifier[5]

The 43 true misses

After judging, 43 of 1,000 questions were true misses. They cluster into four failure classes — in three of them the fact is not on the reachable open web at all.

Derived answers

Durations and unit conversions the returned pages let you compute but never state outright. A retrieval check does not do math.

Paywalled numerics

Book-chapter values and subscription data sources — the fact exists, but behind a login rather than on the open web.

Deep-lookup facts

Episode credits, award lists, docket dates, niche article specifics: the long tail that no index ranks first.

Contested golds

Sources contradict SimpleQA's stated answer — wrong year, wrong season. We stay with the sources and take the miss.


Reproduce this

testbench.js is a standalone, zero-dependency Node ≥ 18 script — no npm install. It seeds a deterministic Fisher–Yates sample of SimpleQA, runs each question through the pipeline, and writes every record — including the full returned payload — to results.json.

$ SAMPLE_SIZE=1000 SAMPLE_SEED=42 node testbench.js
# SimpleQA retrieval eval: 1000 questions (of 4326), seed=42
# per-question records (payload included, for judging) -> results_simpleqa.json
# { hit_rate: 0.8773, content_hit_rate: 0.7932, top1: 0.737, retries: 267 }--- testbench.js (core) ---
// SimpleQA retrieval eval for the Keiro search API.
// The API's one job: surface the gold answer in the returned snippets/content.
// No reader model, no answer extraction - retrieval, ranked.

// seeded RNG (mulberry32) + Fisher-Yates sample: deterministic per seed
function mulberry32(seed) {
  return function () {
    seed |= 0; seed = (seed + 0x6d2b79f5) | 0;
    let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

// normalize: lowercase, strip articles, strip non-alnum, collapse whitespace
function normalize2(s) {
  return String(s || "")
    .toLowerCase()
    .replace(/\b(a|an|the)\b/g, " ")
    .replace(/[^a-z0-9 ]/g, " ")
    .replace(/\s+/g, " ")
    .trim();
}
const goldIn = (text, gold) =>
  !!text && normalize2(gold) !== "" && normalize2(text).includes(normalize2(gold));

async function runOne(q) {
  const res = await fetch(API_URL, {
    method: "POST",
    headers: { "Authorization": "Bearer " + KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ query: q.question, max_results: 10 }),
  });
  const payload = await res.json();
  const results = payload.results || [];
  const fetched = results.filter((r) => r.content);

  const rec = {
    snippet_hit: goldIn(results.map((r) => r.snippet || "").join(" "), q.gold),
    content_hit: goldIn(fetched.map((r) => r.content || "").join(" "), q.gold),
    gold_rank: firstRankHit(results, q.gold),   // top-1 tracking
    latency_ms: payload.meta ? payload.meta.latency_ms : 0,
    // full returned payload kept, so every judged call is auditable
    snippets: results.map((r) => ({ title: r.title, snippet: r.snippet })),
    content: fetched.map((r) => ({ title: r.title, text: r.content.slice(0, 8000) })),
  };
  rec.hit = rec.snippet_hit || rec.content_hit;
  return rec;
}
  • SAMPLE_SIZEquestions per run — default 100, this report used 1,000
  • SAMPLE_SEEDseed for the Fisher–Yates sample (default 42)
  • SAMPLE_OFFSETslice deeper into the 4,326-question set
  • BENCH_OUTresults file (default results_simpleqa.json)

Each question costs ~1 Keiro credit and ~2.2 s of pacing at the starter tier's 30 req/min. The full 1,000-question results file — every snippet and crawled page — is in the repo.1


Method notes

What is SimpleQA?

SimpleQA is OpenAI's benchmark of 4,326 short factual questions written to elicit hallucinations, each with a verified short answer. Our runs sample it with a fixed seed (42): 100 questions by default, 1,000 for the headline run, deterministic per seed.

Why is Keiro's score retrieval-only while competitors answer?

The Keiro API returns ranked data — snippets and full page content — and this benchmark checks whether the gold answer text appears in that data. No reader model writes an answer, no LLM judge grades it. That is a stricter test: an answering pipeline gets an LLM that can rephrase, merge and fix; our number only counts answers that were literally present in what we returned.

Is 95.3% comparable to Tavily's 93.3%?

Directionally, not apples-to-apples. Every third-party number in the leaderboard comes from a different harness with a different answer model and judge (GPT-4.1, GPT-5.4 agent, GPT-5.4 nano/mini). Each is the provider's best published SimpleQA run, linked to its source. Keiro's number is the only retrieval-only one — read the gap as ours being measured the harder way.

How exactly is a hit judged?

Two stages. First a normalized substring check (lowercased, articles and punctuation stripped) of the gold answer across all snippets and crawled content. Then every raw miss is hand-audited for legitimate variant forms — date and comma variants, abbreviations, transliterations, split compounds. The audit does not accept derived answers or contested golds, which is why 43 of the raw misses stayed misses on the 1,000-question run.

Can I reproduce this?

Yes. The benchmark script is a single zero-dependency Node file (Node ≥ 18). It seeds a deterministic Fisher–Yates sample of SimpleQA, runs each question through the pipeline, and writes every record — including the full returned payload — to results.json, so any judged call can be re-audited. Each question costs about 1 Keiro credit.

What is deep search good for?

Any agent flow that needs the fact to actually be in the context: research agents, verification steps, citation-grounded answers, RAG ingestion. The +15.3 points from full-page fetching is the part most search APIs skip — snippets alone hit 72.4% on this benchmark.

Use the same pipeline

The endpoint behind this report returns ranked snippets and full page content for any query — the same data this benchmark scored.

References

  1. 1.Keirolabs. Deep endpoint benchmark results — script, all 1,141 records, full returned payloads. GitHub (2026). link ↗
  2. 2.Van Zyl, J. (ecosystem.Ai). “I tested Firecrawl, Exa, Parallel and Claude Search on SimpleQA.” GPT-5.4 answering agent, official grader (2026). link ↗
  3. 3.Tavily. “Tavily achieves SOTA on SimpleQA benchmark.” GPT-4.1 answering, official classifier, full 4,326-question set (2026). link ↗
  4. 4.You.com. web-search-api-evals — open-source harness, GPT-5.4 nano synthesis and mini judge. GitHub (2026). link ↗
  5. 5.Tavily. tavily-search-evals — GPT-4.1 answering pipeline, official SimpleQA classifier. GitHub (2026). link ↗
  6. 6.OpenAI. “Measuring short-form factuality in large language models with SimpleQA.” Wei et al. (2024); benchmark sample n=1,000 drawn with seed 42. link ↗