Skip to main content
A few habits make Vaquill AI integrations faster, cheaper, and more accurate. Follow these when you move from a prototype to production.

Scope every query

Pass corpusType (and state for state-scoped corpora) on POST /us/statutes/search. Scoping does two things: it sharpens relevance by removing off-target jurisdictions, and it makes your pages more predictable. An unscoped search ranks across the whole corpus, so a state-specific answer can be crowded out by federal or other-state matches.
You can scope tighter still. code (state, e.g. tx_pe) and titleNumber (USC/CFR) narrow a search to one code or title. Get a state’s code values from GET /us/statutes/divisions?corpusType=STATE&state=XX. To go one level deeper, chapter (USC/state) and part (CFR) confine a search to a single subtree. These are the search-side of the parent object on every result: take a hit’s parent and pass it straight back to search that section’s neighbors. chapter/part must be paired with titleNumber or code (which parent always carries), since a chapter number alone repeats across every title.

Choose the right matchType

matchType is the only exact-match control in the API, and it is what you reach for when hybrid ranking is too loose. any ranks on intent, so a query can rank a section that shares no wording with it. That is what you want for “how long does a landlord have to return a deposit”, and wrong for “material adverse effect”, where a section that merely discusses the idea is noise. all and phrase trade recall for precision. Both can return nothing, and an empty result under them is a real answer: the corpus contains no section with those terms, so fall back to any rather than assuming a coverage gap.
To pull up one specific section, pass its citation as the query (for example 42 U.S.C. § 1983) and leave matchType at any. It resolves to that section at rank 1. GET /us/statutes/resolve does the same job for 2 credits instead of 4 when you already hold a well-formed citation.

Control what a search returns

  • excerptChars: how much matching text each result carries (default 500, up to 4000). The excerpt is windowed around the match and can begin mid-section, dropping a leading subsection marker, so it is a ranking preview and not safe to quote.
  • includeBody: attaches each hit’s full text on body in the same call. It bills 6 credits per row that returns text on top of the 4-credit search, so limit: 50 with it set is 304 credits. Use it with a small limit, and read creditsConsumed.
For text you intend to quote, use body or GET /us/statutes/section/{actId}/body, never a raised excerptChars. Each result also carries a parent object: the /us/statutes/divisions query that lists the section’s siblings, so you can walk up the hierarchy from any hit. Section responses also include amendment provenance (sourceCredit, amendmentYears, lastAmendedYear, publicLaws, federalRegisterCitations). Two endpoints answer everything about what is queryable.
  • GET /us/statutes/coverage is the corpus matrix. Read a jurisdiction’s corpora keys and pass one back as corpusType. This avoids guessing a token that has no data for that state and wasting a call on an empty result.
  • GET /us/statutes/divisions is the hierarchy. Pass corpusType=STATE&state=XX to list a state’s individual statutory codes (Penal, Civil, and so on) and their code values, or drill in with titleNumber, code, chapter and part.

Cache coverage

Coverage grows weekly, not hourly. Cache /us/statutes/coverage and /us/statutes/divisions for hours or a day rather than calling them on every request. They still count against your rate limits.

Store the actId values you care about

The actId (for example USC_T42_C21_S1983) is the stable handle for a section. Once a search surfaces a section your product depends on, store its actId and go straight to GET /us/statutes/section/{actId} or .../body on later runs. That skips the search entirely.

Retry on 429, handle 402

  • On 429, respect the Retry-After header and use exponential backoff. See Rate limits.
  • On 402, stop, surface a clear message, resolve it in your account dashboard, then retry.
  • Both are expected in production. Build for them rather than treating them as fatal.

Treat relevanceScore as a within-response rank

relevanceScore (0 to 1) orders results within a single response. It is a relative rank, not a calibrated confidence score. Do not compare scores across different queries and do not use a fixed threshold (for example “drop anything below 0.7”) to decide what to keep. To narrow results, tighten query, corpusType, and state instead. Browse is ordered differently. GET /us/statutes/divisions returns divisions in statutory (natural) order, the way a person reads a code, not by relevance: 9 sorts before 10, and 240.9 before 240.10. Reach for search when you want the most on-point section, and for browse when you want the structure in order. Each result carries source links (htmlUrl, pdfUrl, xmlUrl, textUrl, docxUrl, stateHtmlUrl, govInfoHtmlUrl, govInfoPdfUrl, externalUrl; any may be null). For user-facing deep links, prefer the official government link (state legislature or govinfo.gov) so readers land on authoritative text. This keeps your product grounded and verifiable.

Pagination

Page predictably with limit, offset, and hasMore.

Coverage

See the full jurisdiction and corpus matrix.
Last modified on September 6, 2026