Find out why a URL is not in your results
why_not(url) reports present, removed with a typed reason, or never admitted — so a gap in coverage is a fact you can act on rather than silence.
The problem
Every other search API answers a missing document with an empty list, which is indistinguishable from "your query was wrong". For anything that has to be defensible — compliance, due diligence, monitoring — "we did not find it" is not the same claim as "it is not there", and you need to know which one you have.
What to send
urlthe exact URL
Checked against the index and the removal ledger.
The code
import httpx
HEADERS = {"x-api-key": "ulb_..."}
must_cover = [
"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32024R1689",
"https://www.federalregister.gov/documents/2026/01/15/",
]
for url in must_cover:
r = httpx.get("https://api.unlob.com/why_not",
headers=HEADERS, params={"url": url}).json()
match r["status"]:
case "present":
print(f"OK {url}")
case "removed":
# Recorded with a reason, against an append-only ledger.
print(f"REMOVED {url} ({r['reason']})")
case "never-admitted":
# A real gap. Report it as a gap rather than as no result.
print(f"GAP {url} ({r['reason']})")The mistake to avoid
Reporting a coverage gap to your users as "no results found". They are different claims and only one of them is honest. If your product makes assertions about what exists, surface the gap — it is the difference between a tool people can trust and one they cannot.
Frequently asked questions
What removal reasons are there?
Typed ones, including retention expiry, access starvation, replacement by a stronger passage covering the same ground, and a tombstoned source that asked to be removed or became unfetchable. Each is recorded against an append-only ledger rather than inferred after the fact.
Can I ask about a whole domain?
why_not takes one URL. For a domain, sample the URLs you actually care about — an audit of the twenty pages that matter is more useful than a count over a domain you cannot enumerate anyway.
Try it against your own queries
10,000 requests a month on the free tier, no card. Enough to run a real evaluation set rather than a demo.