API and agents
API
The read-only REST API: authentication, endpoints, rate limits, attribution and errors.
The Cadastre API is a read-only JSON API over the datasets, measures and metro figures described in these docs, with the same screening and ranking the app uses. It is in beta and free while it is. The public datasets need no account: call it with no credential at all, at 30 requests a minute. Sign in (an API key or an approved app) for higher limits.
Base URL
https://getcadastre.com/api/v1The API is version 1. The OpenAPI 3.1 description is public at https://getcadastre.com/api/v1/openapi.json.
Without an account
Every endpoint except /me answers a request with no credential:
curl "https://getcadastre.com/api/v1/metros?q=austin"It serves the same datasets as a signed-in request (the public datasets whose terms allow the API), with the same attribution, at 30 requests a minute and 2,000 a day for each network address. Use is governed by the Terms of Service either way; by using the API you agree to them.
Authentication
For higher limits, send one credential in the Authorization header, as a bearer token:
curl -H "Authorization: Bearer $CADASTRE_API_KEY" https://getcadastre.com/api/v1/meA credential that is not valid (unknown, revoked or expired) is always answered 401, never served as if there were none, so a client learns its key is bad.
- API keys, for your own scripts and servers. Make one in Settings under API keys (you are asked for your password). A key starts
cad_key_and is shown once: copy it then. It acts as you, in the account you were working in when you made it. Revoke it in the same place. - OAuth 2.1, for apps and AI agents that sign in on your behalf: an MCP client, or the Cadastre CLI. The app opens your browser, you sign in to Cadastre, choose the account and approve; the app receives an access token (
cad_at_, one hour) and refreshes it itself. Clients register themselves (dynamic client registration) and use the authorization code flow with PKCE (S256). Discovery starts at the authorization server metadata, https://getcadastre.com/.well-known/oauth-authorization-server, and the API's protected resource metadata, https://getcadastre.com/.well-known/oauth-protected-resource/api/v1. See Connect an AI agent for client setup.
Either credential has the one scope there is, read. Read Cadastre's datasets, measures and metro figures, and run screens and rankings over them. It cannot see or change your projects, account or settings. It works only while you are a member of that account and have accepted the current Terms of Service.
API access is turned on per account, and is what gives a credential its higher limits. A new account does not have it: write to support@getcadastre.com to ask for it (it may become part of a paid plan later). Until it is on, Settings makes no keys for the account and the consent page will not connect an app to it; a key or app the account already has gets what a request without a credential gets (the same data, the per-address limits). GET /me says which: its access.tier is api (the account's limits) or public (the per-address limits).
Disconnect an app in Settings under Authorized apps.
Never put a key in a query string, a web page or a shared file; anything holding it can act as you.
Endpoints
All paths are under the base URL. Lists are paged with page (from 1) and per_page (up to 500, default 100); the answer's meta carries total and total_pages.
Account
GET /me
Who the credential acts as. Needs a credential; without one it is 401 with the sign-in challenge.
GET /openapi.json
This description. Public: no credential needed.
Datasets
GET /datasets
The datasets the API serves.
GET /datasets/{key}
One dataset, with its measures.
| Parameter | In | Type | Description |
|---|---|---|---|
key (required) | path | string | A dataset key, as GET /datasets lists them |
Measures
GET /measures
Search the measures.
| Parameter | In | Type | Description |
|---|---|---|---|
q | query | string | Text in the name, label or unit |
geography | query | msa, county, state | Only measures with values at this geography |
dataset | query | string | Only this dataset's measures (its key) |
page | query | integer | Page number, from 1 |
per_page | query | integer | Items per page, up to 500 (default 100) |
GET /measures/{name}
One measure.
| Parameter | In | Type | Description |
|---|---|---|---|
name (required) | path | string | A measure name, as GET /measures lists them |
GET /measures/{name}/values
A measure's value for every region of a geography.
| Parameter | In | Type | Description |
|---|---|---|---|
name (required) | path | string | A measure name, as GET /measures lists them |
geography | query | msa, county, state | The geography to list; needed (a request without it is a 400) |
state | query | string | USPS code: metros partly in it, its counties, or the state |
page | query | integer | Page number, from 1 |
per_page | query | integer | Items per page, up to 500 (default 100) |
Metros
GET /metros
The metropolitan statistical areas.
| Parameter | In | Type | Description |
|---|---|---|---|
state | query | string | USPS code |
q | query | string | Text in the name |
page | query | integer | Page number, from 1 |
per_page | query | integer | Items per page, up to 500 (default 100) |
GET /metros/compare
Metros side by side.
| Parameter | In | Type | Description |
|---|---|---|---|
ids (required) | query | string | Up to 25 metro ids, CBSA codes or slugs, comma-separated |
measures | query | string | Up to 50 measure names, comma-separated (default: the register's standard figures) |
GET /metros/{ref}
A metro's profile. Every measure the API serves that the metro has a value for. ref is the metro's id, its five-digit CBSA code or its slug (percent-encode the slug's slashes, us%2Ftx%2Faustin-12420).
| Parameter | In | Type | Description |
|---|---|---|---|
ref (required) | path | string | The metro's id, CBSA code or slug |
Analysis
POST /screen
Screen the metros by scope and Requirements (read-only).
The body is JSON, a ScreenRequest (fields below, under Screening and ranking).
POST /rank
Rank the metros on weighted criteria (read-only).
The body is JSON, a RankRequest (fields below, under Screening and ranking).
Incentives
GET /incentive_programs
Incentive programs federal, state and local governments offer (paid). Programs read from the jurisdictions' official pages and reviewed by Cadastre, each value with the sentence it was quoted from (evidence) and the page (source_url); a field the page does not state is null (unknown). A program is what a jurisdiction offers: not an award, an amount anyone received, or a finding that a site qualifies. A jurisdiction with no programs listed is not covered yet. Only records from pages whose terms allow reuse are served. Part of API access: an account without it is answered 403 api_access_required.
| Parameter | In | Type | Description |
|---|---|---|---|
state | query | string | USPS code or state FIPS: federal programs, the state's and its local governments' |
metro | query | string | CBSA code, region id or slug: federal programs, the metro's states' and its local governments' |
mechanism | query | tax_credit, grant, loan, loan_guarantee, abatement, exemption, training_grant, infrastructure, financing_bond, zone_designation, other | Only programs of this kind |
page | query | integer | Page number, from 1 |
per_page | query | integer | Items per page, up to 200 (default 50) |
Examples
# The datasets the API serves
curl -H "Authorization: Bearer $CADASTRE_API_KEY" https://getcadastre.com/api/v1/datasets
# Search the measures
curl -H "Authorization: Bearer $CADASTRE_API_KEY" "https://getcadastre.com/api/v1/measures?q=unemployment&geography=msa"
# A metro's profile, by its CBSA code (Huntsville, AL)
curl -H "Authorization: Bearer $CADASTRE_API_KEY" https://getcadastre.com/api/v1/metros/26620
# Three metros side by side on the standard figures
curl -H "Authorization: Bearer $CADASTRE_API_KEY" "https://getcadastre.com/api/v1/metros/compare?ids=26620,48620,46140"Screen and rank are POSTs with a JSON body. They compute an answer and save nothing:
curl -X POST https://getcadastre.com/api/v1/screen \
-H "Authorization: Bearer $CADASTRE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"requirements": {"tier": "500k", "min_mfg_share": 8, "max_unemployment": 5.5}}'
curl -X POST https://getcadastre.com/api/v1/rank \
-H "Authorization: Bearer $CADASTRE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"requirements": {"tier": "500k"}, "criteria": [{"measure": "unemployment_rate", "direction": "lower_better", "weight": 2}]}'Measure names (unemployment_rate above) come from GET /measures.
Screening and ranking
POST /screen applies a scope and the app's Requirements to the metros and answers with the funnel (how many metros each Requirement leaves) and the metros that pass. POST /rank adds weighted criteria and answers with ranks, composite scores and each criterion's value, score and contribution. The same inputs give the same answer as a project in the app.
Requirements
| Field | Type | Meaning |
|---|---|---|
tier | 1m, 500k, 250k | Minimum population |
min_mfg_share | number | Manufacturing share of GDP, percent, at least |
max_unemployment | number | Unemployment rate, percent, at most |
min_growth | number | Five-year population growth, percent, at least |
max_hazard | number | FEMA National Risk Index, at most |
max_elec_price | number | Industrial electricity price, cents per kWh, at most |
rtw_only | boolean | Only metros entirely in right-to-work states |
Criteria
| Field | Type | Meaning |
|---|---|---|
measure | string | A measure name from GET /measures |
direction | higher_better, lower_better | Which way scores better |
weight | number | Default 1; 0 keeps the criterion as a gate only |
cutoff | object | Eliminates the metros it holds for. |
scope.states limits either to the metros partly in the listed states (USPS codes). A Requirement or criterion that reads a measure the API does not serve is a 422.
Responses and attribution
A successful answer is JSON: { "data": ..., "meta": ..., "attribution": [...] }. attribution lists, once each, the credit every dataset behind data requires: the publisher's credit, the licence and its link, and any notices, disclaimers and conditions the publisher attaches.
- Show the attribution with the figures, wherever they go: an analysis, a report, a deck, an app, an AI agent's answer. The Rights and attribution page explains each source's requirements, and the Terms of Service make it a condition of using the API.
- Cite
retrieved_at. Each attribution entry carriesretrieved_at, when Cadastre last retrieved that data from its publisher. Give it with the data (the Bureau of Labor Statistics asks API users to cite the retrieval date). - Label Cadastre's computed values. A value marked
computed_by_cadastreis Cadastre's figure (for example a metro total built from county figures), andcalculationsays how. Credit it as "Source: Cadastre, computed from" the publisher's data, not as the publisher's own figure.
Only datasets whose terms Cadastre has approved for the API are served; any other is absent from every list and a 404. Sources restricted in the app (see Rights and attribution) are never served.
Not served
- No geometry. Answers carry names and codes (region ids, CBSA codes, FIPS), never boundaries, points or lines. Geometry is not available yet; if it is added it will be an explicit option, never a default.
- No parcel data. The launch is metro-level; parcels are not in the API.
- No listings. Cadastre does not carry property listings.
Rate limits
- Without a credential, 30 requests a minute and 2,000 a day for each network address (an IPv6 /64), the API and the MCP server together. A key or app of an account without API access counts here too.
- With a credential of an account with API access, 60 requests a minute and 10,000 a day for each API key, and for each app you approved (across its token refreshes).
- 50,000 requests a day for each account, over all its keys and apps, so more keys do not add up to more requests.
Every answer carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds). Over a limit the answer is 429 with Retry-After: wait that many seconds; without an account, the message says how to sign in for more. These are the beta limits and may change.
Caching
The data GETs (datasets, measures, metros) carry an ETag and Last-Modified. Send If-None-Match with the ETag you have and an unchanged answer is a 304 with no body, which still counts as a request. The data changes when Cadastre imports a new release, not by the minute. An answer to a request without a credential is the same for everyone, so it is Cache-Control: public, max-age=60 (with Vary: Authorization): a cache may keep it for a minute. An answer to a credential is private and revalidated every time.
Errors
An error is JSON: { "error": "<code>", "message": "<sentence>" }.
| Status | error | What to do |
|---|---|---|
| 400 | bad_request | A malformed parameter or body. The message names it. |
| 401 | unauthorized, invalid_token | A credential that is unknown, revoked or expired, or whose person left the account, or not sent as a bearer token; or none at all on /me. Fix or drop the credential (with none, the public datasets are served). The WWW-Authenticate header names the protected resource metadata, so an OAuth client can sign in again. |
| 403 | terms_required | The Terms of Service were updated. Sign in to Cadastre in a browser and accept them; the key or app works again at once. |
| 403 | insufficient_scope | The credential lacks the read scope. Sign in again or make a new key. |
| 404 | not_found | No such dataset, measure or metro, or one the API does not serve. |
| 415 | unsupported_media_type | Send the POST body as application/json. |
| 422 | invalid_request, unknown_measure | Well formed but cannot be answered: an unknown measure, or a Requirement whose source the API does not serve. |
| 429 | rate_limited | Over a rate limit. Wait for Retry-After seconds, or sign in for higher limits. |
| 503 | unavailable | The API is not available on this server. Try again later. |
Versioning and beta
The version is in the path (/api/v1). During the beta Cadastre may add, change or remove endpoints, fields, datasets and limits, and will try to give notice of a change that breaks existing use; adding a field or a dataset is not a breaking change, so read answers tolerantly. There is no service level during the beta. See the Terms of Service.
AI agents and the MCP server
An AI agent can use the API directly, with or without a key, or connect to Cadastre's remote MCP server, which offers the same data as tools, with no sign-in or signed in with OAuth in the browser for higher limits. See MCP server and the agent guides.