
Look up the GovInfo API rate limit and you will find "1,000 requests per hour" on one page and "36,000 requests per hour" on another. Both come from government sources. They describe different things, and the difference decides whether your batch job finishes.
Short answer: GovInfo is the Government Publishing Office's free archive of official federal documents. Its API needs an api.data.gov key, and the shared sample key, DEMO_KEY, lets you try a few requests and then locks you out for the rest of the day. Use the API to find what changed or to search, the link service when you only need an official link from a citation, and the bulk files when you want a whole collection.
Written and checked on 12 October 2026. This is general information, not legal advice; check the cited statute or opinion before relying on it.
TL;DR
- Three doors. The API needs a key. The link service and the bulk repository do not.
- Keys come from api.data.gov and work across other agencies' APIs. GovInfo's own documentation sets higher limits (36,000 per hour) than the api.data.gov default (1,000 per hour).
DEMO_KEYis for a first try. Its allowance is small, counted per network address, and ran out within minutes when we tested it.- The API returns packages, granules and links to files, not a section as JSON. The link service turns a citation into the official PDF, HTML or XML.
- Some collections have bulk files, such as the Federal Register, the Statutes at Large and the CFR. The US Code is not on the bulk list.
A teammate runs the government's sample request with the shared demo key in the morning and it works. By the afternoon the same request returns "over rate limit" and tells you to try again much later. What happened?
Official text, as of 12 October 2026
Citation: 45 CFR 164.404(b), the HIPAA rule on the timing of breach notices to individuals. We use it because we can fetch it from GovInfo by citation, with no key.
What it says (2025 annual edition, read today from GovInfo's PDF): "Except as provided in § 164.412, a covered entity shall provide the notification required by paragraph (a) of this section without unreasonable delay and in no case later than 60 calendar days after discovery of a breach." Official link: the GovInfo link for this section, which redirects to the PDF.
What changed in 2025 and 2026: nothing we found. The eCFR's version history for the section, read today through its API, lists two entries, both with an amendment date of December 30, 2016. The annual edition shows the CFR as published for 2025. For text as of today, use the eCFR.
Three ways in
| Door | Base address | Key | Returns | Best for |
|---|---|---|---|---|
| API | https://api.govinfo.gov | Required | JSON about packages and granules, with links to files | Finding what changed, search, metadata |
| Link service | https://www.govinfo.gov/link/... | None | A redirect to the official file | A stable link from a citation |
| Bulk data repository | https://www.govinfo.gov/bulkdata/... | None | XML files by collection | Taking a whole collection |
GovInfo's Developer Hub lists all three, plus an MCP server, RSS feeds and sitemaps. A package is one publication on GovInfo, such as a day's Federal Register or one volume of a CFR title for a year. A granule is a piece of a package, such as one rule in that day's issue.
Get a key
Sign up at the GovInfo key page. The form issues an api.data.gov key. GovInfo's API README says the same key can reach "a number of other Federal APIs" that use the shared service. Send it in a header or as a query parameter. The api.data.gov developer manual shows both:
curl -H 'X-Api-Key: YOUR_KEY' 'https://api.govinfo.gov/collections'
curl 'https://api.govinfo.gov/collections?api_key=YOUR_KEY'
Without a key, the API answers HTTP 401. We sent one request on 12 October 2026:
{"error": {"code": "API_KEY_MISSING", "message": "No api_key was supplied. Get one at https://www.govinfo.gov/api-signup"}}
Keep the key out of code repositories. The same applies to any MCP client configuration file that holds it as a plain header. In October 2026, a GitHub user reported to GovInfo's API repository that they could not find a documented way to revoke or rotate a key that had been exposed. A GovInfo maintainer replied that because "the keys are managed by api.data.gov," the issue would be moved to that project (usgpo/api issue 206, October 2026).
The limits: three published numbers
As of 12 October 2026, three numbers appear in official places, plus what we saw on the demo key.
| Source | Number | What it describes |
|---|---|---|
| GovInfo's API README, "Keys" section | 36,000 requests per hour (rolling), 1,200 per minute, 40 per second | The current default limits for GovInfo |
| A GovInfo staff reply on GitHub, January 2026 | The same three numbers | The same limits, given to a developer asking about scale |
| A GovInfo staff reply on GitHub, March 2026 | "Our rate limits are significantly higher than 1,000 requests/hour." | A correction to a user quoting 1,000 |
| api.data.gov developer manual | 1,000 requests per hour per key as the default, with the note "Rate limits may vary by service" | The generic default across all agencies |
api.data.gov manual, DEMO_KEY | 30 requests per hour and 50 per day per IP address | The demo key |
GovInfo README, example 429 header for DEMO_KEY | X-RateLimit-Limit: 40 | The demo key, per GovInfo's example |
| What the demo key returned to us today | x-ratelimit-limit: 10 | The demo key, observed |
So the 1,000 figure is the shared gateway's default and the 36,000 figure is GovInfo's own. The manual tells you where to check your real number: the X-RateLimit-Limit and X-RateLimit-Remaining response headers on every call. The January 2026 staff reply also says "the GovInfo API is free to use with a GovInfo API key from api.data.gov. There are no paid tiers available." The same reply says temporary increases can be discussed once the request pattern is understood.
The demo key is the trap. At 08:32 GMT on 12 October 2026 a first call returned x-ratelimit-remaining: 9. After about eight calls the counter read 0, and the next call returned this:
HTTP/2 429
retry-after: 55452
x-ratelimit-limit: 10
{"error": {"code": "OVER_RATE_LIMIT", "message": "You have exceeded your rate limit. Try again later or contact us at govinfo@gpo.gov for assistance"}}
A retry-after of 55,452 seconds sent at 08:35:47 GMT points to midnight GMT, so this is a daily window. The manual counts demo-key requests per IP address, so anyone else calling from your address draws on the same allowance. Get your own key before you benchmark anything.
Two more errors come from the README. A 503 with Retry-After: 30 means a granule's MODS or ZIP file is being generated, so wait and ask again. A 401 means the key is missing.
Here is a small Python helper that follows the Retry-After header for short waits and stops on a daily lockout. We ran it with DEMO_KEY after the allowance was spent, and it stopped as designed:
import os
import time
import requests
API = "https://api.govinfo.gov"
def get(path, **params):
r = requests.get(API + path, params=params, timeout=60,
headers={"X-Api-Key": os.environ["GOVINFO_API_KEY"]})
if r.status_code in (429, 503):
wait = int(r.headers.get("Retry-After", 30))
if wait > 120: # a daily lockout, not a short pause
raise RuntimeError(f"HTTP {r.status_code}, retry after {wait} seconds")
time.sleep(wait)
return get(path, **params)
r.raise_for_status()
print("remaining this window:", r.headers.get("X-RateLimit-Remaining"))
return r.json()
print(get("/collections")["collections"][0]["collectionCode"])
RuntimeError: HTTP 429, retry after 55182 seconds
The discovery endpoints
GovInfo's README sorts the API into discovery and retrieval. Discovery finds packages.
| Endpoint | Use it for | Notes |
|---|---|---|
/collections | The list of collections, then packages added or changed since a time | pageSize is limited to 1,000. Start with offsetMark=*. |
/published | Packages by the date they were issued | Needs collection and pageSize |
/related | Documents related to a package, such as the CFR citations tied to a Federal Register document | Takes an access ID |
/search | Search similar to the website, by POST | Announced as a public preview on August 15, 2023 (GovInfo's search overview page) |
The first call lists collections. We ran it on 12 October 2026. The response had 42 collections. Three of them, trimmed (the counts change as GovInfo adds packages, so expect different numbers):
{"collectionCode": "CFR", "collectionName": "Code of Federal Regulations", "packageCount": 6668, "granuleCount": 7850335}
{"collectionCode": "ECFR", "collectionName": "Electronic Code of Federal Regulations", "packageCount": 49, "granuleCount": null}
{"collectionCode": "USCODE", "collectionName": "United States Code", "packageCount": 1552, "granuleCount": 2027914}
To see what changed since a date in one collection, add the timestamp to the path. This request asked for eCFR packages modified since October 1, 2026, two at a time:
curl -s 'https://api.govinfo.gov/collections/ECFR/2026-10-01T00:00:00Z?offsetMark=*&pageSize=2' -H 'X-Api-Key: YOUR_KEY'
The response, trimmed, shows the fields to rely on:
{"count": 24, "nextPage": "https://api.govinfo.gov/collections/ECFR/2026-10-01T00:00:00Z?offsetMark=AoJw...&pageSize=2",
"packages": [{"packageId": "ECFR-title40", "dateIssued": "2026-10-08", "lastModified": "2026-10-11T17:39:16Z", "title": "Protection of Environment"},
{"packageId": "ECFR-title42", "dateIssued": "2026-10-08", "lastModified": "2026-10-09T20:50:16Z", "title": "Public Health"}]}
To page, follow the nextPage URL until it is null. The offsetMark parameter replaces the older offset, and the README says it lets you page past the first 10,000 results. In December 2025, a GovInfo staff post announced that offset is being deprecated for collections, published and the packages granule list. It set no end date and said the earliest possible removal would be Summer 2026 (usgpo/api issue 187). The issue is still open and two README examples still show offset. We did not test whether offset still works, so use offsetMark.
Notice the lastModified clock. The README says it records when a package "was added or updated" and "is not the equivalent to Date Published, Date Issued, or Date Ingested" in the package metadata. A GovInfo reply on GitHub adds that it "should not be considered an official publication date." Use /collections with lastModified to ask what is new in the system. Use /published to ask what was issued on which day.
One behaviour of /published is not in the README. On 12 October 2026 we asked for Federal Register packages with the same start and end date (published/2009-08-24/2009-08-24). The response was {"count":0,"message":"No results found",...}. Moving the end date forward one day (published/2009-08-24/2009-08-25) returned the August 24 package. A range of August 24 to August 31 returned a count of 5, although the Federal Register published on six days in that span (August 24 to 28, and 31, which its own API confirms). That fits an end date that is not included. This is a single-run observation, not a documented rule, and we did not repeat it. Test it with your own key, and if it holds, add a day to the end date.
The search service takes a JSON body. We ran this on 12 October 2026 with a quoted title:
curl -s -X POST 'https://api.govinfo.gov/search' -H 'Content-Type: application/json' -H 'X-Api-Key: YOUR_KEY' \
-d '{"query":"collection:(FR) and \"Breach Notification for Unsecured Protected Health Information\"","pageSize":"2","offsetMark":"*","sorts":[{"field":"publishdate","sortOrder":"ASC"}]}'
It returned a count of 1. The one result was a December 2022 Federal Register document on substance use disorder records, packageId FR-2022-12-02, granuleId 2022-25784, and not the 2009 rule whose title we typed. A search hit is a lead. Compare the packageId and the title with what you wanted, or use the link service below when you already hold the citation. GovInfo's search overview page describes pageSize ("Maximum is 1000"), the sort fields and the historical and resultLevel options.
Packages and granules: one document
The retrieval endpoints return a package, then its granules. We pulled the 2009 interim final rule on breach notification, which sits in the Federal Register issue of August 24, 2009. The package summary at /packages/FR-2009-08-24/summary returned, trimmed:
{"packageId": "FR-2009-08-24", "title": "Federal Register Volume 74 Issue 162 (August 24, 2009)",
"download": {"pdfLink": "https://api.govinfo.gov/packages/FR-2009-08-24/pdf", "xmlLink": "https://api.govinfo.gov/packages/FR-2009-08-24/xml", "modsLink": "...", "zipLink": "..."}}
The granule for the rule itself, /packages/FR-2009-08-24/granules/E9-20169/summary, returned its title ("Breach Notification for Unsecured Protected Health Information"), granuleClass: "RULE", rin: "0991-AB56" and links to the PDF and MODS metadata. For the same rule from the Federal Register's own API, with filters and paging, see Federal Register API in Python. For a granule worked through for a US Code section, see how to pull US Code sections programmatically.
The link service: a citation in, the official file out
The link service needs no key. You build a URL from a citation, and GovInfo redirects you to the official file. GovInfo's link-service repository documents the parameters. For the CFR they include titlenum, partnum, sectionnum, year (a four-digit year or mostrecent) and link-type, which defaults to pdf. The Developer Hub lists the collections it covers, including the CFR, the Federal Register, Public and Private Laws, the Statutes at Large and the US Code.
We ran each request below on 12 October 2026 and recorded the redirect:
| Request | Result |
|---|---|
/link/cfr/45/164?sectionnum=404&link-type=pdf | Redirect to CFR-2025-title45-vol2/pdf/CFR-2025-title45-vol2-sec164-404.pdf |
/link/cfr/45/164?sectionnum=404&link-type=xml | Redirect to the matching xml file |
/link/cfr/45/164?sectionnum=404&link-type=html | HTTP 400 |
/link/cfr/45/164?sectionnum=404&year=2024&link-type=pdf | Redirect to the 2024 edition |
/link/fr/74/42740 | Redirect to FR-2009-08-24/pdf/E9-20169.pdf#page=1 |
/link/plaw/111/public/148 | Redirect to PLAW-111publ148/pdf/PLAW-111publ148.pdf |
/link/statute/124/119 | Redirect to STATUTE-124/pdf/STATUTE-124-Pg119.pdf#page=1 |
/link/uscode/42/1983 | Redirect to the 2024 edition PDF |
/link/uscode/42/1983?link-type=html | Redirect to the 2024 edition HTML |
/link/uscode/42/1983?year=2023&link-type=pdf | Redirect to the 2023 edition |
/link/uscode/42/1983?year=2025 | HTTP 400 |
/link/uscode/42/1983?link-type=xml | HTTP 400 |
Three lessons sit in that table. First, "latest" means the latest edition GovInfo holds. On 12 October 2026 the newest US Code edition it served for 42 U.S.C. 1983 was 2024, and it refused a request for 2025. That is not the same as current law. For how the US Code and the CFR differ, see USC vs CFR. Second, the file types you can ask for depend on the collection: xml worked for the CFR section and failed for the US Code section, and html did the reverse. GovInfo's documentation says an invalid or unavailable link-type is an error. Third, a failed lookup is a web page. The 400 body is an HTML error page, so check the status code and not the body.
Here is a small Python function for that check. We ran it on 12 October 2026:
import requests
UA = {"User-Agent": "cite-linker (you@example.com)"}
def official_url(path, **params):
"""Turn a citation into the official file, or raise if GovInfo has none."""
r = requests.get("https://www.govinfo.gov/link/" + path, params=params,
headers=UA, allow_redirects=False, timeout=60)
if r.status_code != 302: # a failed lookup is an HTML page
raise ValueError(f"HTTP {r.status_code} for {path} {params}")
return r.headers["Location"]
cites = [
("cfr/45/164", {"sectionnum": 404}), # 45 CFR 164.404
("fr/74/42740", {}), # 74 FR 42740
("uscode/42/1983", {"link-type": "html"}), # 42 U.S.C. 1983
("uscode/42/1983", {"year": 2025}), # no such edition
]
for path, params in cites:
try:
print(official_url(path, **params))
except ValueError as err:
print("ERROR:", err)
https://www.govinfo.gov/content/pkg/CFR-2025-title45-vol2/pdf/CFR-2025-title45-vol2-sec164-404.pdf
https://www.govinfo.gov/content/pkg/FR-2009-08-24/pdf/E9-20169.pdf#page=1
https://www.govinfo.gov/content/pkg/USCODE-2024-title42/html/USCODE-2024-title42-chap21-subchapI-sec1983.htm
ERROR: HTTP 400 for uscode/42/1983 {'year': 2025}
For a section in the US Code with many amendments, our guide to CFR annual editions and point-in-time access shows why an edition and a date are different things. For how citations become exact sections, see legal citation resolution.
Bulk data: which collections, and which not
The bulk data page says GPO makes "select collections" available "in a machine-readable format (i.e. XML)". The top-level folders for some collections, such as the Federal Register and the CFR, also hold a Resources folder with the schema, stylesheet and user guide. We read the list on 12 October 2026. The dates in the table are GovInfo's own "last modified" values:
| Collection | Last modified (GMT) |
|---|---|
| Congressional Bills | 10-Oct-2026 |
| Bill Status | 10-Oct-2026 |
| Bill Summaries | 09-Oct-2026 |
| Code of Federal Regulations (Annual Edition) | 08-Oct-2026 |
| Electronic Code of Federal Regulations | 11-Oct-2026 |
| Federal Register | 10-Oct-2026 |
| Public and Private Laws (xml uslm beta) | 10-Oct-2026 |
| Statutes at Large (xml uslm beta) | 06-Oct-2026 |
| Statute Compilations (xml uslm beta) | 09-Oct-2026 |
We opened four of those folders. The Federal Register folder has one subfolder per year from 2000 to 2026, plus Resources. The eCFR folder has one per title. Public and Private Laws covers the 113th to 119th Congresses, and the Statutes at Large are listed by volume.
The list also has the US Government Manual, House Rules and Manual, Privacy Act Issuances, Public Papers of the Presidents, Commerce Business Daily and Supreme Court decisions from 1937 to 1975 (FLITE). There is no US Code entry, and https://www.govinfo.gov/bulkdata/USCODE returns HTTP 404. Our guide to pulling US Code sections covers where Code files come from. For court opinions, GovInfo staff said in January 2026, "We do not provide bulk datasets or dumps for USCOURTS materials," and pointed to the collections service as the way to track updates (usgpo/api issue 192).
The GovInfo MCP server
GovInfo's repository documents an MCP server, marked "Public Preview." The endpoint is https://api.govinfo.gov/mcp. A client sends the key in an x-api-key header, and the documentation lists two tools, searchGovInfo and describePackageOrGranule. It also warns that the data "will be interpreted by your chosen LLM, and typical LLM quality assurance is needed." An unauthenticated request to the endpoint on 12 October 2026 returned the same API_KEY_MISSING 401 as the API. We did not call the tools, because the demo key's allowance was spent, so we cannot say how they behave.
Which door to use
What the free source leaves to you
GovInfo gives you official documents, metadata and links. It does not turn "42 U.S.C. 1983" into a JSON record with the section text, or search state law, or tell you a section changed. Our comparison, GovInfo API vs a legal data API, covers what teams end up building on top. For the wider map of federal and state sources, see US Law Data: The Complete Guide and the compliance data sources guide.
What goes wrong
- Using
DEMO_KEYfor real work. The allowance is small, shared and daily. - Quoting 1,000 per hour as GovInfo's limit. That is the gateway default. Read your own headers.
- Using
offset. It is being deprecated. UseoffsetMark. - Reading
lastModifiedas a publication date. It is not one. - Taking "latest" in the link service as current law. It is the latest edition GovInfo holds.
- Treating a 400 as a lookup. Check the status code, not the page.
- Expecting a ZIP or MODS file on the first call. A 503 with
Retry-After: 30means it is being built. - Committing the key to a repository or an MCP config file.
FAQ
What is the GovInfo API?
It is a JSON API from the Government Publishing Office for finding GovInfo's packages and granules, getting their metadata and downloading the files. GovInfo describes the data as "official publications from all three branches of the Federal Government."
Do I need an API key for GovInfo?
You need one for the API, and you get it free from the sign-up page. The link service and the bulk data repository need no key. Without a key, the API returns HTTP 401 with API_KEY_MISSING.
What is the GovInfo API rate limit?
GovInfo's README gives 36,000 requests per hour, 1,200 per minute and 40 per second as the defaults. The api.data.gov manual's generic default is 1,000 per hour. Read the X-RateLimit-Limit header on your own key to see which applies.
What is DEMO_KEY, and why did it stop working?
It is the shared sample key used in documentation examples. It has a much lower limit than a personal key, counted per IP address. On 12 October 2026 it returned 429 until midnight GMT after a few calls.
How do I get a US Code section from GovInfo?
For a link to one section, use the link service, for example /link/uscode/42/1983. It returns the latest edition GovInfo holds, 2024 on 12 October 2026. For editions and metadata, use the USCODE collection through the API. GovInfo's bulk list has no US Code entry.
Does GovInfo have bulk data?
Yes, for select collections, including the Federal Register, the CFR, the eCFR, bills, Public and Private Laws and the Statutes at Large. GovInfo staff said in January 2026 that it provides no bulk dumps for court opinions in the USCOURTS collection.
Is there a GovInfo MCP server?
GovInfo documents one in public preview at https://api.govinfo.gov/mcp. It needs an API key, offers two tools, and carries a warning that your LLM interprets the results. We did not exercise its tools.
For the US statutes, regulations and court rules these laws sit in, see the US primary law API.
New legal AI guides, weekly.
Further Reading
Federal Register API in Python: Search Rules and Notices
Read postRegulations.gov API: Dockets, Documents and Comments Explained
Read postCompliance API: Two Meanings, and Where Regulatory Data Comes From
Read postOpen States API Guide: v3 Endpoints, Keys, Bulk Data, and Licensing
Read postLegiScan API Guide: Bills, Votes, Datasets, and Joining Them to Enacted Law
Read postCongress.gov API Guide: What It Covers and What It Doesn't
Read post
Co-Founder & CTO
Priyansh leads engineering and AI at Vaquill AI: the pipelines that pull statutes, regulations and court rules from every US jurisdiction's official publisher, and the REST API, MCP server and open dataset that serve them.