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 dataset for one area:
curl "https://statsmapped.com/ireland/api/v1/geographies/county%3Akerry/datasets/psra_median_price_kerry"
# Every area at one boundary level:
curl "https://statsmapped.com/ireland/api/v1/geographies?level=county"
# 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
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.
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.
MCP
MCP lets an AI agent (Claude
Desktop, Cursor, others) call this data directly as tool calls instead of
parsing web pages. A thin client package exists (statsmapped-mcp)
that calls this same public API over stdio -- not yet published to PyPI, so
for now it's a source install: see the package's own
README
for the exact steps.