US Statutes

Get statute full text

Get the full text of a statute section in HTML and plain text.

Cost: 6 credits. You are only charged when text is returned: not-found (404), failed fetches, sections whose text is not yet ingested (available: false) and sections the publisher prints as images (bodyUnavailable: true) are all refunded.

Works across USC, CFR, and state corpora. The text preserves formatting, cross-references, and paragraph numbering as published in the official source.

Response: available: true with html + plain, or available: false with a note and creditsConsumed: 0 when the full text is not yet ingested (metadata is still available from /us/statutes/section/{actId}).

A section with no text to return. Some sections (appendices, forms and maps) are printed by the publisher as images, so there is nothing to extract. They answer available: false, plain and html null, bodyUnavailable: true, bodyUnavailableReason: "image_only_source", a note and creditsConsumed: 0. Both fields are omitted on every other section. This is a final answer, not a failure to retry: the section exists and its metadata is complete. Where we hold an official link for it, sourceUrl carries it; it is null where we may not republish the publisher's link. Search rows, includeBody and the batch /sections route carry the same two fields, with body null and no body charge for that row.

sourceUrl is where the government published this text: cite and verify against that, not against source, which names our storage backend. It is null when we hold no official link for the section; only government links are served.

Tables and figures (markdown / tables / figures)

Where a section has a structured rendering, source is r2_render and the body keeps what a flat text extraction loses: tables as real tables and images at the position the publisher prints them.

  • html -- <table> elements with <caption>, colspan and rowspan, and <figure> / <img> elements whose images are hosted on statutes-us.vaquill.ai
  • markdown -- GitHub-flavoured Markdown, tables as pipe tables and figures as ![alt](url)
  • plain -- tables as one tab-separated line per row, figures as [Figure N: caption] placeholders
  • tables / figures -- what the body contains, in document order. Each figure carries its hosted url and its offset into markdown and plain, so you can place images in your own layout. A figure we could not fetch is listed with status: "unavailable" and keeps its caption in the text.
  • hasTables / hasFigures -- quick flags

A section in a covered corpus that has no table and no figure returns tables: [], figures: [] and both flags false, with its text in html and plain as before. Where a corpus has no structured rendering yet, those fields are null, meaning "not known", not "none": a table may still be present in html. markdown is returned only for format=all or format=markdown: the default format=both leaves it out, because it is a third full copy of the text. format=markdown returns only markdown, and falls back to plain with a note when the section has no structured rendering. The price is the same whichever format you ask for.

Telling the law from the apparatus (content / sourceCredit / notes)

plain and html are the WHOLE body as the publisher prints it: the operative text, then the source credit, then the notes apparatus (historical and revision notes, committee reports, editorial notes, amendments, effective-date notes).

For United States Code sections that body is mostly not the law: measured 2026-09-02, the operative text is a median 46% of it across USC, and as little as 3.4% on 17 U.S.C. § 107.

So the granule is split into three additional fields, using the field delimiters GPO publishes in the source:

  • content -- the operative text, and nothing else
  • sourceCredit -- the credit line, e.g. (Pub. L. 94-553, ...)
  • notes -- the apparatus, kept because it is the legislative history

Use content if you are feeding sections to a model: the full body invites it to quote a 1992 amendment note as the law in force.

Two format values act on the split, and the difference between them is how many bytes cross the wire, not what the law says:

  • format=content drops plain/html and returns all three split fields. The apparatus is still on the response, because for a legislative-history or effective-date question it IS the answer.
  • format=operative drops notes as well, returning content + sourceCredit and nothing else. Measured on 17 U.S.C. § 107: 95,217 bytes at both, 61,003 at plain, 30,545 at content, 1,564 at operative. Same 6 credits either way -- the fetch is identical, so this buys bandwidth and prompt budget, not a discount.

Reach for operative when you are putting the law in front of a model or a reader and the notes are noise. Reach for content when you may need to read the apparatus but want to keep it clearly separated from the law.

⚠️ USC only. CFR and the state corpora carry no equivalent structure in their sources, so all three fields are null there and plain remains the whole body. Null means "we cannot split this reliably", never "this section is empty". Both content and operative fall back to serving plain with an explanatory note on a corpus that cannot be split, rather than returning a response that claims to carry the text and does not.

Pass structured=true to also get markdown (the body as nested Markdown lists) and subsections (a tree you can address by pincite, e.g. (b)(2), each node carrying its pincite path and full pinpoint citation). Same cost.

One subsection (pinpoint)

Pass pinpoint=(c)(1) to get that unit in the pinpoint field, alongside the whole body, for the same price. Write the pinpoint as parenthesised labels, outermost first, without the section number: (c), (c)(1), (d-1), (f)(1.5). A label that contains a hyphen or a dot is one label, so (f)(1.5) is the path ["f", "1.5"]. Anything else is a 422 and is not charged.

pinpoint carries the unit's own text (text), the unit with everything beneath it as printed (fullText), each ancestor's own text (leadIn, so (c)(1) can be read as the sentence it completes), the units directly beneath it (children), the labels either side of it (siblings) and its character range in plain (charStart, charEnd). Read matched first. A pinpoint the section does not contain is matched: false with a reason and, in available, the labels that do exist at the level where the lookup stopped; matchLevel: ancestor means only the leading part of your pinpoint exists and the block describes the deepest unit that does (unmatched is the rest). A section whose outline we could not recover answers reason: no_structure.

structure says where the outline came from: a stored artifact that was checked against the exact text returned here, or request_time parsing, and its quality. structured and pinpoint are independent and can be combined: structured returns the whole tree in subsections, pinpoint returns one unit in pinpoint. When a stored outline exists both come from it. pinpoint cannot be combined with asOf (the historical text is plain and carries no outline): that is a 422.

Point-in-time (asOf)

Pass asOf=YYYY-MM-DD to get the text as it stood on that date instead of today's. Same cost.

One parameter, two engines, and asOf.engine says which one answered. Read it before anything else in the block, because the two make different promises and isBounded does not mean the same thing under each.

engine: "stored_edition" -- we hold the publisher's own printed editions for this corpus and return one verbatim. CFR annual editions, the US Code, the Copyright Compendium and OFAC FAQs. Here isBounded: true means your date fell inside an edition we actually hold, which is a verified published printing.

Coverage under this engine is ENUMERATED, not continuous, and outside the CFR annual editions it is currently sparse. A date in a gap between two held editions returns source: "unavailable", isBounded: false, no text, and an outOfCoverageReason naming what we do hold. It is never answered from a neighbouring edition, because the text may have changed in the gap. For the US Code this is the common case today: most historical dates fall between the editions we hold and are reported out of coverage, with outOfCoverageReason naming the editions that are available. Do not read the presence of this parameter as full US Code point-in-time coverage.

engine: "observed_change" -- every other corpus. A reconstruction, not an archive. The corpus holds one current text per citation; an earlier one is rebuilt from the before-side of the first change we OBSERVED after your date, through the same resolver the watch diff uses. Here isBounded: true is the WEAK claim, described below.

The asOf block reports:

  • source -- on observed_change: live (nothing captured after your date AND the text we hold took effect on or before it, so today's text stood then), reconstructed, or unavailable. On stored_edition: published or unavailable
  • outOfCoverageReason -- why no text came back, when none did
  • currentVersionEffective / earliestHeldVersion -- when the text we hold took effect, and the earliest version we hold. If your date PRECEDES the current text's effective date, today's text is never returned as the law on your date: you get a held prior version (engine: stored_edition, source: published) or source: unavailable with these two dates and NO text, refunded. A section that states no readable effective date and has no capture reaching your date returns today's text with a note saying it is unverified for that date
  • basisChangeId -- the change event this answer rests on, readable at /us/statutes/section/{actId}/changes
  • observedFrom -- how far back the evidence reaches for this section
  • isBounded -- read this one, and read engine first. On observed_change, true means we observed no change affecting your date, which is not the same as there having been none: capture began long after the corpus did and is per-source. On stored_edition it is inverted and stronger, as above: true means a held edition governed your date.

html is never returned on this path: the text is plain, and synthesising markup the publisher never printed would be a wrong answer on the endpoint whose job is fidelity.

A section that did not exist on that date returns available: false with asOf.existed: false and IS charged, the same way an unresolved citation is charged on /resolve: a confident negative is the answer. On observed_change, a section we know changed but cannot rebuild returns source: "unavailable" and is refunded. On stored_edition, an out-of-coverage date is an ANSWER about what we hold and is charged, which is the same rule the CFR annual editions have always followed.

get/api/v1/us/statutes/section/{act_id}/body

Request

Path parameters

act_idstring required

Section identifier, e.g. USC_T42_C21_S1983 (Title 42, Chapter 21, Section 1983, which a lawyer writes as 42 U.S.C. § 1983). Take it from a /us/statutes/search or /us/statutes/resolve result.

A citation also works here: 26 U.S.C. § 1, 42 USC 1983 or Cal. Civ. Code § 1950.5 is resolved with the same resolver /resolve uses, and the section is served. A citation costs this endpoint's price PLUS the /resolve price (2 credits), charged as its own line whether or not it resolves, exactly as /resolve charges; that is the same total as calling /resolve and then this endpoint, in one round trip. An exact act_id costs only this endpoint's price. When a citation resolves, or when the id only matched after surrounding whitespace, quotes or a trailing period were removed, the response carries resolvedFrom saying what your input was matched as. Check it the way you would check a /resolve answer. A citation containing / cannot travel in a URL path segment; resolve it with GET /us/statutes/resolve instead.

Do not assemble an id from a citation: the title and section are derivable, but the CHAPTER is not, so USC_T26_S1 misses. A miss returns 404 with reason and, where the section exists under another id, didYouMean.

State session laws (acts as enacted, ids starting SSL_) are not code sections: read them at /us/session-laws/{sessionLawId}.

Example:CFR_T17_P240_S240_10b5_1

Query parameters

format'all' | 'both' | 'html' | 'markdown' | 'plain' | 'content' | 'operative'

Which representations to return. both (the default) returns html and plain. A long section carries the same text twice that way, so plain or html alone roughly halves the payload. Cost is unchanged: the fetch is the same either way.

all adds markdown where the section has a structured rendering. It is opt-in because it is a third full copy of the text (about 600,000 extra characters on 49 CFR 172.101), which a model-facing client would pay for in tokens without asking.

markdown returns only markdown. On a section with no structured rendering it falls back to plain with a note saying so, never to an empty body. tables and figures are returned on every format, because they are small and describe the text you received.

content omits html and plain and returns the split fields (content, sourceCredit, notes).

operative omits notes as well, leaving content + sourceCredit: the law and what enacted it, and nothing else. This is the smallest representation of a section, and on a note-heavy section it is the difference between a payload that fits in a prompt and one that does not. Measured on 17 U.S.C. § 107: 95,217 bytes at both, 30,545 at content, 1,564 at operative, all for the same 6 credits.

Only United States Code sections can be split, so on any other corpus both values fall back to returning plain with a note saying why -- content will be null there, so read note rather than assuming the section was empty.

Example:operative
structuredboolean

When true, also return a subsections tree parsed from the text for pincite addressing, and markdown as that tree rendered as nested Markdown lists. Same cost.

structured=true OWNS markdown: on every format, and on every source, markdown is the nested-list rendering, never the table-preserving rendering a r2_render section otherwise returns for format=all/markdown (a note says so when that happens). Ask without structured for the tables. With format=markdown the nested lists are returned alone, without html or plain.

The response's structure block says whether the tree came from a stored outline (checked against this exact text) or was parsed on this request. To fetch a single unit instead of the whole tree, use pinpoint.

Example:true
pinpointstring nullable

Return one subsection in pinpoint, alongside the whole body. Parenthesised labels, outermost first, without the section number: (c), (c)(1), (d-1), (f)(1.5). A label containing a hyphen or a dot is a single label. Same cost. A malformed pinpoint, or one sent with asOf, is a 422 and is not charged.

Read pinpoint.matched before using the text: a subsection the section does not have is reported as matched: false, not answered with the whole section.

Example:(c)(1)
asOfstring date nullable

Return the section's text as it stood on this date (YYYY-MM-DD, for example 2026-01-15) instead of today's. Same cost. Cannot be combined with pinpoint (a 422, not charged): a historical text carries no subsection outline.

This is a reconstruction, not an archive. The corpus holds one current text per citation; an earlier one is rebuilt from the before-side of the first change we OBSERVED after your date. The asOf block on the response says which version you got (source), what it rests on (basisChangeId), how far back the evidence reaches (observedFrom), and whether the answer is bounded by when capture began rather than by the law (isBounded). Read isBounded before citing the text.

A section that did not exist yet returns available: false with asOf.existed: false, which is a real answer and is charged. A section we know changed but cannot rebuild returns source: "unavailable" and IS refunded, because you asked for a historical text and did not get one.

A date that does not exist on a calendar (2026-02-30) is a 422 and is not charged.

Headers

Idempotency-Keystring nullable

Optional. 16 to 255 visible ASCII characters (a UUIDv4 is ideal). A retry with the same key and the same request replays the original 2xx response for 24 hours without charging again. The same key with a different request is rejected. Scope is the API key, method, path and body. The stored response body is a query-derived cache controlled by the account's data retention setting cacheQueryDerivedData: when it is false the body is never stored and a retry answers 409 idempotency_replay_unavailable, without charging again.

Example:3f9c2a1e-7b44-4d0a-9c1e-5a6b7c8d9e0f

Response

Successful Response

actIdstring required

The act_id of the section served. Equal to your request unless resolvedFrom is set, in which case it is the id your citation or cleaned-up input resolved to.

htmlstring nullable

The section text as HTML. When source is r2_render this is our structured rendering of the publisher's source: real <table> elements (with <caption>, colspan and rowspan) and <figure> / <img> elements at the position the publisher prints them, with images hosted on statutes-us.vaquill.ai. When source is r2_s3 this is the publisher's own markup (tables, paragraph structure, history lines), cut to the section's own content where we recognise the publisher's page layout. For any other source the text was not held as per-section HTML, and html carries the same text as plain with no markup.

plainstring nullable

Plain text version.

sourcestring nullable

Which copy the text came from: r2_render (our structured rendering, carrying markdown, tables and figures), r2_s3 (the publisher's page for this section), r2_text (our per-section text extraction), qdrant_reconstructed (reassembled from indexed passages), and on asOf requests stored_edition or corpus_change_history. A storage identifier, not a citation: cite sourceUrl.

sourceUrlstring nullable

Where this text was published by the government, so the bytes you were served can be cited and verified against the official record. Null when we hold no publishable link for the section: only official government links are served here, and an absent link is the correct answer in that case. source is a storage identifier and is NOT a citation.

sourceUrlNotestring nullable

Says why sourceUrl is null. Either we serve no link for this section on purpose and it is cited by citation alone, or the publisher issues it only inside a larger file (an archive, spreadsheet or whole volume) that is not a page of the section, or no source link is recorded for it at all. Null when sourceUrl is set.

contentstring nullable

The OPERATIVE TEXT of the section, with the source credit and the notes apparatus removed. This is the law; plain is the law plus everything the publisher prints around it.

Populated for United States Code sections, where GPO delimits the fields in the granule it publishes. Null for CFR and for state corpora, whose sources carry no equivalent structure -- null means "we cannot split this reliably", never "this section is empty", and plain is still the whole body.

Worth using if you feed sections to a model: the operative text is a median 46% of plain across USC and as little as 3.4% (17 U.S.C. § 107, where nearly all of the body is committee reports and amendment notes). A model handed the full body can quote a 1992 amendment note as the law in force.

sourceCreditstring nullable

The publisher's credit line for the section, e.g. (Pub. L. 94-553, title I, §101, Oct. 19, 1976, 90 Stat. 2546; ...). Split out of the body rather than left inside it.

The same value is also on GET /us/statutes/section/{actId} as sourceCredit; it is repeated here so a caller fetching the text does not need a second call to know what enacted it.

notesstring nullable

The notes apparatus the publisher prints after the section: Historical and Revision Notes, committee reports, Editorial Notes (codification and amendments), Statutory Notes and Related Subsidiaries (effective dates), and any guidelines reprinted by the editors.

Kept, not discarded: it is the legislative history, and it is the reason a section's body can be twenty times the length of the law. It is simply NOT the operative text, so it is served as its own field. Null where we cannot split the body.

Also null, deliberately, when you pass format=operative: that is the one format that asks us to leave the apparatus off the wire. Null there means "not sent", not "none exists" -- the same request at format=content returns it.

availableboolean

Whether full text is available.

notestring nullable

Note if text is unavailable.

bodyUnavailableboolean nullable

Present, and true, only on a section that has no text to return: the publisher prints it as images (an appendix, a form, a map), or the text we hold is only a partial copy of the official text. Omitted on every other section. The section is real and its metadata is complete; there is simply no body, so body / plain / html are null, available is false on /body, and nothing is charged for a body. Read it instead of treating a null body as a fetch failure that is worth retrying.

bodyUnavailableReason'image_only_source' | 'misfiled_source_text' | 'partial_snapshot_text' nullable

Why there is no body, present with bodyUnavailable. image_only_source: the publisher prints this section as images, so there is no text to extract. Where we hold an official link for the section it is in sourceUrl; it is null where we may not republish the publisher's link. misfiled_source_text: the text stored under this regulation opens with another rule's number (a prior version filed under a renumbered rule), so it is withheld rather than served as this rule. partial_snapshot_text: the text we hold for this section is only a partial copy of the official text, so it is withheld rather than served as if it were complete.

markdownstring nullable

The body as GitHub-flavoured Markdown. When source is r2_render this is the structured rendering: tables as GFM pipe tables (a caption line above, footnotes below, multi-level headers joined as Parent / Child) and figures as ![alt](url) at their position in the text. Returned only when format is all or markdown, not on the default both, where it would be a third full copy.

For a section with no structured rendering, markdown is null unless you pass structured=true, in which case it is the body as nested Markdown lists (the pre-existing behaviour). When both exist the structured rendering wins, because it is the one that keeps the tables; subsections is returned either way.

hasTablesboolean nullable

True when the body contains at least one table, false when it contains none. Null when not known, because the section's corpus has no structured rendering yet.

hasFiguresboolean nullable

True when the body contains at least one figure, equation or form image, false when it contains none. Null when not known, because the section's corpus has no structured rendering yet.

processingTimeMsnumber

Server-side time for this request in milliseconds, excluding network transit. Useful for spotting a slow query; not billed on.

creditsConsumednumber

Credits actually charged for this call. Read it rather than assuming the list price: failed and refunded work bills 0, and batch endpoints charge per item returned, so a partial result costs less than a full one.

Example response

{
  "actId": "USC_T42_C21_S1983",
  "sourceUrl": "https://www.govinfo.gov/content/pkg/USCODE-2024-title17/html/USCODE-2024-title17-chap1-sec107.htm",
  "content": "Notwithstanding the provisions of sections 106 and 106A, the fair use...",
  "sourceCredit": "(Pub. L. 94-553, title I, §101, Oct. 19, 1976, 90 Stat. 2546)",
  "notes": "Historical and Revision Notes\n\nhouse report no. 94-1476...",
  "committeeNotes": [
    {
      "year": 2015,
      "kind": "amendment",
      "heading": "Committee Notes on Rules—2015 Amendment",
      "effectiveDate": "2015-12-01",
      "subdivisionsDiscussed": [
        "(b)(1)",
        "(c)"
      ]
    }
  ],
  "committeeNote1937Print": {
    "document": "H.R. Doc. No. 588, 75th Cong., 3d Sess. (1938)",
    "ruleNumber": "4",
    "printedHeading": "Rule 4. Process.",
    "verdict": "agrees"
  },
  "bodyUnavailable": true,
  "bodyUnavailableReason": "image_only_source",
  "tables": [
    {
      "tableId": "t1"
    }
  ],
  "figures": [
    {
      "figureId": "fig_3f2a9c0d1e4b5a67",
      "url": "https://statutes-us.vaquill.ai/figures/9b2e...c41.gif",
      "sourceUrl": "https://www.ecfr.gov/graphics/er13my11.020.gif",
      "mimeType": "image/gif"
    }
  ],
  "subsections": [
    {
      "pincite": "(b)(2)"
    }
  ],
  "pinpoint": {
    "requested": "(c)(1)",
    "path": [
      "c",
      "1"
    ],
    "label": "(1)",
    "level": "paragraph",
    "inferred": true,
    "matched": true,
    "matchLevel": "exact",
    "leadIn": [
      {
        "path": [
          "c"
        ],
        "label": "(c)",
        "text": "Unless a different limit is established under this Chapter, the limit is:"
      }
    ],
    "children": [
      {
        "path": [
          "c",
          "1"
        ],
        "label": "(1)",
        "level": "paragraph",
        "inferred": true
      }
    ],
    "siblings": {
      "previous": "b",
      "next": "d"
    },
    "charStart": 1204,
    "charEnd": 1873,
    "kind": "range",
    "reason": "no_such_subsection",
    "structure": {
      "source": "artifact",
      "quality": "verified",
      "builder": "ilga_html",
      "textSha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
    }
  },
  "structure": {
    "source": "artifact",
    "quality": "verified",
    "builder": "ilga_html",
    "textSha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
  },
  "asOf": {
    "requested": "2026-01-15",
    "engine": "observed_change",
    "source": "reconstructed",
    "basisChangeId": 91,
    "observedFrom": "2026-08-09T04:10:00Z",
    "resolvedEditionYear": 2019,
    "scheduledEditionYear": 2024,
    "editionsObserved": [
      2014,
      2015,
      2016
    ],
    "currentVersionEffective": "2026-01-01",
    "earliestHeldVersion": "2026-01-01"
  },
  "resolvedFrom": {
    "input": "26 U.S.C. § 1",
    "actId": "USC_T26_C1_S1",
    "via": "citation",
    "subsection": "(h)(11)",
    "matchLevel": "container",
    "container": {
      "kind": "chapter",
      "label": "U.S. Const. art. III",
      "childCount": 12,
      "children": [
        {
          "actId": "CONST_US_A3_S1",
          "citation": "U.S. Const. art. III, § 1",
          "status": "in_force"
        }
      ]
    },
    "repair": {
      "kind": "code_name",
      "cited": "Jud. Ct. Acts Law",
      "interpretedAs": "N.Y. Judiciary Law § 475",
      "alternatives": [
        {
          "actId": "STATE_NY_FCT_S475",
          "citation": "N.Y. Fam. Ct. Act § 475"
        }
      ]
    },
    "registerReference": {
      "citation": "36 Pa. Bull. 510",
      "state": "il",
      "kind": "page",
      "ruleCount": 2
    }
  },
  "processingTimeMs": 240.5,
  "creditsConsumed": 4
}

Changes

No recorded changes to this operation across all 1 revision of this API.