Legal Data Provenance: How to Tell Where a Statute Actually Came From

Short answer: you tell where a statute came from by asking the API to show you, per section, the publisher's own URL and the date it was pulled. "We cover all 50 states" is a claim nobody can check. "This section came from leg.state.xx.us on 2026-08-14, and the publisher says the code is current through the 2026 regular session" is a claim you can verify in a browser tab. The gap between those two sentences is the whole evaluation. This post gives you a five-question test you can run against any provider in an afternoon, and shows how Vaquill AI answers each one.

TL;DR

  • Coverage counts are unfalsifiable on their own. A provider can count sections it scraped from an aggregator, or counted twice, and the number looks the same from outside.
  • Provenance is five yes/no questions: source URL per result, government publisher behind that URL, retrieval timestamp, a currency statement in the publisher's own words, and declared gaps.
  • The fifth question is the one that separates real providers from marketing. A provider that never declares a gap either has none (impossible at this scale) or is not looking.
  • Gov-only sourcing forces gap declaration. If you refuse to fall back to a commercial aggregator, some jurisdictions have no usable text, and you have to say so out loud.
  • Vaquill AI declares six paused state statute corpora and six jurisdictions with no court rules, each with a named reason, in the API response and in this post.
  • The strongest provenance signal is a readable pipeline. Vaquill AI's ingestion code is open source at open-us-law, so the parsers themselves are auditable.

A five-step flow of provenance checks: a source URL per result, a government publisher behind it, a retrieval timestamp, the publisher's own currency statement, and declared gaps.

4-question check
Question 1 of 4

Which question is the hardest for a legal data provider to fake?

This is one post in our legal data infrastructure series.

For the machinery that produces the fields tested below, see From a State Website to an API Response: Every Layer a Legal Corpus Passes Through. For what happens after a source is verified, see Legal Data Freshness: What Refresh Cadence Actually Means, Source by Source.

Why coverage counts do not survive contact with an audit

A legal data vendor tells you it covers 50 states. You have no way to check that from the outside. You cannot count sections you cannot see, and you cannot tell a section pulled from the Nevada Legislature's own site from one pulled from a free aggregator that mirrored it in 2021.

Both look identical in a JSON response. Both say "Nev. Rev. Stat. 41.032." One is current law from the publisher of record. The other might be four sessions behind.

So coverage size is the wrong first question. The first question is provenance: for this specific result, which publisher produced the text, and when did you fetch it? Everything else about a legal corpus is downstream of that answer.

The five-question provenance test

Run these against any provider's live API. You need a key, a terminal, and about two hours.

#QuestionPass looks likeFail looks like
1Does every result carry a source URL?A URL field on every hit, populated 100% of the timeThe field exists but is null on some results, or only a "citation" string
2Does that URL resolve to a government publisher?A .gov, a state legislature host, a judiciary hostAn aggregator, a law firm blog, the vendor's own CDN
3Does the response tell you when it was retrieved?A timestamp per source, exposed in a free endpointNothing, or a single site-wide "updated daily" banner
4Does it say what the corpus is current through?A currency statement in the publisher's own wordsA rebuild date presented as a currency date
5Does the provider declare its gaps?A machine-readable list of paused or missing sources with reasonsSilence, or "full coverage"

Running the test, step by step

Step 1: pull one result and look for a URL

Search for a section you can independently verify.

curl -s -X POST https://api.vaquill.ai/api/v1/us/statutes/search \
  -H "Authorization: Bearer $VAQUILL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"deprivation of rights under color of law","corpusType":"USC","limit":3}'

Each result should carry a source URL pointing at the publisher's own copy of that section, and the source format reference says which mirror each corpus keeps. Open it. You should land on the government page for the same citation, not a search page, not a paywall, not a 404.

Do this ten times across different corpora. A source URL that is present on federal results and null on state results is a real finding, and it is the most common failure mode at scale. Nothing in a response's shape makes a null field visible. You have to count.

Run it on every corpus you actually plan to depend on, ours included, and run it per corpus rather than once. Source-URL coverage is a property of an individual corpus, not of a vendor, because each one was built against a different publisher with a different idea of what a stable URL is. A corpus that populates the column for statutes tells you nothing about the same vendor's regulations.

Sample a few hundred sections per corpus, count the nulls, and treat the result as the answer for that corpus only.

Step 2: classify the host, not the string

Write down the hostname from every source URL you collected. Sort them. Then ask, per host, whether the entity behind it is the government publisher of that law.

This is a boring exercise and it is the entire test. An aggregator host in that list means the vendor is willing to serve you a copy, and a copy has no publication date you can rely on.

Loading diagram...

Step 3: ask for retrieval times

Vaquill AI exposes this on a free endpoint. GET /boards lists every watchable source and answers question 3 with three fields read together: lastRetrievedAt, an ISO-8601 UTC timestamp of the last refresh run for that source that finished cleanly, where a run that found nothing new still counts; retrievalStatus, the board's own verdict on that run; and cadence, how often we poll the source.

curl -s https://api.vaquill.ai/api/v1/boards \
  -H "Authorization: Bearer $VAQUILL_API_KEY" | jq '.items[] | {board: .label, cadence, retrievalStatus, lastRetrievedAt}'

The pairing matters. cadence alone tells you when we would look. Anything other than current in retrievalStatus means silence from that source is uninformative rather than evidence that nothing changed. A provider that gives you a cadence with no status is giving you half the fact.

The full status vocabulary, what each cadence value commits us to, and a cron recipe for watching both live in the companion post on legal data freshness and refresh cadence.

Step 4: read the currency statement, not the build date

GET /us/statutes/coverage is free and unauthenticated in the sense that it costs zero credits, and the coverage endpoint reference lists its fields. It returns per-jurisdiction section counts, a measuredAt timestamp, and a currency block that carries what each corpus is current through in the publisher's own words.

That phrasing is deliberate. The United States Code corpus is the 2024 edition, current through 2025-01-06. That is not our build date. It is the edition the Office of the Law Revision Counsel published, and it is what a court will treat as the reference point.

The status and currency fields are documented one by one. Quoting the publisher rather than paraphrasing it is what keeps the field honest. A code that is 20 months behind reads as 20 months behind in the response.

Step 5: ask what is missing

This is the question that separates the two kinds of vendor. Ask directly: which jurisdictions do you not have, and why?

Vaquill AI answers this in the API. The freshness array on GET /statutes/coverage declares every deliberately paused corpus with its reason, as data, in the same response that reports the counts.

The sourcing policy behind all of this

The sourcing rule is the government publisher's own copy. A commercial aggregator is never used, not as a source and not as a fallback, not even temporarily, not even for one state where it would be easy.

That rule sounds like a nice-to-have until you see what it costs. Where a state's only consolidated text sits behind a commercial licensee, the corpus declares the gap instead of filling it. Filling it from an aggregator would improve the coverage number and destroy the thing the number is supposed to measure.

It also means that when a publisher's robots.txt prohibits automated access, we stop. Not throttle, not work around it, stop. The corpus goes to paused and the API says why.

The declared gaps, in full

Here is what the policy produces. These are real holes in a corpus of 4,150,839 distinct sections across 53 jurisdictions, and they are published rather than hidden.

Paused corpora, and why the state is declared

Paused means complete and officially sourced, but not re-pulling. The text you get is real and came from the publisher. It is not being refreshed, and the API tells you so.

Reason a corpus pausesWhat the freshness array says
The publisher's robots.txt opts automated access outNamed as the reason, per corpus
The publisher blocks automated retrievalNamed as the reason, per corpus
A correction is being applied to the stored buildNamed as the reason, per corpus

Every paused corpus is listed by jurisdiction and corpus type in that array, in the response body, with the reason attached. Read it from the API rather than from a status page.

Six jurisdictions have no court rules, each for a different reason

JurisdictionWhy there is no court-rules corpus
ArkansasNo government-published consolidated text. Only the amendment stream is on the judiciary's site; consolidated text is published only by a commercial licensee
VermontSame shape as Arkansas: amendment stream only, consolidated text behind a commercial licensee
ColoradoOnly rule-change orders are published. The last government compilation is 2023, and ingesting it would serve superseded procedure as current law
OklahomaRules are codified into the statute book (Okla. Stat. tit. 12) and are already served under corpusType=STATE
South DakotaRules are codified into the statute book (SDCL tits. 15, 19, 23A) and are already served under corpusType=STATE
MissouriThe judiciary's published policy does not permit automated access, and we honor it

Notice that these six are not one problem. Two are licensing, one is a currency judgment, two are "it is already there under a different corpus type," and one is a policy we chose to respect. A vendor that lumps its gaps into one bucket has not actually looked at them.

Colorado is the case worth sitting with. A 2023 government compilation of its court rules exists, and ingesting it would move a court-rules coverage count from 46 jurisdictions to 47. It would also mean a litigator's tool returning three-year-old procedure as current. The count is not worth the defect, so the compilation stays out.

Reading the pipeline itself

The strongest provenance signal a vendor can offer is not a field in a response. It is letting you read the code that produced the field.

Vaquill AI publishes the collection layer at open-us-law under a permissive license: the bulk-source parsers, the scrapers, and the JSONL schema they emit. If you want to know how a Nevada section became a row, you can read the parser that made it.

This is the answer to a question no amount of API-surface inspection can settle. A source URL field can be populated by anything. A parser you can read tells you what actually populated it. For what that code does stage by stage, see every layer a legal corpus passes through.

What provenance does not buy you

Being honest about the limits is part of the same discipline.

A perfectly sourced section is still only the current section. One text per citation is all the corpus keeps, so as_of=2019-03-01 is not a query you can send. If you need the exact words of a statute as they stood on a specific past date for a litigation argument, this is not the tool for that job, and no amount of provenance metadata changes it.

What does exist is adjacent and useful: amendment history and a lastAmendedYear per section, a yearFrom/yearTo currency filter that keys on the last amendment year the publisher credits, change events captured on each refresh, and per-section diffs on watched boards. That combination answers "when did this last move and what moved" without pretending to answer "what did it say in 2019." Which of the four fits which question is worked out in Amendment History and Point-in-Time Law: What a Legal API Can and Cannot Tell You.

A short scorecard you can copy

Score any provider out of 5. Anything below 4 and you are buying a coverage number rather than a corpus.

TestVaquill AIWhat to check elsewhere
Source URL on every resultYes, the publisher's own copySample 50 results across corpora, count nulls
Government publisher onlyYes, no aggregator fallback, everSort hostnames from your sample
Retrieval timestamp exposedYes, lastRetrievedAt and retrievalStatus on free GET /boardsLook for a per-source timestamp, not a site banner
Currency in publisher's wordsYes, currency block on free GET /us/statutes/coverageAsk whether the date is theirs or the publisher's
Gaps declaredYes, freshness array with reasons; six paused statute corpora, six court-rule gapsAsk for the list. Silence is the answer

FAQ

Provenance is the documented chain from a piece of text in an API response back to the government body that published it. For a statute, that means the publisher's own URL, the date the text was fetched, and the publisher's own statement of what the code is current through. Without those three, a citation string is an assertion rather than a record.

An aggregator is a copy, and a copy carries the aggregator's update schedule rather than the legislature's. You inherit a lag you cannot measure and cannot fix. It also introduces a licensing question, because a commercial aggregator's compilation is often the thing being licensed, not the underlying public-domain law.

Pull 50 results spread across the corpora you care about, extract the source URL from each, and check two things: that the field is never null, and that every hostname belongs to a government publisher. Then open ten of those URLs and compare the text on the page to the text in the response. That afternoon of work tells you more than any coverage table.

In Vaquill AI's API, paused means the corpus is complete and was sourced from the official publisher, but is no longer being re-pulled. The text is real and dated; it is just not moving. The freshness array on GET /us/statutes/coverage names each paused corpus and the reason, so you can decide whether that jurisdiction is safe for your use case.

Does an open-source ingestion pipeline actually prove anything?

It proves what the code does, which is the one thing an API response cannot show you. You can read how a source is fetched, how the text is parsed, and what schema it lands in. It does not prove that the deployed system is running that exact code, so treat it as a strong signal rather than an audit, and pair it with the source-URL sampling above.

Can I query US statutes as they existed on a past date?

Not through this API. Only the current text of each citation is stored, and the request has no as_of parameter to accept a past date. What is available instead is amendment history per section, a lastAmendedYear field, a yearFrom/yearTo filter on the publisher's credited amendment year, and per-section diffs on watched boards, which together tell you when a section last moved.

Why do some states have no court rules in the corpus?

Six jurisdictions have no separate court-rules corpus, for four different reasons. Arkansas and Vermont publish only the amendment stream, with consolidated text behind a commercial licensee. Colorado's last government compilation is from 2023 and would serve superseded procedure. Oklahoma and South Dakota codify their rules into the statute book, and Missouri's judiciary does not permit automated access.

What is the difference between a refresh date and a currency date?

A refresh date is when the vendor last fetched the source. A currency date is what the publisher says the law is current through, which can be much older. The US Code corpus is the 2024 edition, current through 2025-01-06, no matter how recently we checked for a newer one. Design against the currency date, and monitor the refresh date.

The most complete US primary law API.
Every US statute, regulation, constitution, and executive order through one REST and MCP API. 4M+ sections, section-level citations, and links to the official source. Plus a free open dataset.
18 min read

New legal AI guides, weekly.

Priyansh Khodiyar

Priyansh Khodiyar

Co-Founder & CTO

Priyansh leads engineering and AI at Vaquill, from the matter workbench to drafting, document comparison, document matrix, and citation-verified research.