Public search API
A free JSON API over an independent index of official government websites in the United States, Canada, and the United Kingdom, from national departments down to city councils. No key, no signup, CORS enabled.
Every endpoint is a GET request that returns JSON. Send no headers and no
credentials.
https://crawl.govglance.org
# Search for passport renewal pages
curl "https://crawl.govglance.org/api/v1/search?q=renew+passport&size=3"
The main endpoint. Full-text search across every indexed page, in all three countries unless you narrow it.
/api/v1/search| Parameter | Type | Description |
|---|---|---|
q | string required | Query text. Supports the operators below. Max 500 characters. |
page | integer | 1-indexed page number. Default 1. The result window is capped at 1000. |
size | integer | Results per page, 1–50. Default 10. |
country | string, repeatable | us, ca, uk. Defaults to all
of them. Comma-separated values work too
(country=us,ca), as do the ISO codes, where the United
Kingdom is gb. |
level | string, repeatable | Level of government. The values differ by country — see Countries. |
state | string, repeatable | Two-letter US state code, e.g. tx. |
domain | string, repeatable | Restrict to specific domains, e.g. irs.gov. |
filetype | string | pdf, html, doc, docx |
facets | boolean | Include aggregation counts. Default true; set false for lower latency. |
Results will appear here.
Operators go inside q and combine freely with the query parameters.
| Operator | Example | Effect |
|---|---|---|
site: | site:irs.gov tax forms | Restrict to one domain |
country: | country:uk council tax | Restrict to one country |
filetype: | budget filetype:pdf | Restrict by document type |
level: | level:city parking permit | Restrict by level of government |
state: | state:tx drivers license | Restrict by US state |
intitle: | intitle:budget | Require a term in the page title |
inurl: | inurl:forms | Require a term in the URL |
"…" | "notice of proposed rulemaking" | Exact phrase |
-term | permits -parking | Exclude a term |
Trimmed to one result for readability.
{
"query": "renew passport",
"total": 3255,
"total_is_lower_bound": false,
"page": 1,
"size": 10,
"results": [
{
"url": "https://travel.state.gov/…/renew.html",
"title": "Renew my <mark>Passport</mark>",
"snippet": "You can renew by mail if your …",
"domain": "state.gov",
"organization": "US Department of State",
"country": "US",
"level": "federal",
"state": null,
"language": "en",
"content_type": "text/html",
"published_at": null,
"last_crawled": "2026-08-05T14:21:56Z",
"word_count": 807,
"score": 317.2
}
],
"facets": {
"countries": [{ "value": "US", "count": 2911 }],
"levels": [{ "value": "federal", "count": 836 }],
"states": [{ "value": "DC", "count": 644 }],
"domains": [{ "value": "uscis.gov", "count": 279 }],
"types": [{ "value": "text/html", "count": 3067 }]
},
"took_ms": 77.3
}
title and snippet are already HTML-escaped and
may contain <mark> around matched terms. Insert them as HTML;
escaping them a second time renders the escaping itself, so
apply/renew comes out as apply/renew. Every other
field — url, domain, organization and the rest —
is raw text and must be escaped by you before it reaches the DOM. For plain text, strip
the <mark> tags and HTML-decode.
When total_is_lower_bound is true,
total is a floor rather than an exact count.
Autocomplete drawn from indexed page titles. Useful for search-as-you-type.
/api/v1/suggest| Parameter | Type | Description |
|---|---|---|
q | string required | Prefix, 2–100 characters. |
size | integer | 1–20. Default 8. |
curl "https://crawl.govglance.org/api/v1/suggest?q=medicare"
{ "query": "medicare", "suggestions": ["Medicare Costs", "Medicare Enrollment"] }
The countries in scope and the levels of government each one contributes. Build country and level pickers from this rather than hard-coding the lists, which change as the crawl grows.
/api/v1/countriesLevels are deliberately not forced into a shared vocabulary: a UK council is not a US county, and collapsing both into "local" would discard the distinction you are usually filtering on.
| Country | Accepts | Levels |
|---|---|---|
| United States | us |
federal, interstate, state,
county, city, tribal,
special_district, school_district |
| Canada | ca |
federal, provincial,
crown_corporation, municipal,
indigenous |
| United Kingdom | uk, gb |
national, parliamentary, judicial,
devolved, health, police,
local_authority, public_body |
public_body covers the several thousand
.gov.uk registrations that the published register lists by name
only. Recording them as public bodies is accurate; guessing whether each is a
department or a council would not be.
curl "https://crawl.govglance.org/api/v1/countries"
{
"default": "all countries",
"countries": [
{ "code": "US", "name": "United States", "aliases": [],
"levels": ["federal", "state", …], "domains": 13084, "pages_indexed": 2841003 }
]
}
Browse the government domains that make up the index.
/api/v1/domains| Parameter | Type | Description |
|---|---|---|
country | string, repeatable | us, ca, uk. Defaults to all. |
level | string | Filter by level of government. |
state | string | Two-letter US state code. |
search | string | Match against domain or organization name. |
limit | integer | 1–500. Default 100. |
offset | integer | For pagination. |
Index and crawl coverage. Recomputed in the background every five minutes.
/api/v1/statsindexed_pages and domains_total are exact.
The frontier totals under crawl are planner estimates, flagged by
counts_are_estimates, because an exact count of a table this size is far
too expensive to serve. Also useful: GET /health returns per-dependency
status and a 503 when search is unavailable.
| Status | Meaning |
|---|---|
400 | Invalid parameter — empty query, unknown country, level or state, or a page beyond the 1000-result window. |
429 | Rate limit exceeded. Includes a Retry-After header. |
503 | Search backend temporarily unavailable. Retry with backoff. |
Errors return {"detail": "…"}. The rate limit is applied per IP per minute.
Responses are cached briefly, so repeated identical queries are cheap and return
X-Cache: HIT. If you need a higher limit for research or public-interest work,
get in touch through govglance.org.