Documentation / Endpoints
Getting started
Reference
Endpoints
Endpoint reference
Eleven routes, all GET, all under one base URL. Six of them have a page of their own; the two account-facing utilities are documented here.
Base URL
An anonymous response
Every route
| Route | Credits | Key | Returns |
|---|---|---|---|
| GET /v1/countries | free | optional | The country spine. |
| GET /v1/countries/{iso3} | 1 | required | One country with every latest value it has. |
| GET /v1/indicators | free | optional | The catalogue. Search, filter, sort, page. |
| GET /v1/indicators/{id} | free | optional | One indicator plus its related set. |
| GET /v1/topics | free | optional | The 13-topic taxonomy with counts. |
| GET /v1/meta/freshness | free | optional | Per-provider licence, cadence, last successful load. |
| GET /v1/meta/coverage | free | optional | Per-country observation and indicator counts. |
| GET /v1/rankings/{indicator} | 1 | required | Every country ranked on one indicator, one year. |
| GET /v1/data | max(1, ceil(rows / 100)) | required | Raw observations, JSON or CSV. The only variable price. |
| GET /v1/usage | free | required | Your own balance and recent usage. |
| GET /v1/ping | free | required | Key liveness: key id, scopes, balance. |
optional means the route answers without credentials, rate-limited by IP at the anonymous tier. Sending a key costs nothing and raises those limits. required means no key, no answer: 401 unauthorized.
Reference pages
The two account routes
Both are free, and both need a key — they are about your account, so they have to know whose it is. Neither has a reference page of its own because neither takes a parameter.
GET /v1/ping
The liveness check for a deployment. It confirms the key resolved and reports the key id, the scopes it carries, your rate-limit tier and your balance. It costs nothing and touches no data — the balance comes from the key resolution that already happened — so it is the right thing to call at boot to fail fast on a bad credential.
Request
Response · 200
tier is anonymous, free or paid — the same three tiers on Rate limits. Seeing anonymous on a key you just made means the account has not verified its email address yet.
A 401 invalid_key means the credential was read and rejected — unknown, malformed, revoked, expired or closed account, all one code on purpose. A 401 unauthorized means you sent nothing at all.
GET /v1/usage
Your own balance and recent usage, for the key making the call. Free, and the one way to watch your own burn rate from a script without a browser session.
Response · 200
days— the only parameter. An integer from 1 to 90, defaulting to 30. Today counts as one of them, sodays=1means today. The window actually used is echoed inmeta.days.credits— the wallet: currentbalancepluslifetime_grantedandlifetime_spent.totals— the window folded into one row, summed from the same series returned below it, so the headline and the chart cannot disagree.daily— dense: every day in the window appears, oldest first, zero-filled where nothing happened. Plot it without gap-filling.endpoints— per-route totals, busiest first, and deliberately not zero-filled. Routes you have never called are absent rather than listed at zero.
Endpoints are reported as route templates — /v1/rankings/{indicator}, never the path you actually called. Raw paths carry query strings and query strings carry intent, which is not something worth retaining.
Behaviour every route shares
- GET only. The public API is read-only. Anything else returns
405 method_not_allowed. - Two-key envelope. Success is
{ "data": …, "meta": … }; failure replaces the body with{ "error": { "code", "message" } }.meta.generated_atis always present. - meta echoes your filters, and omits anything you did not send. An absent key means “not applied”, never “null”.
- The licence gate applies everywhere. An indicator we may not redistribute is not listed, not ranked and not retrievable — it does not exist as far as the API is concerned. See Licensing.
- Caching depends on who asked. An anonymous GET returns
public, max-age=3600, s-maxage=21600; an authenticated one returnsprivate, no-store; any error returnsno-store. Cache in your own application regardless — a response you did not re-request costs no credit and no quota. - Per-caller headers only on authenticated calls. X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-Credits-Charged, X-Credits-Remaining are withheld from anonymous responses, precisely because those are the ones a shared cache may keep.
X-Request-Idis on everything. - Nulls are real.
value,ci_lo,ci_hi,rankand most coverage fields are nullable. A missing measurement is a null, not a zero and not an absent row.
Identifier conventions
- Countries are ISO 3166-1 alpha-3:
IND,CHN,USA. Case is normalised for you, so/v1/countries/indand/v1/countries/INDare the same request. In a comma-separated list, whitespace around a code is trimmed. - Indicators are
provider.slug—wgi.control_of_corruption,wdi.gdp_per_capita_ppp. These are case-sensitive and exact; there is no fuzzy resolution. Find one with/v1/indicators?q=…, which is free. - Years are four-digit integers.
fromandtoon/v1/dataare both inclusive. - Topics are lowercase slugs —
governance,economy,health. Ask /v1/topics rather than hardcoding the list.