Gov APIdiscovery.nationalarchives.gov.uk ↗
Search and browse The National Archives Discovery catalogue via API. Access archival records, creators, repository info, and catalogue hierarchy metadata.
What is the Gov API?
The National Archives Discovery API exposes 7 endpoints for searching and navigating the UK National Archives catalogue, which holds millions of archival records spanning centuries of British government and public history. Use search_records to query records by keyword, date range, and holding repository, or get_record_details to retrieve structured metadata including reference codes, closure status, catalogue level, scope descriptions, and administrative background for a specific catalogue item.
curl -X GET 'https://api.parse.bot/scraper/4987305c-bd8a-4973-9efd-fc7f6bc25118/search_records?query=world+war&held_by=The+National+Archives%2C+Kew&end_year=1945&page_size=5&start_year=1939' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace discovery-nationalarchives-gov-uk-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: National Archives Discovery API — search, browse, and explore archival records."""
from parse_apis.the_national_archives_discovery_api import NationalArchives, RecordNotFound
client = NationalArchives()
# Search for records about "world war" — limit caps total items fetched.
for record in client.recordsummaries.search(query="world war", limit=5):
print(record.title, "|", record.reference, "|", record.date)
# Drill into one result's full details via the summary→detail navigation op.
summary = client.recordsummaries.search(query="Churchill", limit=1).first()
if summary:
detail = summary.details()
print(detail.title, detail.reference, detail.catalogue_level, detail.closure_status)
# Fetch a known record directly by ID.
try:
admiralty = client.recorddetails.get(id="C4")
print(admiralty.title, admiralty.date, admiralty.held_by)
except RecordNotFound as exc:
print(f"Record not found: {exc}")
# Browse the catalogue hierarchy from a known parent.
entry = client.catalogueentry(id="C4")
for child in entry.browse(limit=3):
print(child.title, "|", child.reference, "|", child.is_parent)
print("exercised: recordsummaries.search / summary.details / recorddetails.get / catalogueentry.browse")
Search for archival records in the Discovery catalogue. Returns results matching the query keyword, with optional date range and repository filters. Results are returned in relevance order.
| Param | Type | Description |
|---|---|---|
| queryrequired | string | Search keyword or phrase (e.g. 'world war', 'Churchill', 'navy') |
| held_by | string | Filter by holding repository name (e.g. 'The National Archives, Kew') |
| end_year | string | Filter results to records covering dates up to this year. Four-digit year (e.g. '1945'). |
| page_size | integer | Number of results to return per request |
| start_year | string | Filter results to records covering dates from this year onwards. Four-digit year (e.g. '1939'). |
{
"type": "object",
"fields": {
"results": "array of record objects each containing id, title, reference, date, description, held_by, and context",
"total_count": "integer total number of matching records across the catalogue"
},
"sample": {
"data": {
"results": [
{
"id": "C7394009",
"date": "1914 June-July",
"title": "Department IA: World War I: World War I Files",
"context": "German Foreign Ministry Archives: Photostat Copies.",
"held_by": "The National Archives, Kew",
"reference": "GFM 33/2280/5273",
"description": "Department IA: World War I: World War I Files."
}
],
"total_count": 9140468
},
"status": "success"
}
}About the Gov API
Search and Record Retrieval
The search_records endpoint accepts a required query string and optional filters including start_year, end_year, and held_by to narrow results by date range or repository. Each result object includes id, title, reference (the citable archival reference code such as ADM 1/1234), date, description, held_by, and context. The total_count field in the response indicates the full number of matching records across the catalogue, enabling pagination via page_size.
Record Detail and Catalogue Structure
get_record_details takes a catalogue ID (typically C followed by digits, e.g. C3478849) and returns comprehensive metadata: catalogue_level to identify where the record sits in the hierarchy (1 = departmental level, higher numbers indicate deeper items), parent_id for traversal, closure_status indicating access restrictions, description for scope and content, and administrative_background describing the history of the creating body. The browse_catalogue endpoint accepts a reference parameter to navigate the hierarchy directly, returning child items and the parent_reference.
Creators and Archives
search_creators and get_creator_details cover persons, families, organisations, and manors as record creators. get_creator_details returns the creator's name, date, and associated collections. browse_creators allows filtering by type (Person, Family, CorporateBody, or Manor). browse_archives lists contributing repositories alphabetically via the letter parameter, returning repository items and the current letter cursor.
The Gov API is a managed, monitored endpoint for discovery.nationalarchives.gov.uk — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when discovery.nationalarchives.gov.uk changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official discovery.nationalarchives.gov.uk API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Building a genealogy research tool that queries
search_recordsby surname and date range to surface relevant archival holdings - Mapping catalogue hierarchy depth using
catalogue_levelandparent_idfields fromget_record_details - Identifying which repositories hold records on a specific topic using the
held_byfilter insearch_records - Indexing record creators and their associated collections via
search_creatorsandget_creator_details - Generating citable references for historical research by extracting the
referencefield from record detail responses - Browsing contributing archives A–Z using
browse_archivesto discover lesser-known holding institutions - Filtering for open-access records by checking the
closure_statusfield returned byget_record_details
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does The National Archives have an official developer API?+
What does `catalogue_level` mean in the `get_record_details` response?+
parent_id alongside this field to traverse up the tree.Does the API return the full text content of digitised documents?+
Can I retrieve records held by archives other than The National Archives at Kew?+
held_by parameter in search_records accepts repository names to filter to a specific institution, and browse_archives lists all contributing repositories alphabetically.Is there a way to get a list of all records within a specific department or series?+
browse_catalogue endpoint accepts a reference parameter and returns immediate child items along with parent_reference, enabling level-by-level traversal. It does not return a flat list of all descendants in a single call. You can fork this API on Parse and revise it to add recursive or bulk-traversal endpoints if your use case requires deep subtree enumeration.