---
title: "Coverage matrix by jurisdiction and corpusType"
method: GET
path: "/api/v1/us/statutes/coverage"
tags: ["US Statutes"]
---

# Coverage matrix by jurisdiction and corpusType

`GET /api/v1/us/statutes/coverage`

## Request

- Base URL: `https://api.vaquill.ai`
- URL: `https://api.vaquill.ai/api/v1/us/statutes/coverage`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`
- TypeScript: <https://skmtc.dev/vaquill/apis/vaquill-developer-api/docs/api/v1/us/statutes/coverage/get.ts> (a function with typed inputs; its response is checked against the schema)

Self-describing coverage matrix: a legend of every `corpusType` token (what it contains and whether it is federal or state-scoped) plus, for each jurisdiction, the ingested DOCUMENT counts per corpusType in `corpora` (one per section or document, not per retrieval passage; `totalPassages` is the passage count). Read a jurisdiction's `corpora` keys, then pass one as `corpusType` to `/us/statutes/search` (with `state` for state-scoped corpora). A corpusType absent from `corpora` is not held for that jurisdiction. A legend entry's `browsable` says whether `GET /us/statutes/divisions` can walk that corpus as a tree.

Congressional bill text (119th Congress) is held as `FEDERAL_BILL`: proposed text, never law, opt-in only and outside every total; `proposedCorpora` reports its count. Enacted federal text is under `SESSION_LAW` and `USC`.

**Territories.** Beyond the 50 states and DC, five territories are jurisdictions of their own, each with `kind: territory`: Puerto Rico (`pr`), Guam (`gu`), the U.S. Virgin Islands (`vi`), American Samoa (`as`) and the Northern Mariana Islands (`mp`). All five hold statutes, regulations and court rules. Constitutions (`STATE_CONSTITUTION`) are held for `pr`, `as` and `mp` and not for `gu` or `vi`. Attorney general opinions (`STATE_AG_OPINION`) are held for `pr` and DC only, and a register (`STATE_REGISTER`) for `mp`. Puerto Rico statutes are held in Spanish, as enacted, and resolve by their `L.P.R.A.` number where that number is printed on the section; the LexisNexis annotated edition (English translation, annotations, index) is not held.

This reports what we hold, not how recently it was refreshed. For the age of a source call `GET /boards` (free): `lastRetrievedAt` and `cadence` record when we last CHECKED, not when the law last changed. Where a publisher states its own currency, that rides on each section as `currentThrough`.

**Free.** Requires an API key and is rate-limited, but costs no credits.

State session laws (acts as enacted) are at `/us/session-laws`. Where we hold any for a jurisdiction, its `sessionLaws` block lists its sessions (`complete` or `partial`), how many laws we serve and withhold (`withheldCount`, each with a stated reason), the expected total and open gaps, and the `series`, `instrumentTypes` and approval-date span that exist (the values `GET /us/session-laws/list` accepts). A jurisdiction with none has no block. This is the one place session-law coverage is served, so check it before you list.

## Query parameters

- `state` 'federal' | 'al' | 'ak' | 'as' | 'az' | 'ar' | 'ca' | 'co' | 'ct' | 'de' | 'dc' | 'fl' | 'ga' | 'gu' | 'hi' | 'id' | 'il' | 'in' | 'ia' | 'ks' | 'ky' | 'la' | 'me' | 'md' | 'ma' | 'mi' | 'mn' | 'ms' | 'mo' | 'mt' | 'ne' | 'nv' | 'nh' | 'nj' | 'nm' | 'ny' | 'nc' | 'nd' | 'mp' | 'oh' | 'ok' | 'or' | 'pa' | 'pr' | 'ri' | 'sc' | 'sd' | 'tn' | 'tx' | 'ut' | 'vt' | 'vi' | 'va' | 'wa' | 'wv' | 'wi' | 'wy', nullable: Return only this jurisdiction: a 2-letter US state code (one of the 56 supported) or `federal`. Case-insensitive. Omit for every jurisdiction. The unfiltered matrix runs to about a megabyte, so pass this when you are asking about one place. `totalSections` and `stateCountWithData` stay corpus-wide.

## Response `200`

Coverage legend plus per-jurisdiction corpusType counts.

- UsStatutesCoverageEnvelope: What `GET /us/statutes/coverage` returns: the matrix under `data`. Declared because the route used to return a hand-built dict with no `response_model`, so its published schema was `{}`. Every field was discoverable only if the example happened to show it, and the MCP tool and generated clients built from the document got no types at all for the one endpoint that exists to be read before anything else.
  - `data` UsStatutesCoverageResponse, required: Response for `GET /us/statutes/coverage`. A self-describing matrix: a legend of every `corpusType` token plus, for each jurisdiction, the per-corpusType ingested-document counts. Use it to learn exactly what is queryable where before calling `/us/statutes/search`.
    - `corpusTypes` UsCorpusTypeInfo[], required: Legend of every corpusType token, its meaning, and its scope.
      - `token` string, required: The `corpusType` value to pass to `/us/statutes/search`.
      - `description` string, required: What this corpus contains.
      - `scope` 'federal' | 'state', required: `federal` corpora appear under the `federal` jurisdiction; `state` corpora are scoped per state (pair with the `state` filter).
      - `browsable` boolean: Whether `GET /us/statutes/divisions` can walk this corpus level by level (titles, chapters, parts, codes, articles, rule sets). When true, following every node and every `nextCursor` reaches every section the corpus holds; a level a jurisdiction does not record is not invented, so some codes list their sections directly beneath them. State court rules (`STATE_RULES`) are walked rule set first, then the containers each rule's record names inside its set. False for dated series such as the Federal Register and executive actions, and for corpora with no shared tree such as agency guidance. Every corpus is searchable either way; this only says whether you can NAVIGATE it instead of querying it.
      - `scopeNote` string, nullable: Always present. Set ONLY when we hold part of a corpus rather than all of it, and then it names both what is held and what is not. Null means no class-level exclusion applies. It is a STRUCTURED completeness claim, deliberately separate from `description` (prose a caller cannot act on). It says nothing about how recently the corpus was refreshed, a different fact: a filtered corpus can be, and `FEDERAL_REGISTER_NOTICE` is, refreshed weekly. `GET /boards` answers that one.
      - `sourceScopeNotes` object: Scope statements for INDIVIDUAL sources inside this token, keyed by the `source` value you can filter on. `scopeNote` is the right unit for a token that is one corpus; it is the wrong unit for `AGENCY_GUIDANCE`, which fans out to more than thirty unrelated sources, so a partial source declares its own coverage here rather than describing every sibling. Empty when every source under this token is held whole.
    - `jurisdictions` UsJurisdictionCoverage[], required: One row per jurisdiction (federal first, then states and territories), each carrying its per-corpusType counts in `corpora`.
      - `code` string, required: 2-letter state ISO code (lowercase) or `federal` for USC/CFR.
      - `name` string, required: Display name.
      - `kind` 'federal' | 'state' | 'territory', required: `federal` for USC/CFR, `state` for the 50 states, `territory` for non-state jurisdictions (DC, Puerto Rico).
      - `sectionCount` integer, required: Distinct sections held for this jurisdiction, summed across its `corpora`. 0 means not yet covered. One per provision or document, NOT per retrieval passage (see `totalPassages` for those). Repealed, transferred and reserved sections ARE counted: a legal research corpus serves them and a customer researching a historical question needs them. A SUPERSEDED prior version is not counted a second time when the section it supersedes is also served, because that is the same section twice -- but one with no current counterpart IS counted, since it is the only text we hold for that provision. Read `statusBreakdown` to see the split.
      - `hasData` boolean, required: True when section_count > 0.
      - `statusBreakdown` object: Per-corpusType `act_status` split over the same sections `corpora` counts, e.g. `{"REGULATION": {"inForce": 12151, "repealed": 10640, "transferred": 5426}}`. Published so a large section count can be read as maintained law plus retained history rather than as an undifferentiated total: Montana holds 28,217 regulation sections of which 12,151 are in force, and without this split that reads either as 28,217 current rules or as a coverage problem, and it is neither. ⚠️ `inForce` is what the ingester recorded, and it is NOT a complete census of current law: a zero means the status was never determined, never that the corpus is entirely inoperative. It is the status recorded for the section; the currency verdict is `goodLawStatus` on each section, which is `unknown` where a jurisdiction does not publish repeal information. The `unknown` key counts sections whose status is not stated. Absent when a jurisdiction has not been measured exactly.
      - `corpora` object: Per-corpusType ingested-DOCUMENT counts for this jurisdiction, keyed by the `corpusType` token (e.g. `{"STATE": 176778, "REGULATION": 51142}`). Only corpora with data are included. Pass a key as `corpusType` to `/us/statutes/search` to scope a query.
      - `sessionLaws` SessionLawJurisdictionCoverage: A jurisdiction's state session laws (acts as enacted), by session.
        - `sessions` SessionLawSessionCoverage[]: Oldest session first.
          - `code` string, required: Session code, for example `2025R`.
          - `label` string, nullable: The session's canonical label.
          - `type` string, nullable: `regular`, `special`, `extraordinary`, `fiscal`, `veto` or `unknown`.
          - `year` integer, nullable: The year the session convened, the year `code` starts with.
          - `status` 'complete' | 'partial', required: `complete` when every law the publisher lists for the session is accounted for. Anything less is `partial`: a law missing from a partial session is not evidence that it does not exist, and asking for one by id or citation answers `session_not_fully_collected`, free of charge, rather than a plain not found.
          - `servedCount` integer, required: Laws from this session we serve: every one we answer for by id, citation or list, whether or not we hold its text (`notHeldCount` of them have none). Laws whose text is withheld are not counted here, they are `withheldCount`. `servedCount + withheldCount` is `registryCount`, less any law still being verified.
          - `withheldCount` integer: Laws from this session we hold and list but whose text is withheld for a measured defect (`textStatus: withheld`). They are real laws: their records are served, their text is not.
          - `notHeldCount` integer: Of the laws counted in `servedCount`, how many have no text held (`textStatus: not_held` or `pending`). A subset of `servedCount`, not an addition to it: do not add it to `servedCount` or `withheldCount`.
          - `registryCount` integer: Every law of this session in our registry, whether or not its text is held: `servedCount + withheldCount`. Any difference is a law still being verified, which is neither.
          - `collectedCount` integer: Laws from this session whose text we have collected, served or withheld. Compare it with `denominator.value` to see how much of the session we hold.
          - `denominator` SessionLawDenominator: How many laws a session is supposed to hold, and where that number comes from.
            - `kind` 'stated_count' | 'complete_listing' | 'max_number' | 'feed_total' | 'our_recount' | 'registry_union' | 'none', required: Where the total comes from. `stated_count`: the publisher states how many measures the session enacted. `complete_listing`: the publisher's own complete list of the session's acts, which we counted. `max_number`: the highest chapter number the publisher printed. `feed_total`: the total a publisher feed reports. `our_recount`: we counted the publisher's pages ourselves. `registry_union`: the measures we know of from several sources. `none`: no total is available, so completeness cannot be judged.
            - `value` integer, nullable: The number of laws the session is expected to hold. Null when `kind` is `none`. Compare it with `registryCount` and `servedCount`.
            - `derivation` string, required: One plain sentence saying what `value` counts and where it comes from. Written for customers: it never contains our internal audit or collection notes.
          - `openGaps` integer: Laws the publisher lists for this session that we could not collect and have not yet. 0 on a `complete` session.
          - `numberingHoles` integer, nullable: Numbers inside the session's printed range that carry no law, which may never have been issued; null when not measured, and never counted in `openGaps`.
          - `denominatorStale` boolean, nullable: True when our registry holds more laws than `denominator.value`, so the figure counts a narrower unit or is out of date and cannot measure what is missing; null when not assessed.
          - `measuredAt` string, nullable: When this session's coverage was last measured, ISO 8601 UTC.
        - `sessionCount` integer, required: Sessions of this jurisdiction we hold session laws for.
        - `completeSessionCount` integer, required: How many of those sessions are `complete`.
        - `servedCount` integer, required: Laws served across every session listed.
        - `series` string[], nullable: The numbering series that exist among this jurisdiction's session laws: the values `series` accepts on `GET /us/session-laws/list`. `general` is the ordinary chapter sequence. Omitted when it cannot be read, which is not the same as no series existing.
        - `instrumentTypes` string[], nullable: The kinds of measure we hold for this jurisdiction: the values `instrumentType` accepts on `GET /us/session-laws/list`. Omitted when it cannot be read.
        - `earliestApprovedDate` string, date, nullable: The earliest approval date among this jurisdiction's session laws, ISO 8601: the start of what the approval-date filters on `GET /us/session-laws/list` can match. Omitted when no law prints an approval date or the span cannot be read.
        - `latestApprovedDate` string, date, nullable: The latest approval date among this jurisdiction's session laws, ISO 8601: the end of what the approval-date filters on `GET /us/session-laws/list` can match. Omitted when no law prints an approval date or the span cannot be read.
    - `totalSections` integer, required: Count of distinct sections (one per provision or document) across the corpus. This is the deduplicated legal-document total, not the raw index size; see `totalPassages`.
    - `totalPassages` integer: Total indexed retrieval passages across the corpus. Longer sections and documents are split into several passages for retrieval, so this runs well above `totalSections`. The Federal Register (long agency rules) accounts for over half.
    - `stateCountWithData` integer, required
    - `proposedCorpora` UsProposedCorpusCoverage[]: Opt-in corpora of PROPOSED text (Congressional bills), each with its own count. They are deliberately outside `totalSections`, `totalPassages`, `stateCountWithData` and every jurisdiction's `corpora`: a proposal is not law, and those figures count law. Reach one only with `corpusType=<token>`.
      - `corpusType` string, required: The `corpusType` token to pass to opt in.
      - `name` string, required: Human label.
      - `sectionCount` integer: Distinct documents held. Zero while the corpus is registered but not loaded.
      - `passageCount` integer: Indexed retrieval passages held for this corpus.
      - `held` boolean, required: True when `sectionCount` > 0. False means the token is registered and returns nothing yet.
      - `optInOnly` boolean: Always true: never part of an unscoped search, browse or total.
      - `note` string, required: What this corpus is, and is not, today.
    - `measuredAt` string, nullable: When these counts were last measured against the index, as the OLDEST per-jurisdiction measurement in this response. This is OUR measurement's age, not the publisher's currency: for what a section is current THROUGH, read `currentThrough` on the section, and for when a source was last checked, read `GET /boards`.\n\nIt exists because a jurisdiction whose measurement keeps failing is served from the last value we knew to be correct, which is the right trade (a stale count is accurate, a degraded one reports a real corpus as absent) and used to be indistinguishable from a fresh one. Null means nothing in this response has been successfully measured yet.
  - `meta` UsFreeCallMeta, required: `meta` on a free discovery endpoint.
    - `processingTimeMs` number, required: Server-side time to build the response, in milliseconds.
    - `creditsConsumed` number: Always 0: this endpoint is free.

## Other responses

- `401`: Missing, invalid or revoked API key.
- `403`: API key lacks `research:read` scope.
- `422`: `state` is not a supported jurisdiction. Same validation envelope as the POST routes: code `validation_error`, `errors[].loc` is `query.state`, and the message lists the allowed values.
- `429`: Rate limit exceeded.
- `500`: Internal error (`internal_error`, retryable). Any credits charged for the call are refunded; retry with backoff and quote `requestId` to support if it persists.

## Changes

- **2026-11-07** `340c0d24d0b6`: 37 info
  - added the non-success response with the status `500`
  - added the optional property `candidateCount` to the response with the `401` status
  - added the optional property `candidateCount` to the response with the `403` status
  - added the optional property `candidateCount` to the response with the `422` status
  - …33 more

[Operation history](https://skmtc.dev/vaquill/apis/vaquill-developer-api/changes/api/v1/us/statutes/coverage/get.md)

---

[API](https://skmtc.dev/vaquill/apis/vaquill-developer-api.md) - [All operations](https://skmtc.dev/vaquill/apis/vaquill-developer-api/llms.txt) - [OpenAPI document](https://skmtc.dev/vaquill/apis/vaquill-developer-api/revisions/340c0d24d0b6?raw)
