How to Pull US Code Sections Programmatically
Short answer: there is no official per-section US Code API. To pull a single USC section programmatically you have two real options. Use the GovInfo API (free api.data.gov key) to fetch a section as a package granule, which returns metadata plus HTML, PDF, and MODS, but not clean per-citation JSON. Or use a statutes API like Vaquill AI that maps a citation to a stable ID and returns the section as structured JSON. Both are shown below with working requests.
The first time I went looking for a USC API, I did what most developers do. I searched for "United States Code API," landed on the official site at uscode.house.gov, and clicked Download. What I got back was not an API. It was a 1.4 GB pile of XML.
That is the moment a lot of legal-tech projects quietly change shape. You wanted a clean endpoint that returns 42 U.S.C. § 1983 as JSON. Instead you inherited an XML parser, a schema spec, and a currency problem you did not know existed.
If you searched for a "usc api" and ended up here, you are in the right place. The honest answer is that the government does not publish one, and the gap between "download the Code" and "query a section" is where most of the real engineering lives.
This post is a practical walkthrough: how to pull a single US Code section programmatically with real requests, what the response actually looks like, and why pulling the section is the easy part. Keeping that section structured, cited correctly, and current is the part everyone underestimates.
TL;DR
- There is no official per-section USC API. The Office of the Law Revision Counsel (OLRC) ships the United States Code as bulk USLM XML, XHTML, and PDF downloads, whole-Code or title-by-title, with no queryable section endpoint.
- GovInfo's developer API is the closest official option. It is package and granule oriented (collections like USCODE), so a granule request returns metadata and download links (HTML, PDF, MODS), not clean per-citation JSON. A working example is below.
- The hard problems are not retrieval. They are mapping a citation to the right node, handling repealed and renumbered sections, resolving cross-references, and keeping currency as Congress amends the Code.
- A purpose-built statutes API turns the workflow into three primitives: search the Code, fetch a section's metadata by a stable
actId, fetch its full text. The same shape extends to the CFR and state codes. - For how to phrase the search itself (AND, OR, NOT, proximity), see the companion guide to Boolean search for legal databases. This post is about pulling and structuring the result.
When you request a section granule summary from the GovInfo API, what does the JSON actually contain?
Part of our MCP and developer guide series.
For related MCP / API / developer coverage, see How to Pull US Code and Statutes Programmatically: A USC API Guide and Legal API in 2026: What It Is, What It Returns, and How to Pick One.
What the Government Actually Publishes
The gap between expectation and reality is the whole story here.
The official US Code is maintained by the OLRC and distributed from uscode.house.gov as bulk downloads. You can grab the entire Code or one title at a time, in USLM XML, XHTML, or PDF. That is it. There is no GET /titles/42/sections/1983 waiting for you.
The Library of Congress has written about this distribution model on its In Custodia Legis blog: the data is open, which is genuinely good, but open bulk data is not the same thing as a queryable API.
USLM stands for United States Legislative Markup. It is a second-generation XML schema derived from Akoma Ntoso, the international LegalDocML standard for legislative documents. It is well designed.
It is also a full document model, which means a single title can be a deeply nested tree of subtitles, chapters, subchapters, parts, and sections, each with its own identifiers, notes, source credits, and cross-references.
Then there is GovInfo, run by the Government Publishing Office. GovInfo does have a developer API (you authenticate with a free api.data.gov key), and it does expose the USCODE collection. This is the closest thing to a real US Code API the government ships, so it is worth showing exactly what it returns.
Pulling a section from the GovInfo API
The GovInfo API is organized around packages and granules. A package is a US Code title for a given year (USCODE-2023-title42). A granule is one section inside it (USCODE-2023-title42-chap21-subchapI-sec1983). You ask for a granule summary, you get JSON back.
curl "https://api.govinfo.gov/packages/USCODE-2023-title42/granules/\
USCODE-2023-title42-chap21-subchapI-sec1983/summary?api_key=DEMO_KEY"
That request returns 200 with a summary like this (verified live, June 2026, with the public DEMO_KEY):
{
"title": "Civil action for deprivation of rights",
"granuleId": "USCODE-2023-title42-chap21-subchapI-sec1983",
"dateIssued": "2023-12-31",
"download": {
"txtLink": ".../USCODE-2023-title42-...-sec1983/htm",
"pdfLink": ".../USCODE-2023-title42-...-sec1983/pdf",
"modsLink": ".../USCODE-2023-title42-...-sec1983/mods"
}
}
Two things jump out. First, the section text is not in the JSON. You get download links, and the text comes as HTML, PDF, or MODS metadata, not as a parsed field you can index. Second, you had to know the granule ID already, including the chapter and subchapter (chap21-subchapI), to build that URL. There is no "give me 42 U.S.C. 1983" lookup by citation. You either browse the granule list for a title (over 10,000 granules for title 42) or maintain your own citation-to-granuleId map.
GovInfo is excellent for archival and bulk ingestion. It is not built to answer "give me the current text of 17 U.S.C. § 107 as structured JSON." You still do the citation mapping and the text parsing yourself.
So when someone says "I'll just hit the USC API," what they are really signing up for is: resolve the granule ID, fetch the granule, parse the HTML, model the hierarchy, and maintain all of it forever. That last word, forever, is the one that hurts.
Why Structured Statute Data Is Harder Than It Looks
Pulling raw statute text is trivial. Pulling trustworthy, structured statute text is a real systems problem, and it is the part most teams underestimate. Four things turn an afternoon project into a quarter.
Citations do not map cleanly to nodes. A human reads 42 U.S.C. § 1983 and knows exactly what they mean. Your parser sees a tree of XML elements with identifier attributes, and you have to write the logic that turns "title 42, section 1983" into the correct node, while handling the fact that the same section number appears in every title.
A bare "Section 1983" is meaningless without its title. This is the same ambiguity that bites people in Boolean search, where 5 U.S.C. § 706 is APA review and a freestanding "706" is noise.
Sections get repealed, renumbered, and reserved. The Code is not a static document. Sections are struck, moved, and renumbered as Congress acts. A section can be marked "Repealed" or "Omitted" or "Reserved" while still occupying its slot in the hierarchy.
If your parser does not model these states, you will confidently return text for a section that no longer has operative effect, which in legal research is worse than returning nothing.
Cross-references are everywhere and they are load-bearing. Statutes refer to other statutes constantly. "As defined in section 2 of this title," "notwithstanding section 1331 of title 28." A flat text dump strips the structure that makes those references resolvable. To do anything useful, you need to preserve and ideally resolve them.
Currency is a moving target. USLM is updated continuously as laws are enacted. The Code you parsed last month is not the Code today. Anyone shipping statute data has to answer a deceptively hard question: as of what date is this text correct?
If you cannot answer that, you do not have a legal-research data source. You have a snapshot of unknown vintage.
None of this is exotic. It is just unglamorous, and it is precisely the work that an API layer exists to absorb. You build the parser, the hierarchy model, the citation resolver, and the currency pipeline once, then expose three clean endpoints so nobody has to rebuild that XML parser again.
(Plenty of teams do rebuild it. It is one of those wheels the industry keeps reinventing, each parser slightly different, each one drifting out of date on its own schedule.)
The Three Primitives You Actually Need
Strip away the ceremony and there are only three operations a developer wants against the US Code:
- Search the Code for a concept or phrase.
- Fetch a section's metadata (citation, where it sits in the hierarchy, what it links to) by a stable identifier.
- Fetch the section's full text, cleanly.
The examples below run against the Vaquill AI statutes API, because it is purpose-built for exactly this shape. The public surface is statutes and legislation only: U.S. Code, CFR, state codes (49 states plus DC and Puerto Rico), the Constitution, federal rules, and executive actions.
There is no public case-law, ask, or citation-resolution endpoint, so I will not pretend otherwise. If you need court opinions programmatically, that is a different data source you would source separately.
One housekeeping note: the JSON below shows representative request and response shapes built from the documented schema, not pasted live output. Field names match the API; exact values will vary with the data and with currency.
Authentication
Every request carries a bearer token.
Authorization: Bearer vq_key_your_key_here
Content-Type: application/json
Keys are issued from the platform dashboard.
Primitive 1: Search the Code
POST /api/v1/statutes/search. The body takes a query plus optional scoping: corpusType (one of USC, CFR, STATE, CONSTITUTION, FEDERAL_RULES, and so on), state, titleNumber, and limit.
import requests
BASE = "https://api.vaquill.ai/api/v1"
HEADERS = {
"Authorization": "Bearer vq_key_your_key_here",
"Content-Type": "application/json",
}
payload = {
"query": "civil action color of law",
"corpusType": "USC",
"titleNumber": "42",
"limit": 5,
}
resp = requests.post(f"{BASE}/statutes/search", json=payload, headers=HEADERS)
resp.raise_for_status()
results = resp.json()
A representative response shape:
{
"results": [
{
"actId": "USC_T42_C21_S1983",
"citation": "42 U.S.C. § 1983",
"title": "Civil action for deprivation of rights",
"titleNumber": "42",
"corpusType": "USC",
"breadcrumb": "Title 42 > Chapter 21 > § 1983",
"excerpt": "Every person who, under color of any statute, ordinance, regulation, custom, or usage...",
"externalUrl": "https://uscode.house.gov/..."
}
],
"total": 1
}
The field that matters most here is actId. That is the stable identifier you carry into the next two calls. The convention is readable on purpose: USC_T<title>_C<chapter>_S<section>, so USC_T42_C21_S1983 is title 42, chapter 21, section 1983. Take it from the response; do not hand-build it.
You do not have to reverse-engineer an opaque node path out of an XML tree. The hierarchy is already encoded in the ID.
For the syntax inside the query string itself (quoting phrases, combining terms with AND/OR/NOT, proximity), the Boolean search guide is the companion piece. This post assumes you already know what to search for and focuses on what you do with the result.
Primitive 2: Fetch Section Metadata
GET /api/v1/statutes/section/{actId}. Hand it the actId and you get back the section's identity and its place in the Code.
act_id = "USC_T42_C21_S1983"
resp = requests.get(f"{BASE}/statutes/section/{act_id}", headers=HEADERS)
section = resp.json()
Representative shape:
{
"actId": "USC_T42_C21_S1983",
"citation": "42 U.S.C. § 1983",
"title": "Civil action for deprivation of rights",
"corpusType": "USC",
"titleNumber": "42",
"titleName": "The Public Health and Welfare",
"chapter": "21",
"chapterName": "Civil Rights",
"sectionNumber": "1983",
"breadcrumb": "Title 42 > Chapter 21 > § 1983",
"htmlUrl": "/api/v1/statutes/section/USC_T42_C21_S1983/body",
"externalUrl": "https://uscode.house.gov/..."
}
This is the payload that the bulk XML download makes you compute yourself. The breadcrumb, the chapter heading, the title heading, all of it has to be assembled by walking up the USLM tree from the section node. Here it arrives resolved.
Primitive 3: Fetch the Full Text
GET /api/v1/statutes/section/{actId}/body. Same identifier, the actual statutory text, in both rendered HTML and plain text.
resp = requests.get(f"{BASE}/statutes/section/{act_id}/body", headers=HEADERS)
body = resp.json()
print(body["text"]) # plain text for ingestion / embeddings
# body["html"] keeps structure for display
{
"actId": "USC_T42_C21_S1983",
"citation": "42 U.S.C. § 1983",
"html": "<p>Every person who, under color of any statute...</p>",
"text": "Every person who, under color of any statute, ordinance, regulation, custom, or usage, of any State... shall be liable to the party injured in an action at law..."
}
The two formats exist for two jobs. The HTML preserves subsection structure for display in your UI. The plain text is what you feed into a retrieval pipeline, embeddings, or an LLM prompt.
If you are building retrieval-augmented generation over statutes, the plain-text body is the unit you chunk and index. We walk through that retrieval layer in how AI legal research actually works.
That is the entire happy path: search to find the actId, fetch metadata for the hierarchy, fetch the body for the text.
Listing What Is Available
Two list endpoints round things out, and they matter more than they look.
GET /api/v1/statutes/states returns the jurisdictions in the corpus with section counts. GET /api/v1/statutes/codes?state=<state> returns the codes available for a given state. These are how you build a jurisdiction picker, validate user input before a search, or audit coverage before you commit to a data source.
states = requests.get(f"{BASE}/statutes/states", headers=HEADERS).json()
ca_codes = requests.get(
f"{BASE}/statutes/codes",
params={"state": "CA"},
headers=HEADERS,
).json()
Coverage is the question every serious buyer asks, so here are the figures we publish for our own corpus: 54,855 USC sections, 219,403 CFR sections, and 1,068,918 state-code sections, plus the Constitution (74 chunks), federal rules (297), and executive actions (3,567, refreshed daily). That is north of 1.3 million sections behind one consistent schema.
I cite these as product numbers, not a third-party benchmark, but they make the point: the value is not any single section, it is the joined, currency-managed whole. Joining USC, CFR, and state codes under one citation model is the work.
Build vs. Buy: An Honest Take
Should you parse the USLM XML yourself or hit an API? It depends, and I will not pretend the answer is always "buy."
Parse it yourself if statute text is your core product, you have the engineering to own a parser and a currency pipeline indefinitely, and you need control over every edge case. The data is open and free. That is a real and legitimate path. A handful of civic-tech efforts have done exactly this in the open, and the ecosystem is better for it.
Reach for an API if statutes are an input to your product rather than the product itself. If you are building a contract-review tool, a compliance checker, or a research assistant, you do not want to spend a quarter on a USLM parser and then own its maintenance forever. You want three endpoints and a stable actId.
The build-it-yourself cost is rarely the initial parse. It is the second year, when the schema shifts, a title gets renumbered, and your snapshot silently goes stale while you are busy shipping features.
The trap I see most often is teams that build a quick scraper, ship it, and conflate full text with structure. A scraped HTML page or a PDF is not queryable structured data with stable citation IDs.
It looks like data until the day a lawyer asks "is this current, and how do you know," and you have no answer.
A Note on Trust
Everything above is about plumbing, but the reason any of it matters is trust. The 2023 Mata v. Avianca sanctions, where lawyers filed a brief full of cases a chatbot invented, made the cost of unverifiable legal data concrete and public.
Statutes are lower-drama than fabricated case citations, but the principle is identical: if your system surfaces "42 U.S.C. § 1983 says X," a lawyer needs to click through to the verbatim text and confirm it, as of a known date.
That is why the three primitives matter in that exact order. Search gets you a candidate. The actId and metadata pin it to a real place in the Code. The body gives you the words to verify. No step asks the reader to trust a summary.
That is the whole reason an API layer over the US Code exists. Not because the data is secret (it is gloriously open), but because making it structured, cited, current, and joinable across jurisdictions is genuine work that should be done once and done well.
FAQ
Is there an official US Code API? No. The Office of the Law Revision Counsel publishes the United States Code as bulk USLM XML, XHTML, and PDF downloads at uscode.house.gov, whole-Code or title-by-title. There is no official endpoint that returns a single section by citation as JSON.
How do I pull a US Code section programmatically?
Two practical routes. The GovInfo API lets you fetch a section as a package granule (for example USCODE-2023-title42-chap21-subchapI-sec1983) with a free api.data.gov key, but it returns download links to HTML, PDF, and MODS rather than parsed JSON. A statutes API like Vaquill AI maps a citation to a stable actId and returns the section as structured JSON with hierarchy and full text.
Is the GovInfo API free?
Yes. You sign up for an api.data.gov key at no cost, and the public DEMO_KEY works for testing at lower limits. The data itself is public domain.
What format is the US Code published in? USLM (United States Legislative Markup) XML, plus XHTML and PDF. USLM is a second-generation schema derived from Akoma Ntoso, the international LegalDocML standard. It models the full document hierarchy, so a single title is a deeply nested tree of subtitles, chapters, parts, and sections.
How do I get the current text of a US Code section?
Currency is the catch. The Code changes as Congress acts, so the answer depends on the edition. GovInfo packages are dated by year (the USCODE-2023-... prefix). Whatever source you use, confirm the "as of" date before you treat a section as operative, because repealed and renumbered sections still occupy their slots.
What is the difference between the GovInfo API and a statutes API? GovInfo is a bulk and archival API organized around packages and granules; you resolve the granule ID and parse the content yourself. A statutes API is built for per-citation retrieval: it absorbs the parsing, hierarchy modeling, citation resolution, and currency, then exposes search, metadata, and body as clean JSON.
Can I get all 50 state codes from one API? Not from the government. Each state publishes (or does not publish) its code on its own terms, in its own format. Aggregators like Vaquill AI join federal and state statutory codes under one schema and one citation model, which is the part you would otherwise build and maintain per jurisdiction.
For more on the statutes API surface and what it covers, see /legal-api, or email contact@vaquill.ai.

New legal AI guides, weekly.
Further Reading
Legal API in 2026: What It Is, What It Returns, and How to Pick One
Read postTop Legal Data APIs for Developers in 2026
Read postHow Legal API Pricing Works (and Why Vendors Hide It)
Read postBoolean Search for Legal Databases
Read postCourt Records API vs Court Data API: Which One Your App Actually Needs
Read postReplace Harvey AI: Build Your Own Legal AI Stack on Claude + MCP (2026)
Read post
Co-Founder & CTO
Priyansh leads engineering and AI at Vaquill, from the matter workbench to drafting, document comparison, document matrix, and citation-verified research.