curl --request GET \
--url https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"actId": "USC_T42_C21_S1983",
"html": "\n<p>Every person who, under color of any statute, ordinance, regulation, custom, or usage, of any State or Territory or the District of Columbia, subjects, or causes to be subjected, any citizen of the United States ...</p>",
"plain": "Every person who, under color of any statute, ordinance, regulation, custom, or usage, of any State or Territory or the District of Columbia, subjects, or causes to be subjected, any citizen of the United States or other person within the jurisdiction thereof to the deprivation of any rights, privileges, or immunities secured by the Constitution and laws, shall be liable to the party injured ...",
"source": "r2_s3",
"available": true,
"processingTimeMs": 8.4,
"creditsConsumed": 6
}{
"detail": "Section not found. This id does not exist, but the section does, ...",
"actId": "<string>",
"reason": "assembled_id",
"didYouMean": [
"USC_T26_C1_S1"
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}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, and sections whose text is not yet ingested
(available: false) 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}).
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; we never substitute a
third-party compiler.
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>,colspanandrowspan, and<figure>/<img>elements whose images are hosted onstatutes-us.vaquill.aimarkdown— GitHub-flavoured Markdown, tables as pipe tables and figures asplain— tables as one tab-separated line per row, figures as[Figure N: caption]placeholderstables/figures— what the body contains, in document order. Each figure carries its hostedurland its offset intomarkdownandplain, so you can place images in your own layout. A figure we could not fetch is listed withstatus: "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 elsesourceCredit— 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=contentdropsplain/htmland 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=operativedropsnotesas well, returningcontent+sourceCreditand nothing else. Measured on17 U.S.C. § 107: 95,217 bytes atboth, 61,003 atplain, 30,545 atcontent, 1,564 atoperative. 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.
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— onobserved_change:live(nothing captured after your date, so today’s text stood then),reconstructed, orunavailable. Onstored_edition:publishedorunavailableoutOfCoverageReason— why no text came back, when none didbasisChangeId— the change event this answer rests on, readable at/us/statutes/section/{actId}/changesobservedFrom— how far back the evidence reaches for this sectionisBounded— read this one, and readenginefirst. Onobserved_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. Onstored_editionit 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.
curl --request GET \
--url https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/us/statutes/section/{act_id}/body"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"actId": "USC_T42_C21_S1983",
"html": "\n<p>Every person who, under color of any statute, ordinance, regulation, custom, or usage, of any State or Territory or the District of Columbia, subjects, or causes to be subjected, any citizen of the United States ...</p>",
"plain": "Every person who, under color of any statute, ordinance, regulation, custom, or usage, of any State or Territory or the District of Columbia, subjects, or causes to be subjected, any citizen of the United States or other person within the jurisdiction thereof to the deprivation of any rights, privileges, or immunities secured by the Constitution and laws, shall be liable to the party injured ...",
"source": "r2_s3",
"available": true,
"processingTimeMs": 8.4,
"creditsConsumed": 6
}{
"detail": "Section not found. This id does not exist, but the section does, ...",
"actId": "<string>",
"reason": "assembled_id",
"didYouMean": [
"USC_T26_C1_S1"
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
API key issued from the developer dashboard. Pass as Authorization: Bearer vq_key_... (preferred).
Path Parameters
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}.
3 - 200"CFR_T17_P240_S240_10b5_1"
Query Parameters
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.
all, both, html, markdown, plain, content, operative "operative"
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.
true
Return the section's text as it stood on this date (YYYY-MM-DD) instead of today's. Same cost.
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.
^\d{4}-\d{2}-\d{2}$"2026-01-15"
Response
Successful Response
Full text of a statute section in HTML and/or plain text.
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.
"USC_T42_C21_S1983"
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.
Plain text version.
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.
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: a third-party compiler is never served here, and an absent link is the correct answer in that case. source is a storage identifier and is NOT a citation.
"https://www.govinfo.gov/content/pkg/USCODE-2024-title17/html/USCODE-2024-title17-chap1-sec107.htm"
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.
"Notwithstanding the provisions of sections 106 and 106A, the fair use..."
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.
"(Pub. L. 94-553, title I, §101, Oct. 19, 1976, 90 Stat. 2546)"
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.
"Historical and Revision Notes\n\nhouse report no. 94-1476..."
Whether full text is available.
Note if text is unavailable.
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  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.
The tables in the body, in document order, with their size. An empty list means the section has none. Null means not known: the section's corpus has no structured rendering yet, so a table may still be present in html.
Show child attributes
Show child attributes
The figures, equations and form images in the body, in document order, with hosted image urls and each one's offset into markdown and plain. An empty list means the section has none. Null means not known: the section's corpus has no structured rendering yet.
Show child attributes
Show child attributes
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.
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.
The section broken into its lettered and numbered subsections, nested as they appear in the text. Use it to quote or link a single clause rather than the whole section. Present only when structured=true.
Show child attributes
Show child attributes
Present only when the request passed asOf. Says WHICH version of the section you are holding and how far the evidence for it goes. Read isBounded before treating the text as the law on that date.
Show child attributes
Show child attributes
Null when the section is exactly the act_id you sent. Otherwise how your input was matched: a citation, or an act_id with transport damage (whitespace, quotes, a trailing period) removed. When your citation named a chapter, article, series or several sections, the section served is the FIRST of them and matchLevel says so, as on GET /us/statutes/resolve.
Show child attributes
Show child attributes
Server-side time for this request in milliseconds, excluding network transit. Useful for spotting a slow query; not billed on.
240.5
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.
4
Was this page helpful?

