Documentation / Endpoints
Getting started
Reference
Endpoints
Data
Raw observations — one country, one indicator, one year, one value — as JSON or as a streaming CSV. This is the endpoint that costs credits, and the only one whose price varies.
/v1/data- Auth
- Bearer key required
- Cost
- max(1, ceil(rows / 100))
- Returns
- Observation rows, JSON or CSV
- Order
- iso3, then year
- Row cap
- 100,000 per request
- Paging
- None — narrow the query instead
Base https://api.worldgovdata.com/v1
No pagination, a hard row cap, and a price set by what actually came back. Read the two notes on the cap and on CSV before you build against it.
Parameters
Query parameters
| Parameter | Description |
|---|---|
indicatorstring · required | The indicator id. Exact and case-sensitive. Resolve it with /v1/indicators?q=…, which is free.example: wgi.control_of_corruption |
countriescomma-separated ISO3 | Restrict to these countries. Codes are trimmed and upper-cased for you, and empty entries are ignored, so a trailing comma is harmless. Omit it and you get every country that has the series — which is usually what trips the row cap.default: all countries · example: IND,CHN,USA |
frominteger year | Earliest year, inclusive.default: the start of the series · example: 2000 |
tointeger year | Latest year, inclusive.default: the end of the series · example: 2024 |
formatjson | csv | Response format. csv streams a five-column file with no envelope — and therefore no licence or attribution.default: json · example: csv |
indicator is the only required parameter. Everything else narrows the result, which is how you control both the row count and the cost.
JSON
Request
curl -sS "https://api.worldgovdata.com/v1/data?indicator=wgi.control_of_corruption&countries=IND,CHN,USA,DEU,JPN&from=2000&to=2024" \
-H "Authorization: Bearer $WGD_API_KEY"Response · 200
Row fields
| Field | Type | Notes |
|---|---|---|
| iso3 | string | ISO 3166-1 alpha-3 country code. |
| year | integer | The year the observation is for. |
| value | number | null | The measurement. Null where the provider published a row with no value. |
| ci_lo | number | null | Lower bound of the confidence interval, where the provider gives one. |
| ci_hi | number | null | Upper bound. Null for the many series that carry no interval. |
meta
indicator— echoed back.count— rows in this response. This is the number the credit charge was computed from, so you can always reconcile a bill against a response.licenceandattribution— the terms for this series. Carry them with the rows; see Licensing.fromandto— echoed only if you sent them.
CSV
format=csv streams rather than buffering, which usually matters more than the size of the response itself. The header row is fixed and the columns are in this order:
text/csv
- Sent as
text/csvwithContent-Disposition: attachment; filename="<indicator>.csv", so a browser downloads it rather than rendering it. - Nulls are empty fields, not the string
NULLand not0. Configure your reader accordingly — the trailing empty columns in the sample above are a series with no confidence interval. - Identical cost, identical row cap, identical ordering.
What it costs
The formula
- Charged on rows returned, not rows requested. A generous query that happens to match little is cheap.
- Every error costs 0 — including
too_many_rows, because the count runs before any data is read. - Each request rounds up independently, so many small requests cost slightly more than one large one. Credits works this through.
The row cap
A single request will not return more than 100,000 rows. Over that, the request is refused with the real count in the message, so you know exactly how far over you are.
too_many_rows · 400
There is no page 2. You narrow the query — fewer countries, or a shorter year range — and issue it again. Pagination has a complete chunking recipe that splits on countries first and years second, and halves adaptively if the estimate was wrong.
In practice the cap is generous: one indicator across every country and every year it holds is usually well under it. It bites on the deep-history series, some of which carry centuries.
Straight to a file
Download as CSV
curl -sS "https://api.worldgovdata.com/v1/data?indicator=wdi.gdp_per_capita_ppp&countries=IND,CHN,USA&from=2000&to=2024&format=csv" \
-H "Authorization: Bearer $WGD_API_KEY" \
-o gdp_per_capita.csvErrors
400 bad_request—indicatormissing. Thedetailsarray names it.400 bad_format—formatwas neitherjsonnorcsv. Case is normalised first, soCSVis accepted.400 bad_range—fromis greater thanto. Only checked when you send both.400 too_many_rows— over the cap. Costs nothing.401 unauthorized— no key.402 insufficient_credits— balance below the minimum. Nothing was served and nothing was charged.403 display_only— the indicator’s licence permits display but not export. Permanent, and not fixable by topping up.404 indicator_not_found— no such id, or a series we may not redistribute at all.
display_only · 403
An unknown country code is not an error. Codes that match nothing simply contribute no rows, so countries=IND,XXX returns India’s rows with a 200. If a response is smaller than you expected, check your codes against /v1/countries. A year range outside the series behaves the same way: an empty array, a count of 0 — and, because there is a minimum, one credit.
Notes and gotchas
- Ordering is stable. Always
iso3thenyear, ascending. There is no sort parameter, and none is needed — the result is deterministic. - No pagination, on purpose. Offsets over an unbounded observation table are slow and fragile; a bounded query with a hard cap is neither. Chunk on the axes the data has.
- Only the open tier is exportable. Rankings and country detail will serve you a display-tier value; this endpoint will not. That is the difference between displaying and redistributing.
- Cache it yourself. Because this route needs a key, the response comes back
private, no-store— it carries your balance, so no shared cache may hold it. Cache it inside your own application instead: the pipeline behind it runs daily at fastest, and a response you did not re-request costs no credit. - Prefer
latest_yeartoyr_max. A few series carry projection years. Boundingtowithcoverage.latest_yearkeeps forecasts out of a dataset that is meant to be observed. - Reconcile from
meta.count. It is exactly the number the charge was computed from, so a surprising bill is one division away from being explained.
Related
- /v1/rankings — if what you want is every country for one year, this is a flat 1 credit and arrives already ordered.
- Pagination — the full-panel chunking recipe.
- Credits — the cost formula, worked through.
- Licensing — what you owe the provider.