Skip to content
worldgovdata
Sign in
Documentation / Core concepts

Core concepts

Credits

One number, spent only when rows of data come back. Browsing the catalogue, reading metadata and checking freshness are free — so working out what to buy never costs anything.

One credit is one row. Credits are whole numbers, they do not expire, and there is no subscription.

What a credit is

A credit is a unit of data delivered, not a unit of time or of requests. The rule for the one variable endpoint is:

/v1/data

cost = max(1, rows_returned)

Every other billable route is a flat 1. Everything else is 0. There is no ratio and no division: the number of credits a request costs is the number of lines in the body you got back. Three consequences worth holding on to:

  • You are billed for what arrived, not for what you asked for. A query matching 40 rows costs 40 credits whether you scoped it tightly or got lucky, and a query that matches nothing costs the floor of 1.
  • Errors are free. Credits are debited after a successful response exists and its row count is known. A 4xx or 5xx costs nothing — including too_many_rows, which is decided by a count before any data is read.
  • How you slice it does not change the bill. Nothing rounds, so one request of 1,200 rows and twelve of 100 cost the same 1,200 credits. Chunk for the row cap and for your own retry story, not for the price.

New accounts receive 2,000 credits — 2,000 rows — at email verification, not at signup. After that you top up by amount, whenever you like; nothing renews and no card is stored.

What a credit costs

Flat, and only flat. Credits cost the same whether you buy a hundred rupees’ worth or a hundred thousand: no tiers, no volume discount, and nothing to compare on a pricing table. You type an amount, that amount is charged, and it buys the credits below.

What money buys, per currency
CurrencyBuy in steps ofCredits per stepMost in one purchase
INR₹100100,000₹500,000 · 500,000,000 credits
USD$1100,000$5,000 · 500,000,000 credits

Purchases are whole multiples of the step — ₹100 or $1 — and the step is also the minimum. The ceiling is a fat-finger guard rather than a policy: if you genuinely mean to spend more than that in one go, get in touch and we will sort it out. Amounts and balances are integers end to end, so what you are charged, what lands on the balance and what the invoice says are the same three numbers.

Buying is on your billing page; the pricing page carries the same figures for anyone without an account yet. Credits do not expire, nothing auto-renews, and no card is stored — every purchase is a one-off you start yourself.

The full cost table

Credit cost of every public API route
RouteCreditsWhat it returns
GET /v1/countriesfreeThe country spine.
GET /v1/countries/{iso3}1One country with every latest value it has.
GET /v1/indicatorsfreeThe catalogue. Search, filter, sort, page.
GET /v1/indicators/{id}freeOne indicator plus its related set.
GET /v1/topicsfreeThe 13-topic taxonomy with counts.
GET /v1/meta/freshnessfreePer-provider licence, cadence, last successful load.
GET /v1/meta/coveragefreePer-country observation and indicator counts.
GET /v1/rankings/{indicator}1Every country ranked on one indicator, one year.
GET /v1/datamax(1, rows)Raw observations, JSON or CSV. The only variable price.
GET /v1/usagefreeYour own balance and recent usage.
GET /v1/pingfreeKey liveness: key id, scopes, balance.

Three worked examples

A five-country time series

GDP per capita for India, China, the United States, Germany and Japan, 2000 to 2024.

GET /v1/data?indicator=wdi.gdp_per_capita_ppp&countries=IND,CHN,USA,DEU,JPN&from=2000&to=2024
  • 5 countries × 25 years = 125 rows
  • max(1, 125) = 125 credits
  • 125 credits = ₹0.125 at ₹1 = 1,000 credits

Total125 credits

A world map for one year

The latest control-of-corruption ranking for every country, to colour a choropleth.

GET /v1/rankings/wgi.control_of_corruption
  • Rankings are a flat price: 1 credit
  • 213 rows returned — the row count does not enter into it
  • Finding the indicator id first, via /v1/indicators?q=corruption, is free

Total1 credit

A full panel, chunked

One indicator for all 218 countries over 60 years — about 13,000 rows, fetched 25 countries at a time.

GET /v1/data?indicator=…&countries=<25 codes> ×9
  • 218 countries ÷ 25 per chunk = 9 requests
  • ≈1,450 rows per chunk = 1,450 credits each
  • 9 × 1,450 = 13,050 credits
  • One unchunked request of the same 13,050 rows costs 13,050 too — how you slice it makes no difference to the price

Total13,050 credits (₹13.05)

Estimating before you spend

You never have to guess. Two free moves tell you the size of a pull in advance.

Read the coverage block

Every indicator record carries coverage: how many countries hold it and the span of years. Multiply. /v1/indicators/{id} is free.

Upper bound

"coverage": { "n_countries": 213, "yr_min": 2000, "yr_max": 2024, "latest_year": 2024 }

213 countries × 25 years = 5,325 rows  →  5,325 credits  →  ₹5.33

That is an upper bound, not a figure: coverage is rarely complete, so the real row count is usually lower and so is the real cost. Estimating is now the same arithmetic as counting, which is the practical reason the unit changed — a row budget and a credit budget are one number.

Probe with one country

One country buys you an exact answer. Pull it, read meta.count, and multiply by how many countries you actually want. The probe costs its own row count — typically a few dozen credits — which is the cheapest possible way to stop guessing.

One-country probe

# Size the job before committing to it: ask for one country, read meta.count,
# multiply. The probe itself costs one credit per row it returns.
curl -sS "https://api.worldgovdata.com/v1/data?indicator=wdi.gdp_per_capita_ppp&countries=IND" \
  -H "Authorization: Bearer $WGD_API_KEY" | jq '.meta.count'

Reading the credit headers

Every metered response tells you what it cost and what is left. There is no reason to poll a balance endpoint on a schedule — the answer is already attached to the work you are doing.

Credit headers on every metered response
HeaderExampleMeaning
X-Credits-Charged125Credits this request cost — on /v1/data, the number of rows in the body. Always sent on a metered call, including when it is 0.
X-Credits-Remaining97558Your balance after the charge. Watch this instead of polling /v1/usage.

Response headers · 200

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private, no-store
X-Request-Id: 0f3a91c4e2b7
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 594
X-RateLimit-Reset: 1785315600
X-Credits-Charged: 125
X-Credits-Remaining: 97558
  • Both headers are absent on a request that was never metered — an anonymous call to a free route, for instance.
  • X-Credits-Charged: 0 on a 4xx or 5xx is a promise, not a rounding: failed requests genuinely cost nothing.
  • Log X-Credits-Remaining from your batch jobs and alert on it falling below a day of headroom. It is the cheapest budget monitor available and it is free.

When you run out

We never serve on credit. If your balance is below what a request needs, it is refused before the query runs — so an over-budget request costs nothing and leaves nothing half-done.

Insufficient credits · 402

HTTP/1.1 402 Payment Required

{
  "error": {
    "code": "insufficient_credits",
    "message": "This request needs 1 credit and your balance is 0.",
    "required": 1,
    "balance": 0,
    "top_up_url": "https://worldgovdata.com/account/billing"
  }
}

The body is deliberately actionable. required is what this request needed, balance is what you hold, and top_up_url is where to fix it. A client that gets a bare 402 can only guess whether it is one credit short or a hundred thousand.

Handling it

  • Do not retry. A 402 is not transient; retrying is the one response guaranteed not to help. Stop the loop.
  • Record where you stopped. In a chunked pull, keep the index of the last chunk that succeeded. Credits are debited per request, so everything before the 402 was delivered and paid for — resume there rather than starting over.
  • Surface it as a budget event. This is not an outage and not a bug. Alert whoever owns the account, not whoever is on call.
  • Then retry the identical request. Once topped up, the same URL returns the same rows. Nothing about the request needs to change.

What credits are not

  • Not a licence. Credits buy delivery, not rights. An indicator whose licence forbids redistribution returns 403 display_only at any balance. See Licensing.
  • Not a rate limit. The two ceilings are independent: a full balance does not raise your requests-per-minute, and hitting a 429 does not cost you anything. See Rate limits.
  • Not perishable. Credits do not expire, do not reset monthly and are not use-it-or-lose-it.
  • Not charged to the portal. Browsing worldgovdata.com in a browser never touches your balance. Only calls you make with your own key do.