The Caselaw API Legal AI Builders Have Been Waiting For
· LawDiver
Full boolean and semantic legal search, case retrieval, and a cite checker that actually reads, resolves, and scores citations — over a corpus of 10 million opinions kept current around the clock. No Westlaw contract required.
The Caselaw API Legal AI Builders Have Been Waiting For
Every team building legal AI hits the same wall, and it is always the same wall.
You build the agent. The reasoning is good. The drafting is good. The product demos beautifully. And then somebody asks the only question that matters: where does the law come from?
At that point there have been exactly two answers. You can scrape and stitch — a bulk dump here, a court website there, a citation regex you wrote on a Tuesday — and ship something that finds cases the way a search box from 2003 finds cases. Or you can go get a data license from one of the incumbents: a six-figure conversation, a twelve-month procurement cycle, usage caps written by people whose business model your product threatens, and, very often, no at the end of it anyway. Vendors do not rush to arm their replacements.
That is why the single most common complaint we hear from legal AI builders is not about models. It is not about hallucination, or context windows, or evals. It is this: there is no caselaw API that lets an application do legal research at the level a lawyer actually does legal research.
Today there is.
LawDiver's public API opens the same retrieval and citation stack our own products run on: full legal search with real engine control, case retrieval with the citation graph attached, and a cite checker that resolves and scores individual citations — or every citation in an entire brief. It is a versioned REST API, authenticated with an API key, billed per unit of work, and free during the current rollout.
GET https://lawdiver.com/api/v1
That discovery document is unauthenticated on purpose. You should be able to see what an API offers and what it costs before anyone asks you for a signature.
What the LawDiver caselaw API includes
| Endpoint | What it does |
|---|---|
POST /api/v1/search | Case search: boolean, semantic, hybrid, citation, name, or auto |
POST /api/v1/citations/resolve | Resolve a cite or case name to candidate cases (free) |
POST /api/v1/cases/retrieve | Cite or name in, case out — with did-you-mean when ambiguous |
GET /api/v1/cases/:id | Case metadata by opinion or cluster id |
POST /api/v1/cases/batch | Up to 50 case lookups in one round trip |
GET /api/v1/cases/:id/good-law | Good-law status and negative treatments |
GET /api/v1/cases/:id/cited-by | Everything citing this case, paginated |
GET /api/v1/cases/:id/pdf | The full opinion PDF with processing material appended |
POST /api/v1/citecheck/cite | Check one citation, or up to 50 at once |
POST /api/v1/citecheck/document | Upload a PDF or Word brief; check every cite in it |
GET /api/v1/citecheck/jobs/:id | Job status |
GET /api/v1/citecheck/jobs/:id/report | The finished cite-check report |
GET /api/v1/jurisdictions | The jurisdiction choices search accepts |
GET /api/v1/usage | Your usage and spend to date |
Every response carries a requestId. Every billable response carries a usage block showing exactly what you were charged and why. Rate-limit headers are on every call. Idempotency-Key is honored on the billable POSTs, so a retried request replays the original answer instead of re-running — and re-charging for — the work.
Legal search that behaves like research, not like a search box
The hardest part of legal retrieval is that "search" is not one operation. A lawyer types five fundamentally different things into the same box:
410 U.S. 113— a citation. There is exactly one right answer.Roe v. Wade— a case name, possibly misspelled, possibly half-remembered."clearly established" /s qualified immunity— a boolean query with a proximity connector.can a landlord withhold a deposit for ordinary wear and tear— a concept, phrased as a question, using none of the words the opinion uses.Miranda v. Arizona qualified immunity /s clearly established— all of the above at once.
Systems that treat these as one problem are bad at all five. So the API runs four independent engines and a router that decides which of them a query deserves.
The router produces a plan, not a label
This is the design decision everything else follows from. A classifier that stamps a query "this is a citation query" throws away everything else the string contained. Our router instead extracts every signal at once and produces a plan: the reporter citations it found, the docket numbers, the X v. Y caption, the parsed boolean expression, the jurisdiction phrases lifted out into filters, and the residual concept text.
That is why Miranda v. Arizona qualified immunity /s clearly established runs the name engine against the caption and the keyword engine against the connectors simultaneously, and lets fusion decide which mattered — instead of picking one interpretation and silently discarding the other.
It is also why constraints become filters and never search terms. Leave "5th Circuit" in the query text and you get opinions that discuss the Fifth Circuit. Lift it into a filter and it removes most of the corpus before any expensive work happens. Same words, completely different query.
Six search types — you decide how much control you want
POST /api/v1/search
{
"query": "\"clearly established\" /s qualified immunity NOT prison",
"jurisdiction": { "type": "federal_circuit", "circuit": "11" },
"searchType": "keyword",
"limit": 20,
"filters": { "dateFrom": "2015-01-01", "publishedOnly": true }
}
searchType accepts:
auto(default) — the router picks. Recommended, and what our own UI runs.citation— pin the citation engine. Exact reporter-key lookup against a normalized citation index.case_name— pin the name engine. Trigram-indexed on case name and party names, soroe wadeand misspellings still land.keyword— pin the lexical engine. Boolean, phrase, and proximity over a Lucene index with BM25 ranking and field boosts on body, name, and syllabus.semantic— pin the vector engine. Meaning-space retrieval, no shared vocabulary required.hybrid— run keyword and semantic together and fuse them.
Pinning is not a hint; it is honest. If you pin citation on a query with no citation in it, the API tells you the engine was dropped for want of usable input — rather than returning an empty result set that is indistinguishable from "this case does not exist." That distinction has burned every builder who has ever integrated a search API.
Boolean and proximity connectors, done correctly
Uppercase AND, OR, NOT are operators. Lowercase and is a word, because trust and estate is a phrase a lawyer types in lowercase and means literally. Quoted runs stay intact. And the Westlaw-style proximity connectors work:
/s— same sentence/p— same paragraph/3orw/3— within n words, in either order
Here is the part most implementations get wrong. Postgres full-text search has exactly one positional operator, a fixed word distance. It cannot express "same sentence" or "same paragraph" at all. The tempting shortcut is to encode /s as "within 10 words" and call it done — which returns confidently wrong results instead of failing, the worst possible failure mode in a research tool.
So we split the work: the inverted index does recall (every required term appears somewhere in the document), and proximity is verified in code against the candidate text, sentence by sentence and paragraph by paragraph. /s means what a lawyer means by /s.
Semantic search, and why there are two vector sets
Embeddings are Qwen3-Embedding-8B at 1024 dimensions, stored as half-precision pgvector values and retrieved through a binary-quantized HNSW index — a fast Hamming first pass, then a full-precision rerank of the shortlist. Cosine similarity: the angle between vectors, not their length, so a two-paragraph holding and a 200-page opinion can be "about the same thing."
We embed two different things. One set embeds the opinion's own body. The other embeds our model-authored analysis of the opinion — issue, holding, posture, disposition. A question phrased the way a lawyer would ask it matches the analysis set far better, because that text is already written in the language of issues and holdings; the body set catches what the analysis omitted. Search covers both, so recall is the union.
Fusion, jurisdiction filters, and what comes back
Keyword and semantic scores are convex-combined with eligibility renormalization; citation and name hits act as lookup overrides rather than fusion participants, because an exact reporter-key match is proof, not an estimate.
Jurisdiction is required on every search — an unscoped national query is the slowest thing we can run and almost never what the caller meant. Eight published choices cover what lawyers actually pick: all states, all states plus federal, all federal, one state, one state plus federal, a named circuit (1–11, DC, Federal), federal district, or the U.S. Supreme Court alone.
Filters run inside every engine query, never as a post-filter: date range, published-only, include-unpublished, good-law-only.
Two defaults are deliberately mirror images of each other, and it is worth knowing why:
- Unpublished opinions are hidden by default, because in most jurisdictions they cannot be cited as precedent at all. One flag brings them back, because "cannot be cited" is not universal and sometimes the unpublished disposition is the one in your own case.
- Bad law is never hidden by default. An overruled case is still the case the researcher went looking for. It is flagged, not suppressed.
goodLawOnlyexists if you want it, and it is off unless you ask.
Every result carries good-law status inline — status, negative, negativeTreatmentCount, basis, and a separate unknown flag that means not yet determined, published apart from negative precisely so your application cannot mistake silence for approval. Every result also carries a snippet (usually the passage where a later court described the case), a plain-English matchExplanation, and a retrievalUrl for the full PDF.
Search is billed per case returned, not per search. An empty result set is free.
A citation checker built for legal AI, not string matching
We will say this plainly: we have not seen another citation checker that works this well, and the reason is not a better model. It is that the problem was framed correctly.
Most "cite checkers" ask does this string look like a real citation? That question is unanswerable and the answer is worthless. A hallucinated citation looks exactly like a real one — that is what makes it dangerous. The right question is:
Here is a citation string. Does it name a real case in a corpus we actually hold, what is its correct Bluebook form, and is it still good law?
That question has a determinate answer, and the whole system is built to give it.
Deterministic identification first
A reporter citation is globally unique to one decision. Normalize 410 U.S. 113 to a canonical reporter key and it is a single indexed lookup against 15.5 million citation-index rows and 18 million parallel-citation records, not a scan of ten million opinions. The identification layer is deterministic: the same document produces the same citation spans, the same reporter keys, and the same short-form resolutions on Monday that it produced on Friday. That is what makes results reproducible, auditable, and safe to rebuild.
The recognizer started from the open-source eyecite work by the Free Law Project and was substantially extended in-house — more citation types, tighter reporter resolution, short-form chains, and a reconciliation step against our own reporter-key index that turns a raw text match into a resolved graph edge. It has been run across the entire corpus: roughly 10 million completed scans producing 182 million in-text citations with character offsets and pin cites, and 78 million resolved opinion-to-opinion edges.
A probabilistic layer sits on top as a completeness net, not as the backbone. Courts invent cite forms, OCR garbles reporters, statutes get referred to by popular name — a grammar is systematically blind to all of it. So an LLM pass, under a harness built to suppress invention, looks for citations the deterministic scanner did not mark. Its finds are stored as a distinct source, so you can always see which edges came from the parser and which from the model. Determinism is the backbone; probability is the net. Neither philosophy alone survives contact with real briefs.
Verdicts that refuse to lie
POST /api/v1/citecheck/cite
{ "citations": ["Smith v. Jones, 570 U.S. 744 (2013)", "123 F.4th 999 (5th Cir. 2024)"] }
Each citation comes back with one of six verdicts, and the taxonomy is the product:
valid— an exact reporter-key match and the case name, year, and court as written agree with that decision. Both halves are required.name_mismatch— the reporter key resolved to a real case, but the party names, year, or court as written do not match it. This is the shape of a hallucinated citation: a real cite glued to the wrong caption. It is the single most important verdict in the system, and it is never reported asvalid. The resolved candidate comes back too, so you can show the user exactly what was substituted.likely_valid— we found candidates by name or partial signal, but the citation as written does not key to any of them: a transposed volume, a wrong page, a misremembered reporter. Up to three candidates are returned, ranked, and we deliberately do not pick one. Silently "correcting" a citation to a case the author never read is the worst thing a cite checker can do.not_found— nothing in the corpus matched. Note carefully: this is not the same as "this citation is fake," and the response says so through an explicitcorpusCaveatfield.unverified— we have no source that can answer. Some statute sites return HTTP 200 for sections that do not exist, so a live probe there proves nothing. Reporting "not found" off a source incapable of detecting absence would be an accusation dressed up as a finding.unverifiedsays the honest thing and hands you the official link instead.error— the check itself failed. Emitted as a full row with every field present, never omitted, because an omitted row reads as "checked and fine." And it is not billed: a failed check is not a finding you paid to learn.
Scoring you can act on
Every candidate carries matchedBy — reporter_key, case_name, volume_page_near (the classic volume/page transposition), or docket_number — plus a confidence from 0 to 1 that reaches exactly 1.0 only for a reporter-key match. There is no fuzzy 0.97 standing in for certainty. Candidates also carry the correct bluebookCitation assembled from stored metadata, every parallel cite on file so a caller can recognize their own spelling, court, jurisdiction, year, published status, cited-by count, full good-law report, and a retrieval URL.
That is the difference between a checker that tells your user "this looks fine" and one that tells them "this reporter cite is real, but it belongs to a different case; here is that case, here is its correct Bluebook form, and by the way it was questioned by the Ninth Circuit in 2021."
Whole documents, not just citation strings
POST /api/v1/citecheck/document → { "jobId": "..." }
GET /api/v1/citecheck/jobs/:id → status
GET /api/v1/citecheck/jobs/:id/report → the finished report
Upload a PDF or Word brief and every citation in it gets checked — the same extractor our drafting product runs, so the two never disagree about what is in a document. A few things matter here that only show up on real filings:
Short forms are bound, not re-resolved. Celotex, 477 U.S. at 324 is not an independent authority; it binds to a full cite earlier in the same document and inherits that verdict. Resolving it standalone would treat the pincite as a first page and report not_found for a correctly written Bluebook short form. Id. and supra chains are resolved the same way. This is the failure mode that makes most document checkers unusable on actual briefs.
Non-case citations are counted, not guessed at. The extractor also finds statutes, rules, and regulations. In the case-corpus checker they are reported as skipped with a count, rather than reported as "not found" — a false negative about something we never had a way to verify from that index is worse than saying nothing.
Positions come back. Each result carries docCharStart and anchorText, so you can highlight the exact span in your own viewer instead of string-matching your way back into the document.
Results are returned in document order with a summary count of valid, likely-valid, not-found, name-mismatch, and error — plus a rendered report you can hand to a partner.
And there is a free endpoint, POST /api/v1/citations/resolve, that turns a cite or a name into candidate cases at no charge. Use it liberally in an agent loop before deciding what is worth a full check.
The caselaw corpus under the API
An API is only as good as what it searches.
- ~10 million opinions, with majority, concurrence, and dissent each individually addressable
- U.S. Supreme Court, all federal courts of appeals, federal district courts, and the appellate and supreme courts of all fifty states
- 78 million resolved citation edges; 182 million in-text citations with offsets and pin cites; 18 million reporter citations with normalized keys
- A 133 GB Lucene index over the full text for boolean, phrase, and proximity search
- Twenty-five years of the United States Code, the Code of Federal Regulations, and the Federal Rules of Civil Procedure, Criminal Procedure, Evidence, and Appellate Procedure — stored the way lawyers cite them (Rule 12(b)(6), Rule 56, Rule 403), versioned so a 2019 cite still resolves to 2019 text, and cross-indexed in both directions: every case citing a section, every section cited by a case
- State statutes are being added continuously, jurisdiction by jurisdiction, on the same versioned, bidirectionally-indexed model
And it is current. Harvest is a job, not a quarterly ritual. Crawlers walk more than 200 individual court websites around the clock — supreme courts, intermediate appellate courts, and federal courts that publish their own slip opinions — plus public RSS and Atom feeds as an independent second signal, plus GovInfo as the government's own publication of federal law, plus quarterly bulk downloads as the historical backbone. Courts do not publish on a schedule: some in the morning, some after close of business, some in Friday batches. Continuous harvest is why yesterday's opinion is in the index today instead of in next quarter's dump.
Every new opinion is normalized, citation-scanned, LLM-completed, embedded, and pushed to every store — so the pieces stay one corpus rather than five stale copies.
One more thing worth stating, because it determines what you are allowed to build: none of this is licensed from a commercial research platform. No Westlaw feed, no Lexis feed, no scraped headnotes, no Shepard's or KeyCite extract. The inputs are public records and public government publications; the analysis and the citator graph are ours. That is why we can offer it to you as an API at all — and why there is no clause anywhere telling you that your product cannot compete with ours.
What building a legal research agent on it looks like
A research agent stops being a demo and starts being a product when the loop closes:
- Constrain, then rank. Send the user's question to
/searchwithsearchType: "auto", the right jurisdiction, and a date filter. Let the router run name, keyword, and semantic together. - Read the flags. Every hit already carries good-law status and a
matchExplanation. Your agent does not need a second call to know whether it is about to cite something that was overruled. - Pull what matters.
POST /cases/batchfor up to 50 at once, or/cases/:id/pdfwhen you need the court's own pagination. - Walk the graph.
/cases/:id/cited-byfor what came after,/cases/:id/good-lawfor treatments in detail. - Check your own output. Before the draft ever reaches a human, run it through
/citecheck/document— or, for a handful of cites, batch them through/citecheck/cite. If anything comes backname_mismatch, your model just hallucinated, and you caught it before your user did.
That last step is the one we would build first. A legal AI product's reputation is not lost when it gives a mediocre answer. It is lost the first time it cites a case that does not exist.
Auth, billing, and API stability
Auth. Authorization: Bearer <key> or X-API-Key: <key>. One gate handles authentication, rate limiting, and request-id assignment for every route — a new endpoint is structurally incapable of skipping it.
Errors. A typed taxonomy, not HTTP status roulette: missing_api_key, invalid_api_key, account_suspended, rate_limited, invalid_request (with a flat field-by-field list of what was wrong), service_unavailable, internal_error. Every one carries the requestId you can quote to support.
Billing. Per case returned on search. Per citation on cite-check, with errors excluded. Per page on documents. Your /usage endpoint shows calls, units, and cost by operation, plus the pricing actually in effect for your account — including any negotiated rate. Every call writes a ledger row, including zero-cost ones, because "we ran the work and chose not to bill" is exactly what an invoice question asks about.
Right now it is free. The API is free during the current rollout. Usage is still recorded, the published schedule is reserved rather than charged, and if that changes the discovery document and the docs will say so before it does.
Stability. The public shapes are deliberately narrower than our internal ones. Fusion scores, per-engine ranks, and match evidence exist to explain our ranking, and publishing them would freeze our implementation into your contract. What is published is additive-only: fields get added, never renamed out from under you.
Frequently asked questions
What is a caselaw API for legal AI?
A caselaw API lets your application search court opinions, retrieve full cases, walk citation relationships, and verify citations programmatically — without a Westlaw or Lexis desktop contract. LawDiver exposes the same retrieval and cite-check stack our own products use, over roughly 10 million U.S. opinions.
Does the API support boolean and semantic legal search?
Yes. You can run boolean keyword search with proximity connectors (/s, /p, w/n), semantic vector search, hybrid fusion, citation lookup, case-name lookup, or auto routing that plans engines from the query itself.
Is the LawDiver caselaw API free?
Yes during the current rollout. Usage is still recorded against the published schedule, but it is not charged. The unauthenticated discovery document at https://lawdiver.com/api/v1 shows endpoints and pricing before you create a key.
How is this different from an LLM cite checker?
An LLM can only estimate what a citation string looks like. LawDiver resolves citations against a held corpus with deterministic reporter-key lookup, then scores name, year, court, Bluebook form, and good-law status — including a name_mismatch verdict for the classic hallucinated-cite shape.
Do I need a commercial data license to build on it?
No. The corpus is built from public records and public government publications. There is no Westlaw or Lexis feed underneath, and no clause that forbids your product from competing with ours.
The wait is over
You should not have to choose between a search box that embarrasses you and a contract you cannot get. Legal AI has been bottlenecked on retrieval and verification for years, and it has been bottlenecked on purpose — the data has been the moat.
Here is the moat, as an API. Full boolean and semantic search with engine-level control. Case retrieval with the citation graph attached. And a cite checker that reads, resolves, and scores every citation in a document, with a verdict taxonomy honest enough to say "I cannot verify this" instead of guessing.
Go build the thing you have been unable to build.