API docs

Version 2026-10-24. Base URL https://birthrate.io/api/v1 — JSON over HTTPS, CORS enabled. The OpenAPI description is at /api/v1/openapi.json.

Try it

Live requests against the production API. Without a key you are on the Free tier.

Values of one indicator for any set of countries, regions, first-level divisions or cities, with per-series coverage, gaps, sources and licences.

curl "https://birthrate.io/api/v1/data"

Send a request to see the live response.

Authentication

Send your key in the X-API-Key header (or Authorization: Bearer …). Never put it in a URL or in browser code other people can see. Without a key, requests run on the Free tier: 10 a minute and 200 a day per IP address, no bulk downloads.

Pro keys are issued once, right after checkout. If a key leaks, call POST /api/v1/keys/rotate with it: every old key is revoked and a new one is returned. Lost your key entirely? Email us from the address you subscribed with.

Responses

Every successful response has the same two parts:

  • data — for time series, one entry per geography with observations (year, value, kind, source) and coverage (first and last year, count, and missingYears).
  • meta — the indicator and unit, the query as understood, availability (geographies requested with no data, values withheld for licence reasons), sources with licence and the attribution line to display, notes, the API version and a citation.

kind is estimate for historical values as the source published them — many international series (World Bank, UN) are themselves model-based estimates, not census counts — and projection for forecasts. Population projections from birthrate.io's own model are labelled modelled. Missing years are never filled in.

Geography ids are ISO 3166-1 alpha-3 for countries (JPN) and stable slugs for regions, first-level divisions and cities — list them with /api/v1/geographies.

Endpoints

  • GET/api/v1/data

    Values of one indicator for any set of countries, regions, first-level divisions or cities, with per-series coverage, gaps, sources and licences.

    • indicator (required) — Indicator slug from /api/v1/indicators.
    • level — Geographic level. One of: country, admin1, city, region.
    • id — Comma-separated identifiers: ISO3 for countries, slugs for other levels.
    • country — Filter admin1/city rows to these countries (ISO3), or restrict a country query.
    • continent — Countries on one continent, e.g. Europe.
    • incomeGroup — World Bank income group, e.g. High income.
    • from — First year (inclusive).
    • to — Last year (inclusive).
    • kind — Estimates, projections or both. One of: all, estimate, projection.
    • latest — Only the most recent estimate per geography. One of: false, true.
    • aggregates — Include World and regional aggregates in country queries. One of: false, true.
  • GET/api/v1/indicators

    Every indicator with unit, category, default source and coverage by level — including values withheld for licence reasons.

    • category — Filter by category.
  • GET/api/v1/geographies

    The identifiers to pass as id: ISO3 for countries, slugs for regions, admin1 divisions and cities.

    • level — Geographic level. One of: country, admin1, city, region.
    • country — Only divisions of these countries (ISO3).
  • GET/api/v1/projections

    Total population by projection scenario (UN World Population Prospects).

    • country (required) — ISO3 codes, comma-separated.
    • scenario — Scenario names, e.g. medium,low,high.
    • from — First year.
    • to — Last year.
  • GET/api/v1/population-by-age

    Five-year age groups by sex for one year (defaults to the latest available).

    • country (required) — ISO3 codes, comma-separated.
    • year — Year; omit for the latest.
  • GET/api/v1/sources

    Every source, its licence and attribution, and whether the API redistributes it.

  • GET/api/v1/bulk/{indicator}Pro

    Every redistributable value of one indicator, all levels and years, as CSV (or ?format=json).

    • indicator (required) — Indicator slug.
    • format — Output format. One of: csv, json.
  • GET/api/v1/usagekey required

    Your plan, this month's request count and quota, and your active keys.

  • POST/api/v1/keys/rotatekey required

    Revoke all keys on the account and return a new one (shown once).

  • POST/api/v1/billing/portalkey required

    A link to Stripe's billing portal: invoices, payment method, cancellation.

Limits

PlanRequestsPer minuteValues per requestBulk
Free200/day per IP101,000No
Pro100,000/month30050,000Yes
EnterpriseBy agreement1200200,000Yes

Responses carry X-RateLimit-Remaining and X-Quota-Remaining. Your usage is at /api/v1/usage.

Errors

Errors are JSON: { "error": { "code", "message", "docs" } }.

  • 400missing_parameter / bad_parameter — A required parameter is missing or malformed. The message says which.
  • 401invalid_key / key_required — The key is wrong or revoked, or the endpoint needs one.
  • 402subscription_inactive — The subscription behind the key is past due or cancelled.
  • 403plan_required — The endpoint (bulk) is not in your plan.
  • 404unknown_indicator — No indicator with that slug — see /api/v1/indicators.
  • 413too_many_rows — The query matches more values than one response allows; narrow it or use bulk.
  • 429rate_limited / quota_exceeded — Per-minute limit or monthly quota reached. Headers show what is left.
  • 503api_not_provisioned / billing_unavailable — A server-side feature is not switched on yet.

Billing

Pro is billed monthly by Stripe after a 14-day trial. For invoices, a new card or to cancel, call POST /api/v1/billing/portal with your key and open the returned link. Plans and prices: developers.