Issue Nº 53 — Nov 2, 2026

The World Bank API returns HTTP 200 when it has no data for you

Issue fifty-three covers the World Bank Indicators API in the Science & Math category. It needs no key and sends a wildcard CORS header. We queried version 2 of the API live on 2 November 2026. An empty result is a 200 with a null data element. A bad indicator is a 200 with a message array. A page size above 32,767 fails, and the failure was different each time we tried.

Three kinds of nothing

We sent GET https://api.worldbank.org/v2/country/XX/indicator/SP.POP.TOTL?format=json. The API returned HTTP 200. The body was [{"page":0,"pages":0,"per_page":0,"total":0,"sourceid":null,"lastupdated":null},null]. The second element is null, not an empty array. A request with date=2027 returned the same body. So did GET /country/PRK/indicator/SE.XPD.TOTL.GD.ZS?format=json&mrv=1.

GET /country/NZ/indicator/NOT.REAL?format=json also returned HTTP 200. Its body was a one-element array with a message key. The message id was 120 and the key was "Invalid value". This body has no meta object.

A per_page above 32,767 is the only case that gave us a real error. Even then, the result changed between probes. More detail is in the next section.

Your client must handle each case. Test for a null second element. Test for a message key in the first element. Set a timeout, and check the status code and content type before you parse.

The per_page limit is 32,767

We bisected the limit on GET /country/NZ/indicator/SP.POP.TOTL?format=json. A per_page of 32767 returned HTTP 200 with 13,228 bytes in 0.10 s. That is the largest signed 16-bit integer.

Above that number, we got three different results on the same day. One probe returned HTTP 400 with an XHTML page. In a later run, the server sent no bytes for 40 to 100 seconds. In our last run, per_page=32768 returned a Cloudflare 502 HTML page of 54,079 bytes. None of these bodies is JSON.

This series needs far less. New Zealand has 66 rows for this indicator, one for each year. A per_page of 100 returns all of them in one page. Keep per_page small and page through larger sets.

The meta object changes shape

In a data response, per_page is a number. GET /country/NZ/indicator/SP.POP.TOTL?format=json&per_page=2 returned per_page 2, pages 33 and total 66.

GET /country?format=json&per_page=1 returned per_page as the string "1". That meta object also has no sourceid and no lastupdated key. A typed client that expects one shape on every path will fail on one of them.

The data rows differ too. GET /country/CUB/indicator/SE.XPD.TOTL.GD.ZS?format=json&mrv=1 returned sourceid "2" and a unit key set to an empty string. The same path with mrnev=1 returned sourceid null and no unit key. With mrnev=3, sourceid was "2" again. Do not depend on either field.

mrv skips the empty years

The most recent years are often empty. GET /country/CUB/indicator/SE.XPD.TOTL.GD.ZS?format=json&per_page=4 returned rows for 2025, 2024 and 2023 with a value of null. The 2022 row held 8.44086351669284.

With mrv=1, the API returned only the 2022 row. With mrnev=3, it returned 2022, 2021 and 2020. Both parameters skipped the null years here. Use one of them to get the latest real figure.

If a country has no value at all, you get the null body from the first section.

/country mixes countries and aggregates

GET /country?format=json&per_page=400 returned a total of 296. Of those rows, 79 have a region id of NA and a region value of Aggregates. They are groups such as income levels and world regions. The other 217 are countries and territories.

Filter on region.id before you build a country list. A dropdown that skips this step will show aggregates next to countries.

To fetch several countries in one call, join the codes with a semicolon. GET /country/NZ;AU/indicator/SP.POP.TOTL?format=json&per_page=1 returned a total of 132, which is 66 rows for each country. Every response we probed carried access-control-allow-origin: *.

World Bank, by the numbers

Rendered live from the atlas entry
AuthenticationNone required
HTTPSSupported
CORSEnabled
PricingFree
FormatsJSON, XML
Key endpoints
  • GET/country?format=json
  • GET/country/all/indicator/{indicator}?format=json
economicsopen-datagovernment-datastatisticsdevelopment

Sources

Facts checked Nov 2026