The World Bank API turns an indicator code and a country list into one typed row per country-year — NY.GDP.MKTP.CD for GDP in current US dollars, SP.POP.TOTL for population, FP.CPI.TOTL.ZG for inflation, and roughly 16,000 further series covering trade, energy, health, education and debt.
It is the standard source for macro data, and the usual reason to want it as an API is a join: GDP per head next to your sales-by-country table, population under a market-sizing model, inflation behind a pricing review. Rows land flat and numeric, ready to sit beside the output of the exchange rate API or the Yahoo Finance collector in the same warehouse — fetched keylessly over the TLS tier and billed at $0.0002 per delivered datapoint.
$0.0002 per delivered datapoint, up to 200 datapoints per run. Nothing delivered means nothing charged.
One POST names an indicator and up to 30 countries (ISO2 or ISO3 — IT and ITA both work), with optional year_from and year_to framing the window. The collector reads the Bank's Open Data API, flattens its envelope, and delivers one row per country per year, each carrying the indicator code and its human-readable name so exports stay self-describing.
The detail that matters is the null handling. The Bank's raw response contains a slot for every requested year even when it has no figure — small states, recent years, discontinued series. By default those empty years are skipped, so averages and charts are built only from real observations. Set include_empty and the null rows are delivered too, which is the mode you want when the gaps themselves are the finding.
indicator and countries are required. Aggregate codes pass straight through — WLD for the world, EUU for the European Union — so "global GDP since 2000" is one country entry, not a sum you compute. max_results runs 1–200 with a default of 50, a higher ceiling than most collectors because year-by-country grids multiply quickly.
value is the one numeric column and arrives unformatted — GDP in whole dollars, rates as percentages — while year comes back as a string exactly as the Bank publishes it. country_code is normalised to ISO3 on output whatever form you passed in, and indicator_name repeats the series label on every row, which feels redundant until the CSV is opened by someone who was not on the call.
$0.0002 per delivered datapoint ($0.20 per 1,000). Nothing delivered means nothing charged, and the $2 monthly free credit covers roughly 10,000 datapoints here. Volume tiers take up to 30% off.
$0.0002 per delivered datapoint — 20 cents per 1,000, the lowest unit price in the catalogue. GDP for all 27 EU members over two decades is 540 rows, about eleven cents; a 30-country, five-indicator development dashboard refreshed monthly stays well under a dollar a month. The no-card monthly allowance of $2 is exactly 10,000 datapoints at this price.
Years the Bank has no figure for are skipped by default and never charged — though if you opt into include_empty, the null rows you asked to keep are delivered rows like any other.
The Bank's Open Data API is free, keyless, generous, and the data itself is openly licensed — if your need is one series once, use it directly and send them a kind thought. The tax is the envelope. Responses arrive as a two-element array whose first element is pagination metadata; JSON must be requested explicitly or you get XML; date ranges use a colon syntax of their own; per-page defaults truncate silently at 50 records; and every missing year is a present-but-null entry you must filter before any aggregate is trustworthy.
The collector's contribution is boring on purpose: envelope, pagination, format flags and null policy handled once, with what reaches you in the same flat row shape as every other QuantumProxies collector, on the same key and the same per-delivered-row bill. For this source you are explicitly not paying for access — you are paying two hundredths of a cent per row to never think about the envelope again.
Python has open-source wrappers for this API, and they are fine — for a notebook. What breaks in production is everything around the wrapper:
Here the fetch, retries and normalisation live inside the per-row price. And when a project also needs sources genuinely hostile to automation, the same account's residential proxies and the rest of the collector catalogue are already wired to the key you are using.
Join SP.POP.TOTL and GDP onto revenue-by-country and every figure becomes comparable: sales per capita, penetration against market size, growth measured against the country's own trend rather than a global average.
Pull one telling indicator — internet penetration, urban population share, GDP growth — across all 30 candidate markets in a single run, rank the rows, and let the shortlist argue from data instead of familiarity.
An inflation chart built from delivered rows cites cleanly: indicator code, country, year, value, straight from the Bank. Re-running the same POST next quarter extends the series without touching the methodology section.
One run covers one indicator across up to 30 countries and delivers at most 200 datapoints; multi-indicator dashboards are one run per indicator, executed in parallel within your plan's rate limit. Most series are annual and published with a lag — figures for the newest year often arrive a year or more later — so the freshest data you want is frequently the very data the default null-skipping removes. That is the state of the source, not a defect of the pipe.
Coverage is uneven in known ways: small states and conflict economies have holes, discontinued series stop mid-decade, and some indicators exist only for aggregates. The underlying data is the World Bank's, published under an open licence (CC BY 4.0) — attributing the Bank in anything public is both required and good manners.
The Bank's own API is free and keyless, with openly licensed data. This collector charges $0.0002 per delivered datapoint for the flattened, normalised version — and the $2 monthly free allowance is exactly 10,000 datapoints, which covers a lot of macroeconomics before any payment exists.
Every series page on data.worldbank.org shows its code in the URL — NY.GDP.MKTP.CD for GDP, SP.POP.TOTL for population, FP.CPI.TOTL.ZG for CPI inflation. There are around 16,000 of them; locate the series on the site once, then hand its code to the collector.
Because the Bank has no figure for them. Empty years are skipped by default so they cannot poison averages; pass include_empty true and the null rows are delivered instead, which is the right mode when you are auditing coverage rather than charting values.
That is its natural home. One POST from requests, then a DataFrame over the delivered rows — country, year and numeric value are already flat, so there is no wrapper library to install and nothing to unpivot before a groupby.