1
Size the job
Before you walk anything, ask how big it is.
POST /us/statutes/count takes the same scoping filters as search, runs no ranking, and returns an exact section count for one credit.
A scope that matches nothing is refunded.It takes no query on purpose: ranking runs over a bounded window, so “how many sections match this query” has no answer beyond the size of that window.
Counting a scope is exact, and it is the number that tells you whether a jurisdiction is a thousand sections or a hundred thousand before you spend anything walking it.2
Enumerate the spine
Walk Store the
GET /us/statutes/divisions for each jurisdiction and each corpus you care about.
It browses one level at a time, and the leaf level returns every section in a container with its actId.actId, citation, title and hierarchy path for every leaf.
This set is complete by construction, and no ranking decision touches it.3
Narrow to your subject
Now bring in search, scoped.
Run one query per concept, filtered to one jurisdiction and one corpus type, at the largest page size.Page to the end of the reachable set, then repeat for the next concept and union the
actId values.
Intersect that union against the spine from step 2.Two reasons this beats one broad query:- Filters are applied before retrieval, so each scoped query gets a full-depth pool within its slice. Scoping buys recall rather than spending it.
- One query per concept gives you independent pools.
defibrillator OR cardiac arrestis read as a single string, including the wordOR, and dilutes both concepts.
4
Hydrate what survives
Fetch in batches of 50 with Full text is the expensive half, so decide deliberately which sections get it: metadata first for the whole candidate set, then a second pass with
POST /us/statutes/sections.
Add includeBody when you want the text in the same call, instead of one /section/{actId}/body request per section.includeBody for the ones that survive your filter.
Rows whose text cannot be resolved come back with body: null and are not charged for it, so read creditsConsumed on each response rather than computing cost from row counts.5
Subscribe, then re-hydrate
Create a board watch for each
(corpusType, state) pair in scope, then poll GET /watches/{id}/changes with sinceId paging on your own cadence.
Re-fetch only the actId values that appear.A watch returns the source’s whole captured history rather than only what postdates your subscription, it is safe to poll, and watch management and polling cost no credits.Use changedSince on search as a second trigger inside the subject area itself, for the narrower question of what moved among the sections you already track.See Law change alerts.Keeping the spine honest
Re-run the enumeration in step 2 on a slower cadence than your change polling, quarterly rather than daily. It catches structural change that a per-section watch does not describe well: a chapter that gained sections, a code that was reorganised, a part that was recodified. Reconcile the new enumeration against the stored one and treat the three cases separately:
That last row is the one to handle carefully.
An
actId changes when a section is renumbered, so its absence is not evidence that the law is gone.
Re-resolve by citation through GET /us/statutes/resolve before you retire a record.
See Section identifiers.
Related
Browse the hierarchy
The divisions endpoint in detail.
How search works
Why search narrows rather than enumerates.
Compliance mapping
Mapping obligations onto the corpus you have built.
Coverage monitoring
Watching a jurisdiction for change.

