---
title: "Count the sections in a scope"
method: POST
path: "/api/v1/us/statutes/count"
tags: ["US Statutes"]
---

# Count the sections in a scope

`POST /api/v1/us/statutes/count`

## Request

- Base URL: `https://api.vaquill.ai`
- URL: `https://api.vaquill.ai/api/v1/us/statutes/count`
- 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/count/post.ts> (a function with typed inputs; its response is checked against the schema)

How many sections sit in a jurisdiction, corpus, code, title, chapter, part,
article or federal rule set. The scoping filters (`code`, `article`, `chapter`,
`part`) take the same values and pairing rules as on `/us/statutes/search`.

**Cost**: 1 credit. A scope that matches nothing is refunded, because an empty
answer here is usually a wrong filter rather than a finding.

Use it to size a job before you run it. Walking a container with
`/us/statutes/divisions` and hydrating what you find is cheap per call and adds
up across a whole corpus, so this is the call that tells you what you are about
to spend before you spend it.

**A natural-language `query` is refused, on purpose.** Search ranks it over a
bounded window, so "how many sections match this question" has no answer beyond
the size of that window. Without a `query` this counts a SCOPE, which is exact.
Pair the two: count the scope here, enumerate it with `/us/statutes/divisions`,
then rank within it using `/us/statutes/search`.

**Boolean counts.** With `matchType: "boolean"` and a terms-and-connectors
`query` (the syntax of `/us/statutes/search`), this counts the sections that
satisfy the expression within the scope, the same figure a Boolean search
reports as `totalMatches`. `isExact: false` marks an upper bound: the expression
uses an operator the index cannot judge exactly (phrases, `/s`, `/p`, proximity,
`atleastN`, wildcards inside proximity) or a filter it does not apply (anything
beyond `corpusType`, `state`, `actStatus` and `excludeRepealed`). Same price; a
malformed expression is a 422 and is not charged.

The figure counts SECTIONS. Long sections are stored as several passages and are
counted once.

**What an unscoped count leaves out.** With no `corpusType`, past editions
(annual CFR printings) and proposals (bills) are not counted, exactly as in
`/us/statutes/search` and `/us/statutes/coverage`; the echo lists them under
`excludedCategories`. Name one in `corpusType` to count it.

**Agreement with `/us/statutes/divisions`.** The browse counts distinct sections, so
a section re-ingested additively (a superseded and a current copy under one id) is
one section there. A scope of up to 4,000 sections is counted the same way
(`scope.countBasis` is `distinctActIds`), so the children's `sectionCount` values sum
to this figure. A larger scope reports `countBasis: "sectionPoints"` with
`scope.supersededSectionPoints`, the most such copies could overstate the figure by.

## Headers

- `Idempotency-Key` string, nullable: Optional. 16 to 255 visible ASCII characters (a UUIDv4 works). Repeating the same request with the same key replays the original 2xx response for 24 hours without charging again. The same key on a different request is rejected. With the account's `cacheQueryDerivedData` retention setting off, no body is stored and a retry answers 409 `idempotency_replay_unavailable`, still without a second charge.

## Request body

- StatuteCountRequest: Section count for a scope, or for a Boolean expression within it. See `POST /us/statutes/count`. A natural-language `query` is still refused: ranking runs over a bounded window, so "how many sections match this question" has no honest answer beyond the window size. A Boolean expression is different: membership is a yes or no per section, and the candidate index counts it (`matchType: "boolean"`, the same expression `/search` would page through).
  - `query` string, nullable: A Boolean expression to count, with `matchType: "boolean"` (same syntax as `/us/statutes/search`). Omit to count the whole scope. A natural-language query cannot be counted: rank it with `/us/statutes/search`.
  - `matchType` 'boolean', nullable: `"boolean"` to count the sections satisfying `query`. Required with `query`.
  - `corpusType` union: Corpus to count, single or list. Omit to count every corpus.
    - 'USC' | 'CFR' | 'STATE' | 'CONSTITUTION' | 'FEDERAL_RULES' | 'FEDERAL_LOCAL_RULES' | 'STATE_CONSTITUTION' | 'STATE_RULES' | 'EXECUTIVE_ACTION' | 'REGULATION' | 'FEDERAL_REGISTER' | 'FEDERAL_REGISTER_NOTICE' | 'AGENCY_GUIDANCE' | 'SENTENCING_GUIDELINES' | 'US_TAX_TREATY' | 'US_TREATY' | 'STATE_AGENCY_GUIDANCE' | 'STATE_AG_OPINION' | 'STATE_REGISTER' | 'SESSION_LAW' | 'STATUTE_COMPILATION' | 'AGENCY_ADJUDICATION' | 'CFR_ANNUAL' | 'USC_ANNUAL' | 'FEDERAL_BILL' | 'FEDERAL_RULES_ANNUAL' | 'FEDERAL_RULES_PROPOSED': A public `corpusType` token.
    - CorpusType[]
  - `state` union: Two-letter jurisdiction code or `federal`, single or list.
    - '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'
    - string[]
  - `code` union: State code identifier, e.g. `tx_26`. With `corpusType=FEDERAL_RULES`, a rule set instead (`frcp`, `uscapp_t28a_fre`). Same values and checks as `code` on `/search`.
    - string
    - string[]
  - `article` union: Article label (`Amendment XIV`) on CONSTITUTION / STATE_CONSTITUTION, or article number (`2-A`) on a STATE / REGULATION code divided by article. Same values and pairing rules as `article` on `/search`.
    - string
    - string[]
  - `titleNumber` integer, nullable: USC or CFR title number.
  - `chapter` union: Chapter identifier. Pair with `titleNumber` or `code`.
    - string
    - string[]
  - `part` union: CFR part identifier. Pair with `titleNumber`.
    - string
    - string[]
  - `actStatus` union: Count only sections carrying this status.
    - 'abolished' | 'deleted' | 'expired' | 'in_force' | 'inactive' | 'non_precedential' | 'not_funded' | 'not_yet_effective' | 'omitted' | 'proposed' | 'recodified' | 'recompiled' | 'rejected' | 'relocated' | 'removed' | 'renumbered' | 'repealed' | 'rescinded' | 'reserved' | 'revoked' | 'superseded' | 'terminated' | 'transferred' | 'unconstitutional' | 'vacant' | 'vacated' | 'vetoed' | 'withdrawn'
    - string[]
  - `excludeRepealed` boolean: Exclude sections whose status is affirmatively dead. A section with no recorded status is KEPT, because a missing status is not evidence of repeal. The US Code is served from a stored annual edition, so a section repealed after it closed is counted here; see the same field on `/search` for the measurement.

## Response `200`

The number of sections in scope, and the scope that produced it.

- StatuteCountResponse: Response for `POST /us/statutes/count`.
  - `count` integer: Sections in scope. This is a SECTION count, not a passage count: long sections are stored as several passages and are counted once.
  - `isExact` boolean: True when the figure is an exact count. Always true for a scope. For a `matchType: "boolean"` count, false means `count` is an UPPER BOUND: the expression uses an operator the index cannot judge exactly (phrases, `/s`, `/p`, proximity, `atleastN`, wildcards inside proximity) or a filter it does not apply (anything beyond `corpusType`, `state`, `actStatus` and `excludeRepealed`). The same expression on `/us/statutes/search` reports a `totalMatches` that is never larger: when `isExact` is false the search judges every candidate over the section's full text (phrases, proximity, `/s`, `/p`) and drops the ones the index could not rule out, so the count is the bound and `totalMatches` is the answer. They are equal when `isExact` is true.
  - `parsedQuery` string, nullable: Present only for a `matchType: "boolean"` count: the expression as it was read.
  - `scope` object: The filters that produced this figure, echoed back. A count with no scope attached is not reproducible, and an ignored filter would otherwise be invisible.
  - `processingTimeMs` number: Server-side time for this request in milliseconds.
  - `creditsConsumed` number: Credits actually charged for this call.

## Other responses

- `401`: Missing, invalid or revoked API key.
- `402`: Insufficient credits (`insufficient_credits`, never retry). `creditsRequired` and `creditsAvailable` say how short you are when known; top up, then repeat the call.
- `409`: Idempotency conflict. `idempotency_in_progress`: the original request with this key is still running (retry after `Retry-After`). `idempotency_replay_unavailable`: it completed but its response was too large to replay; nothing is charged again, so check the credit balance instead of retrying.
- `422`: Unknown filter value or unknown field. `idempotency_key_reused`: the `Idempotency-Key` was already used with a different request.
- `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`: 46 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 `402` status
  - added the optional property `candidateCount` to the response with the `409` status
  - …42 more

[Operation history](https://skmtc.dev/vaquill/apis/vaquill-developer-api/changes/api/v1/us/statutes/count/post.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)
