Irish public data, by county
StatsMapped

A free, unauthenticated JSON API for every figure StatsMapped publishes, for Ireland and the UK — how to call it, what it returns, and its rate limits.

Why the caveats matter

Every figure carries the publisher's own caveats. Where a statistic is published for a wider area than the one you clicked, or where the publisher itself flags it as unreliable, the page says so rather than quietly rounding it off.

Browse tender awards →

Live tender opportunities →

Rankings →

County in motion →

StatsMapped's data API

Every figure on this site is also available as JSON, free and unauthenticated — the same underlying data the pages themselves render from, not a separate or delayed copy. The one exception is tender_awards' supplier filter, which needs a registered key; see its own access page. Everything else below needs nothing but a URL.

Try it

# Every area's own latest figure for one stat, in one call (pass a
# stat_key from /api/v1/stats below) — the same cross-section every
# ranking page on the site is built from (Ireland):
curl "https://statsmapped.com/ireland/api/v1/series?stat_key=sale_price"

# Same call, UK:
curl "https://statsmapped.com/united-kingdom/api/v1/series?stat_key=sale_price"

# Every dataset for one area (Ireland):
curl "https://statsmapped.com/ireland/api/v1/geographies/county%3Akerry/datasets/psra_median_price_kerry"

# Every dataset for one area (UK):
curl "https://statsmapped.com/united-kingdom/api/v1/geographies/uk%3Alad%3Ae08000003/datasets/uk_rppi_e08000003"

# Every area at one boundary level (Ireland's own primary level is "county"):
curl "https://statsmapped.com/ireland/api/v1/geographies?level=county"

# Same call, UK (its own primary level is "lad" — local authority district):
curl "https://statsmapped.com/united-kingdom/api/v1/geographies?level=lad"

# The full catalogue of what's tracked:
curl "https://statsmapped.com/api/v1/stats"

Full reference, every route and field: /openapi.json (machine-readable) or /docs (interactive, browser-only -- it runs entirely in JavaScript, so a plain curl or crawler fetch of that URL itself returns an empty shell, not documentation text).

Two ways in, same routes

Nearly every route exists both bare (/api/v1/..., this process's own default country) and country-prefixed (/{ireland,united-kingdom}/api/v1/..., explicit regardless of which country happens to be default). Both forms return identical data for the same country — the prefixed form is the one to use if you ever call more than one country, since it never depends on which one this server happens to be defaulting to today. Exceptions: /api/v1/tender_awards, /api/v1/tender_awards/access-requests, /api/v1/tender_awards/summary, /api/v1/planning_applications, /api/v1/receipts/{receipt_id} and /api/v1/stats/ntpf_op/wait_share_rollup exist only in the bare form today, with no country-prefixed twin yet — checked against the live route table on 15 Oct 2026 (the first three since 15 Sep; the other three were added after), not assumed from an older finding.

A third form exists too — don't copy it from devtools

Opening this site's own network tab shows a THIRD form for some routes -- no /v1/ at all (e.g. /api/series, not /api/v1/series). These are undocumented internal aliases this site's own front end calls, not a third real way in: they carry no version guarantee, may change or disappear without notice, and are deliberately left out of this schema (include_in_schema=False) for exactly that reason. Always use the /api/v1/... form above, bare or country-prefixed — copying a URL straight from devtools risks copying one of these instead.

Errors

Every non-2xx response is {"error": {"status": <code>, "message": "..."}} — one shape, whether it's a 404, a 422 validation error, or a 429. No route here ever returns FastAPI's bare {"detail": "..."} default.

Rate limits

600 requests per 1 hour, per IP, on every read-only route (tender_awards search and its access-request endpoint have their own separate, narrower limits — see its own page). Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (a Unix timestamp); past the limit, a 429 adds Retry-After in seconds. Generous deliberately — this bounds scripted abuse, not legitimate use; this site's own front end calls these same routes on every page load and has never been close to it.

Versioning

Everything here is v1. No route has changed shape since first publishing, and none will without a new version path (/api/v2/...) — an existing integration is never broken by a future change to this API.

Concretely: adding a new field to an existing response is not a breaking change — an integration should tolerate fields it doesn't recognise. Removing, renaming, or narrowing what an existing field means gets a new version path, and the old path keeps working for a transition period. When that first happens we will announce it on this page with the date the old path stops being served, and send a Deprecation header on the old path. Nothing on this API is deprecated today. A change to what gets redacted or shown on an authorized tender_awards call (the field's meaning, not its shape) is announced on its own access page rather than here.

MCP

MCP lets an AI agent (Claude Desktop, Cursor, others) call this data directly as tool calls instead of parsing web pages. A hosted endpoint is live at https://mcp.statsmapped.com/mcp (Streamable HTTP) — no install needed for a client that speaks it directly. A thin client package is also published on PyPI for running over stdio instead, calling this same public API: pip install statsmapped-mcp.

Metadata for agents

An Open Knowledge Format bundle describing every metric, dataset, caveat and comparability verdict is served at /okf/ (the bundle root is /okf/; its links are relative to that root). Ireland only for now.