Macroeconomy & country statistics

Realtime queries across the country-level denominator layer, thirteen blocks: World Bank WDI (globally comparable development indicators — GDP / population / poverty lines, where the indicator code is the only name), Eurostat (official EU-27 statistics, the JSON-stat grid decoded into rows), the ECB euro reference rate (the official daily benchmark for converting EUR-denominated amounts), FRED (US time series), WHO xMart (health-statistics denominators — coverage / mortality), UN Comtrade (the bilateral trade mirror: reporter × partner × commodity × flow), Eurostat Comext (the EU's extra-EU HS2-4-6 trade mirror — the denominator under "Germany imported X EUR of HS85 from China"), ILOSTAT (labour-market denominators), IMF SDMX (WEO outlook / GDD debt / CPI prices, at full precision), OECD SDMX (the Economic Outlook / national-accounts dataflow family, series keys validated against the structure first), BIS (70 years of central-bank policy rates / sectoral debt-service ratios / USD exchange rates), UN SDG (the 17-goal × 251-indicator sustainable-development database) and World Bank IDS (the 577-code DT.* external-debt catalog). The subject here is the country, not the company — this domain emits no company fact and stays out of the company master; it answers "how big is this economy, what is it worth, how do you convert the money". All commands run locally on your machine with no credentials: no platform-side quota, each upstream's own limits apply, and repeats within a cache lifetime are served from your local cache without hitting it.

Commands at a glance

Every direct-lookup face in this domain — each has its own section below (one-line positioning / parameters / a real example / boundaries).

Command Jurisdiction What it answers
economy bis_sdmx_series GLOBAL BIS statistics series (policy rates / debt-service ratios / USD rates)
economy bls_series US US BLS series observations (CPI-U / unemployment / nonfarm payrolls; 25 series x 10-year window)
economy comext_flows EU EU extra-EU HS trade mirror (reporter × partner × product × year)
economy ecb_fx_rates EU Official ECB euro reference rate (1 EUR = X)
economy eurostat_table EU EU official statistics (table × dimension cells)
economy fred_series US US Federal Reserve series (GDP / inflation / rates)
economy ilo_stat_indicator GLOBAL ILO labour statistics (employment / wages, one country per call)
economy imf_sdmx_series GLOBAL IMF macro series (WEO outlook / GDD debt / CPI prices)
economy oecd_sdmx_series GLOBAL OECD macro dataflows (Economic Outlook / national accounts, structure-validated series keys)
economy un_comtrade_trade GLOBAL Bilateral trade mirror (reporter × partner × commodity × flow)
economy unsd_sdg_indicators GLOBAL UN SDG indicator catalog (17 goals × 251 indicators × series codes)
economy unsd_sdg_series GLOBAL UN SDG series observations (goal × geography × year)
economy wb_countries GLOBAL World Bank country reference (ISO3 × income band)
economy wb_ids_indicators GLOBAL World Bank debt-statistics catalog (577 DT.* debt codes)
economy wb_wdi_indicators GLOBAL World Bank indicator catalog (WDI codes)
economy wb_wdi_values GLOBAL World Bank indicator values (country × year × code)
economy who_xmart_indicators GLOBAL WHO indicator catalog (with the values entity set)
economy who_xmart_values GLOBAL WHO indicator observations (indicator × M49 geography × year)

Realtime queries

The examples below are real command output, excerpts only, unmodified. Queries are realtime — running a command returns whatever the official source holds at that moment, so figures shift as upstreams update.

The examples below omit the leading executable name — prepend agentdata (or python -m agentdata ) for a full command.

economy bis_sdmx_series

BIS statistics series (policy rates / debt-service ratios / USD rates)

Parameters:

Flag Required Meaning
--flow yes BIS dataflow id (WS_CBPOL policy rates / WS_DSR debt-service ratios / WS_XRU USD exchange rates)
--key yes SDMX series key, at least two dot-separated segments (the segment order is flow-specific: M.US for WS_CBPOL, Q.US.N for WS_DSR, M.CN.CNY.E for WS_XRU) — a one-segment key is every area at once and is refused locally
--start no Period window start (upstream startPeriod)
--end no Period window end (upstream endPeriod)

**Note:**The key needs at least two segments (a dot-separated SDMX series key) — one segment (say just M) is every country's full history at once, refused locally; the segment order is flow-specific: WS_CBPOL M.US, WS_DSR Q.US.N (US non-financial corporations' debt-service ratio), WS_XRU M.CN.CNY.E (USD per CNY, REF_AREA = the currency's home country); a wrong key answers 404 with an SDMX error — not-found, not a block.

$ economy bis_sdmx_series --flow WS_CBPOL --key M.US --start 2026-01-01
{
  "reason": "BLS series CUUR0000SA0, LNS14000000, CES0000000001 — 99 observations, latest ~3 years (default window); first CES0000000001 2024-M01 = 157032.0",
  "result": {
    "series": ["CUUR0000SA0", "LNS14000000", "CES0000000001"],
    "total": 99, "count": 99,
    "rows": [
      { "series": "CES0000000001", "year": 2024, "period": "M01", "period_name": "January",
        "value": 157032.0, "latest": false, "footnotes": [] },
      { "series": "CES0000000001", "year": 2024, "period": "M02", "period_name": "February",
        "value": 157238.0, "latest": false, "footnotes": [] },
      { "series": "LNS14000000", "year": 2024, "period": "M01", "period_name": "January",
        "value": 3.7, "latest": false, "footnotes": [] },
      { "series": "LNS14000000", "year": 2026, "period": "M08", "period_name": "August",
        "value": 4.1, "latest": false, "footnotes": [] },
      { "series": "LNS14000000", "year": 2026, "period": "M09", "period_name": "September",
        "value": 4.2, "latest": true, "footnotes": [] },
      { "series": "CUUR0000SA0", "year": 2024, "period": "M01", "period_name": "January",
        "value": 308.417, "latest": false, "footnotes": [] },
      { "series": "CUUR0000SA0", "year": 2026, "period": "M08", "period_name": "August",
        "value": 334.98, "latest": false, "footnotes": [] },
      { "series": "CUUR0000SA0", "year": 2026, "period": "M09", "period_name": "September",
        "value": 336.94, "latest": true, "footnotes": [] },
      { "series": "CES0000000001", "year": 2026, "period": "M08", "period_name": "August",
        "value": 159015.0, "latest": false, "footnotes": ["P=preliminary"] },
      { "series": "CES0000000001", "year": 2026, "period": "M09", "period_name": "September",
        "value": 159044.0, "latest": true, "footnotes": ["P=preliminary"] }
    ],
    "series_without_data": [],
    "messages": []
  },
  "evidence": [
    { "quote": "CES0000000001 2024-M01 (January) = 157032.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M02 (February) = 157238.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M03 (March) = 157466.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M04 (April) = 157530.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M05 (May) = 157608.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" }
  ],
  "source": { "provider": "bls", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T08:17:17.357Z" }
}

**Reading it:**One row = one period observation; dims follows the dataflow's dimension order (WS_CBPOL carries two, WS_DSR three, WS_XRU four) and title is the official series name (self-describing unit and basis). Rows run oldest-first, so the "latest" in reason is the last row. WS_CBPOL holds 70 years of monthly policy rates back to 1954-07 — omit --start and you pull the whole history. 24-hour TTL.

economy bls_series

US BLS series observations (CPI-U / unemployment / nonfarm payrolls; 25 series x 10-year window)

Parameters:

Flag Required Meaning
--series yes BLS series id(s), comma-separated, ≤ 25 (official codes: CUUR0000SA0 = CPI-U, LNS14000000 = unemployment rate, CES0000000001 = nonfarm payrolls; lower case normalizes locally)
--start-year no Window start year (upstream startyear; travels with --end-year; omitting both = the latest ~3 calendar years)
--end-year no Window end year (upstream endyear; travels with --start-year; ≤ 10-year window — wider windows are refused locally: the upstream clamp keeps the earliest ten years)

**Note:**A window wider than 10 years is refused locally — the upstream does not error, it silently clamps endyear to startyear+9 and KEEPS THE EARLIEST ten years (pinned: a 2010..2026 ask answered 2010..2019, startyear-anchored, one message line "Year range has been reduced...") — a caller wanting recent data would silently lose it, so the face refuses before the wire with the evidence; --start-year/--end-year travel together (one alone = usage_error; half-window behavior is unpinned upstream and never shipped); a bogus id is not an error (200/REQUEST_SUCCEEDED + a message line "Invalid Series for Series X" + the id still in Results.series with empty data) — the face lists it under series_without_data and raises upstream_not_found only when every id is explicitly invalid; catalog/calculations/annualaverage/aspects are key-gated options (catalog:true on the keyless tier answers "The catalog has been disabled") and are never sent; the id vocabulary is upper-case letters + digits (signature doc; lower case normalizes locally, anything else is refused).

$ economy bls_series --series CUUR0000SA0,LNS14000000,CES0000000001
{
  "reason": "BLS series CUUR0000SA0, LNS14000000, CES0000000001 — 99 observations, latest ~3 years (default window); first CES0000000001 2024-M01 = 157032.0",
  "result": {
    "series": ["CUUR0000SA0", "LNS14000000", "CES0000000001"],
    "total": 99, "count": 99,
    "rows": [
      { "series": "CES0000000001", "year": 2024, "period": "M01", "period_name": "January",
        "value": 157032.0, "latest": false, "footnotes": [] },
      { "series": "CES0000000001", "year": 2024, "period": "M02", "period_name": "February",
        "value": 157190.0, "latest": false, "footnotes": [] },
      { "series": "CES0000000001", "year": 2024, "period": "M03", "period_name": "March",
        "value": 157512.0, "latest": false, "footnotes": [] },
      { "series": "LNS14000000", "year": 2026, "period": "M07", "period_name": "July",
        "value": 4.3, "latest": false, "footnotes": [] },
      { "series": "LNS14000000", "year": 2026, "period": "M08", "period_name": "August",
        "value": 4.3, "latest": false, "footnotes": [] },
      { "series": "LNS14000000", "year": 2026, "period": "M09", "period_name": "September",
        "value": 4.2, "latest": true, "footnotes": [] },
      { "series": "CUUR0000SA0", "year": 2026, "period": "M07", "period_name": "July",
        "value": 325.865, "latest": false, "footnotes": [] },
      { "series": "CUUR0000SA0", "year": 2026, "period": "M08", "period_name": "August",
        "value": 326.699, "latest": false, "footnotes": [] },
      { "series": "CUUR0000SA0", "year": 2026, "period": "M09", "period_name": "September",
        "value": 328.143, "latest": true, "footnotes": [] }
    ],
    "series_without_data": [],
    "messages": []
  },
  "evidence": [
    { "quote": "CES0000000001 2024-M01 (January) = 157032.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M02 (February) = 157190.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M03 (March) = 157512.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M04 (April) = 157876.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" },
    { "quote": "CES0000000001 2024-M05 (May) = 157961.0",
      "url": "https://api.bls.gov/publicAPI/v2/timeseries/data/" }
  ],
  "source": { "provider": "bls", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T08:17:17.357Z" }
}

**Reading it:**One row = one series × year × period observation (long-form rows); the upstream value is a string ("336.940") — the SDK converts to float, and . / empty = a null gap, never fabricated; latest marks the newest observation (true); footnotes travel compact (P=preliminary); the upstream ships newest-first, the SDK sorts ascending (series, year, period) for time-series reading. Omitting the years answers the latest ~3 calendar years (pinned: 2024..2026, 33 obs per series). Keyless tier: 25 series × 10 years × 500 queries/day. 12-hour TTL.

economy comext_flows

EU extra-EU HS trade mirror (reporter × partner × product × year)

Parameters:

Flag Required Meaning
--reporter no Reporter geo code (repeatable, e.g. DE; the aggregates EU / EU27_2020 / EA / EA21 live alongside country codes)
--partner no Partner geo code (repeatable, e.g. CN, WLD = the World)
--product no HS 2/4/6 product code (repeatable; 85 = electrical machinery) — a wrong shape answers zero cells silently; check dimensions.product.codes
--flow no Trade flow (repeatable: 1 imports / 2 exports) — omit it and each direction returns a row
--indicators no Value measure (default VALUE_EUR in euros; also QUANTITY_IN_100KG)
--time no Year filter (repeatable, e.g. 2024)
--since no Time-axis start (upstream sinceTimePeriod)
--until no Time-axis end (upstream untilTimePeriod) — at least one filter dimension is required; the filterless call is an upstream 413

**Note:**The root carries the dedicated comext/ segment — the plain Eurostat root 404s the ds- datasets (this face ships the correct root); zero filters are refused locally — the bare mirror is 31.3 billion cells, an upstream 413 "Full extraction forbidden" with a 5-million-cell single-query cap (this face adds a 500,000-cell local cap on top); several values must be repeated (--reporter DE --reporter FR) — the + form gets a 400 and the comma form silently yields zero cells; the product code is HS 2/4/6 (85 = electrical machinery) and a wrong shape answers zero cells silently — check against dimensions.product.codes; reporter aggregates (EU / EU27_2020 / EA / EA21) live alongside the country codes.

$ economy comext_flows --reporter DE --partner CN --product 85 --time 2024
{
  "reason": "Comext annual HS mirror — 2 cells of 4 in the grid, top freq=A, reporter=DE, partner=CN, product=85, flow=1, indicators=VALUE_EUR, time=2024 = 29698131086 (updated 2026-10-16T11:00:00+0200)",
  "result": {
    "rows": [
      { "freq": "A", "reporter": "DE", "partner": "CN", "product": "85", "flow": "1", "indicators": "VALUE_EUR", "time": "2024", "value": 29698131086 },
      { "freq": "A", "reporter": "DE", "partner": "CN", "product": "85", "flow": "2", "indicators": "VALUE_EUR", "time": "2024", "value": 18614843580 }
    ],
    "total": 4,
    "count": 2,
    "label": "International trade of EU and non-EU countries since 2002 by HS2-4-6",
    "updated": "2026-10-16T11:00:00+0200"
  },
  "evidence": [
    { "quote": "freq=A, reporter=DE, partner=CN, product=85, flow=1, indicators=VALUE_EUR, time=2024 = 29698131086",
      "url": "https://ec.europa.eu/eurostat/api/comext/dissemination/statistics/1.0/data/ds-059341" },
    { "quote": "freq=A, reporter=DE, partner=CN, product=85, flow=2, indicators=VALUE_EUR, time=2024 = 18614843580",
      "url": "https://ec.europa.eu/eurostat/api/comext/dissemination/statistics/1.0/data/ds-059341" }
  ],
  "source": { "provider": "comext", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T04:24:56.061Z" }
}

**Reading it:**One row = one (reporter × partner × product × flow × year) cell; value is in euros (indicators defaults to VALUE_EUR, with QUANTITY_IN_100KG as the alternative); flow is the string 1 / 2 (imports / exports) — leave --flow out and each direction gets a row; total counts the whole grid (4 cells here — the freq dimension carries M, but monthly cells stay empty on the annual mirror, so 2 are populated); updated is the upstream refresh stamp (the annual mirror rolls roughly monthly). Rows come out of the JSON-stat grid with the last dimension varying fastest. 24-hour TTL.

economy ecb_fx_rates

Official ECB euro reference rate (1 EUR = X)

Parameters:

Flag Required Meaning
--currency yes ISO 4217 three-letter currency code (USD / JPY / GBP) — the series key is EXR.D.{CCY}.EUR.SP00.A
--start no Window start (upstream startPeriod); give at least one of --start / --end, otherwise the full history (~8,000 rows)
--end no Window end (upstream endPeriod)

**Note:**The historical CSV (eurofxref-hist.csv) is a 2010 zombie snapshot and is not used; the SDMX endpoint negotiates on the Accept header first and only then looks at the format parameter — the default Accept: application/json makes format=csvdata ineffective and answers 200 with an SDMX-JSON envelope (not the csvdata contract), so this face sends Accept: text/csv explicitly; give at least one of --start / --end (neither one pulls the whole history, ~8,000 rows).

$ economy ecb_fx_rates --currency USD --start 2026-10-01 --end 2026-10-31
{
  "reason": "ECB reference rate USD/EUR — 22 daily observations 2026-10-01→2026-10-31, latest 2026-10-30 = 1.1172",
  "result": {
    "rows": [
      { "currency": "USD", "base_currency": "EUR", "rate_type": "SP00", "variation": "A",
        "date": "2026-10-01", "rate": 1.1298, "status": "A", "title": "US dollar/Euro ECB reference exchange rate" },
      { "currency": "USD", "base_currency": "EUR", "rate_type": "SP00", "variation": "A",
        "date": "2026-10-30", "rate": 1.1172, "status": "A", "title": "US dollar/Euro ECB reference exchange rate" }
    ],
    "total": 22,
    "count": 22,
    "unit": "USD per 1 EUR (ECB reference rate)"
  },
  "evidence": [
    { "quote": "2026-10-01: 1 EUR = 1.1298 USD",
      "url": "https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html" }
  ],
  "source": { "provider": "ecb", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:47:51.394Z" }
}

**Reading it:**The rate reads as "1 EUR = X units of that currency" — not the other way round; rows run oldest-first, so the "latest" in reason is the last observation in the window (published once per working day, so weekends have no rows). The currency and base currency travel with every row — the rate never travels without its date. 12-hour TTL.

economy eurostat_table

EU official statistics (table × dimension cells)

Parameters:

Flag Required Meaning
--table yes Table code (e.g. tec00001 / demo_pjan / nama_10_a64)
--geo no Geography filter (repeatable, e.g. DE) — several values must be repeated; the comma form silently yields zero cells
--time no Time filter (repeatable, e.g. 2023)
--dim no Other dimension filters as k=v (repeatable, e.g. unit=CP_MEUR, nace_r2=TOTAL) — leave them out and you get the whole grid
--since no Time-axis start (upstream sinceTimePeriod)
--until no Time-axis end (upstream untilTimePeriod)
--lang no Upstream language (default EN)

**Note:**Several values must be repeated (--geo DE --geo FR) — the + form gets an upstream 400 and the comma form silently yields zero cells (a near-miss); a geo outside the table yields zero cells and no error (a legitimate empty ≠ an error); leave --dim out and you get the whole grid (nama_10_a64 with --geo DE --time 2023 measured 17,664 cells, 8,341 of them populated, 1.87 MB), and this face walls the count at 500,000 cells locally.

$ economy eurostat_table --table nama_10_a64 --geo DE --time 2023 --dim unit=CP_MEUR --dim nace_r2=TOTAL
{
  "reason": "Eurostat Gross value added and income by detailed industry (NACE Rev.2 ) — 8 cells (table holds 8), updated 2026-10-29T23:00:00+0100, dims freq (1 code), unit (1 code), nace_r2 (1 code), na_item (8 codes), top DE 2023 freq=A unit=CP_MEUR nace_r2=TOTAL na_item=B1G = 3888686.0",
  "result": {
    "rows": [
      { "freq": "A", "unit": "CP_MEUR", "nace_r2": "TOTAL", "na_item": "B1G", "geo": "DE", "time": "2023", "value": 3888686.0, "status": "p" },
      { "freq": "A", "unit": "CP_MEUR", "nace_r2": "TOTAL", "na_item": "D29X39", "geo": "DE", "time": "2023", "value": -13324.0, "status": "p" }
    ],
    "total": 8,
    "count": 8,
    "label": "Gross value added and income by detailed industry (NACE Rev.2 )",
    "updated": "2026-10-29T23:00:00+0100"
  },
  "evidence": [
    { "quote": "freq=A unit=CP_MEUR nace_r2=TOTAL na_item=B1G geo=DE time=2023 status=p = 3888686.0",
      "url": "https://ec.europa.eu/eurostat/databrowser/view/nama_10_a64/default/table?lang=en" }
  ],
  "source": { "provider": "eurostat", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:48:02.634Z" }
}

**Reading it:**One row = one cell: {dimension: code, value, status} — status carries the cell flag (p provisional / e estimated / b break in series); dimensions gives each dimension's code list (codes + labels). The JSON-stat grid is decoded row-major with the last dimension varying fastest, so when you stitch cells across tables, match the dimension codes first and time second. 12-hour TTL.

economy fred_series

US Federal Reserve series (GDP / inflation / rates)

Parameters:

Flag Required Meaning
--series yes Series id, one per call (GDP / CPIAUCSL / DGS10) — several ids answer a ZIP upstream
--start no Observation window start (upstream cosd)
--end no Observation window end (upstream coed)

**Note:**One series id per call — several ids answer a ZIP archive (the binary wall: the JSON channel cannot carry binary), so this face refuses locally; --start / --end are the upstream cosd / coed; the CSV export publishes no quota, so the politeness tier is 1 rps.

$ economy fred_series --series GDP --start 2024-01-01 --end 2026-11-01
{
  "reason": "FRED GDP — 11 observations, first 2024-01-01, latest 2026-07-01 = 33010.036",
  "result": {
    "rows": [
      { "date": "2024-01-01", "series": "GDP", "value": 28793.191 },
      { "date": "2026-07-01", "series": "GDP", "value": 33010.036 }
    ],
    "total": 11,
    "count": 11
  },
  "evidence": [
    { "quote": "2024-01-01: 28793.191 (GDP)", "url": "https://fred.stlouisfed.org/series/GDP" }
  ],
  "source": { "provider": "fred", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:47:56.356Z" }
}

Reading it:value is the observation, and a missing observation is null (never zero-filled); rows run oldest-first, so the "first / latest" in reason are the two ends of the window. An unknown series id answers an HTML error page (200), which this layer reads as not-found by the header's magic number. 12-hour TTL.

economy ilo_stat_indicator

ILO labour statistics (employment / wages, one country per call)

Parameters:

Flag Required Meaning
--indicator yes ILOSTAT indicator code (e.g. EMP_TEMP_SEX_ECO_NB_A)
--ref-area yes Country ISO-3 code (e.g. USA) — required, the world-wide answer is orders of magnitude bigger
--time-from no Year lower bound (upstream timefrom)
--time-until no Year upper bound (upstream timeto — the upstream does not know timeuntil)
--sex no Sex dimension filter (upstream sex)
--classif no Classification dimension filter (upstream classif1, e.g. ECO_SECTOR_TOTAL)
--source no Source filter (upstream source)

**Note:**The upstream's year upper bound is timeto — timeuntil is accepted and silently ignored (the answer then runs all the way to the newest year), so this face maps --time-until onto timeto (--time-from 2020 --time-until 2024 measured 510 rows, 2020–2024); --ref-area is required (the world-wide answer is orders of magnitude bigger); the curl stack on this host answers an empty 200 while the urllib channel is the working one.

$ economy ilo_stat_indicator --indicator EMP_TEMP_SEX_ECO_NB_A --ref-area USA --time-from 2020 --time-until 2024
{
  "reason": "ILOSTAT EMP_TEMP_SEX_ECO_NB_A × USA — 510 observations 2020→2024, latest 2024 SEX_T ECO_SECTOR_TOTAL = 161345.53",
  "result": {
    "rows": [
      { "ref_area": "USA", "indicator": "EMP_TEMP_SEX_ECO_NB", "source": "BA:453", "sex": "SEX_T",
        "classif1": "ECO_SECTOR_TOTAL", "time": "2024", "obs_value": 161345.53, "obs_status": null },
      { "ref_area": "USA", "indicator": "EMP_TEMP_SEX_ECO_NB", "source": "BA:453", "sex": "SEX_F",
        "classif1": "ECO_ISIC4_U", "time": "2020", "obs_value": 186.411, "obs_status": "B" }
    ],
    "total": 510,
    "count": 510
  },
  "evidence": [
    { "quote": "2024 SEX_T ECO_SECTOR_TOTAL = 161345.53",
      "url": "https://rshiny.ilo.org/dataexplorer50/?lang=en&id=EMP_TEMP_SEX_ECO_NB_A" }
  ],
  "source": { "provider": "ilo_stat", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:48:13.715Z" }
}

**Reading it:**One row = one observation: year × sex × industry classification; rows run newest year first, so the "latest" in reason is the first row (it names the sex and classification codes). obs_status is the observation status and an I11:… inside note_indicator is an upstream footnote id. 24-hour TTL.

economy imf_sdmx_series

IMF macro series (WEO outlook / GDD debt / CPI prices)

Parameters:

Flag Required Meaning
--flow yes IMF dataflow id (WEO World Economic Outlook / GDD Global Debt / CPI prices)
--country yes Country code (ISO-3 in WEO/GDD, e.g. USA) — required together with --indicator; a country-only key is the multi-megabyte wall
--indicator yes Indicator code (e.g. NGDP_RPCH = real GDP growth) — the key shape is COUNTRY.INDICATOR\[.FREQUENCY\], fitting the WEO/GDD/CPI family (UNFCCC's dimension order differs; do not use it there)
--frequency no Optional trailing key dimension (e.g. A)
--start no Period window start (upstream startPeriod)
--end no Period window end (upstream endPeriod)

Note:****--country and --indicator are both required — the country-only key (/data/WEO/USA) is a multi-megabyte wall this face never forms; the key shape COUNTRY.INDICATOR[.FREQUENCY] fits the WEO/GDD/CPI family — flows like UNFCCC insert further dimensions before the indicator, and a wrong-order key upstream 404s; SCALE is a display hint only, OBS_VALUE already carries the true value.

$ economy imf_sdmx_series --flow WEO --country USA --indicator NGDP_RPCH --start 2023 --end 2026
{
  "reason": "IMF SDMX WEO USA.NGDP_RPCH — 4 observations 2023→2026, first 2023, latest 2026 = 2.327686 (Gross domestic product (GDP), Constant prices, Percent change)",
  "result": {
    "rows": [
      { "flow": "WEO", "dims": { "COUNTRY": "USA", "INDICATOR": "NGDP_RPCH", "FREQUENCY": "A" },
        "period": "2023", "value": 2.918628, "scale": "0",
        "series_name": "Gross domestic product (GDP), Constant prices, Percent change",
        "doi": null },
      { "flow": "WEO", "dims": { "COUNTRY": "USA", "INDICATOR": "NGDP_RPCH", "FREQUENCY": "A" },
        "period": "2026", "value": 2.327686, "scale": "0",
        "series_name": "Gross domestic product (GDP), Constant prices, Percent change",
        "doi": null }
    ],
    "total": 4,
    "count": 4,
    "key": "USA.NGDP_RPCH"
  },
  "evidence": [
    { "quote": "2023 2.918628 (COUNTRY=USA, INDICATOR=NGDP_RPCH, FREQUENCY=A)",
      "url": "https://api.imf.org/external/sdmx/2.1/data/WEO/USA.NGDP_RPCH" }
  ],
  "source": { "provider": "imf_sdmx", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T02:09:56.131Z" }
}

**Reading it:**One row = one period observation and value is the full-precision original (2026 = 2.327686 here — the IMF DataMapper shows 2.3 for the same series, rounded to one decimal); series_name and other metadata travel with the row (the most-used of the WEO's 62 metadata columns — this series carries an empty DOI). Rows run oldest-first. The WEO flow spans actuals plus projections, 1980–2031. 24-hour TTL.

economy oecd_sdmx_series

OECD macro dataflows (Economic Outlook / national accounts, structure-validated series keys)

Parameters:

Flag Required Meaning
--flow yes Dataflow in the catalog form agency,DSD@DF\[,version\] (e.g. OECD.ECO.MAD,DSD_EO@DF_EO,1.5 Economic Outlook, OECD.SDD.NAD,DSD_NAAG@DF_NAAG_I,1.0 national-accounts GDP chapter) — the bare DF spelling answers 404; a dotted agency is the norm
--key yes Dot-separated series key, one segment per DSD dimension, empty = wildcard (A.DEU... = annual × Germany × everything else) — validated against the structure endpoint first, with the dimension names in the error
--start no Period window start (upstream startPeriod)
--end no Period window end (upstream endPeriod)

**Note:**The flow must be the catalog form agency,DSD@DF[,version] — the bare DF spelling answers 404 "Could not find Dataflow and/or DSD" upstream (a dotted agency is the norm: OECD.ECO.MAD); the key needs exactly as many segments as the DSD has dimensions, an empty segment being the wildcard (A.DEU... = annual × Germany × everything else) — this face walks the structure endpoint first, validates the count locally with the dimension names in the error, so the short-key 403 ("expecting 12 got 6") never forms; the data rides the SDMX generic-CSV channel; the whole service is keyless — the 2026-11-02 "needs a key" ruling was a request-form misdiagnosis, since overturned.

$ economy oecd_sdmx_series --flow OECD.SDD.NAD,DSD_NAAG@DF_NAAG_I,1.0 --key A.DEU... --start 2023
{
  "reason": "OECD SDMX OECD.SDD.NAD,DSD_NAAG@DF_NAAG_I,1.0 A.DEU... — 27 observations from 2023, first 2023, latest 2025 = 5169.49861082987 (USD_PPP)",
  "result": {
    "rows": [
      { "flow": "DSD_NAAG@DF_NAAG_I",
        "dims": { "FREQ": "A", "REF_AREA": "DEU", "MEASURE": "B1GQ_R_POP", "UNIT_MEASURE": "PT_B1GQ_POP_PPP_OECD", "CHAPTER": "NAAG_I" },
        "period": "2023", "value": 132.325543634481, "unit_measure": "PT_B1GQ_POP_PPP_OECD",
        "obs_status": "E", "unit_mult": "0", "currency": "_Z", "price_base": "LR", "adjustment": "N" },
      { "flow": "DSD_NAAG@DF_NAAG_I",
        "dims": { "FREQ": "A", "REF_AREA": "DEU", "MEASURE": "B1GQ", "UNIT_MEASURE": "USD_PPP", "CHAPTER": "NAAG_I" },
        "period": "2023", "value": 6069.3347041307, "unit_measure": "USD_PPP",
        "obs_status": "E", "unit_mult": "9", "currency": "_Z", "price_base": "V", "adjustment": "N" }
    ],
    "total": 27,
    "count": 27,
    "dimensions": ["FREQ", "REF_AREA", "MEASURE", "UNIT_MEASURE", "CHAPTER"],
    "params": { "flow": "OECD.SDD.NAD,DSD_NAAG@DF_NAAG_I,1.0", "key": "A.DEU...", "start": "2023", "end": null }
  },
  "evidence": [
    { "quote": "2023 6069.3347041307 (FREQ=A, REF_AREA=DEU, MEASURE=B1GQ, UNIT_MEASURE=USD_PPP, CHAPTER=NAAG_I) [USD_PPP]",
      "url": "https://sdmx.oecd.org/public/rest/data/OECD.SDD.NAD,DSD_NAAG@DF_NAAG_I,1.0/A.DEU.../all" }
  ],
  "source": { "provider": "oecd_sdmx", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T04:25:02.014Z" }
}

**Reading it:**One row = one period observation; dims follows that DSD's dimension order (five here for NAAG; DSD_EO carries three, REF_AREA.MEASURE.FREQ — DSDs range from 3 to 12 dimensions); unit_measure rides the row (USD_PPP = PPP dollars, PT_B1GQ_POP_PPP_OECD = an index basis) and unit_mult is a power of ten (9 = billions — the 6069.3 here with unit_mult 9 is Germany's ~$6.07T PPP GDP); obs_status E = estimate. Rows run oldest-first, so the "latest" in reason is the last row. The structure call carries a 7-day TTL, the data 24 hours.

economy un_comtrade_trade

Bilateral trade mirror (reporter × partner × commodity × flow)

Parameters:

Flag Required Meaning
--reporter yes Reporting country: ISO-3 (USA) or the numeric area code (842)
--period yes Reporting period: 2023 or 202301
--partner no Partner area: ISO-3 or numeric code (0 / W00 = the World aggregate)
--cmd no Commodity code, comma list allowed (TOTAL = all goods)
--flow no Trade flow: X (export), M (import), X,M for both
--type-code no Path segment: commodity type (C)
--freq-code no Path segment: frequency (A = annual)
--cl-code no Path segment: classification (HS)
--max-records no Records per call (1–500)
--partner2 no Second partner area (upstream partner2Code; ISO-3 or numeric code, resolved the same as --partner — the via-country leg of a mirror flow)
--customs no Customs regime filter (upstream customsCode; values per the Comtrade reference)
--mot no Mode of transport filter (upstream motCode; a numeric code per the Comtrade reference)

**Note:**reporter / partner are translated through the area reference — passing ISO3 upstream gets a 400; that reference holds historical and duplicate rows (USA appears as 840/841/842), and the rule is: drop the bracketed historical rows and take the shortest current name; the public preview face is capped at 500 records per call and reaches aggregate-level magnitudes only; 12-hour TTL.

$ economy un_comtrade_trade --reporter USA --period 2023 --partner DEU --cmd TOTAL --flow X
{
  "reason": "UN Comtrade USA × DEU — 2023, cmd TOTAL, flow X: 1 rows, top Export TOTAL = 76472551326.0 USD",
  "result": {
    "rows": [
      { "type_code": "C", "freq_code": "A", "period": "2023", "ref_year": 2023,
        "reporter_code": 842, "reporter_iso3": "USA", "reporter_name": "USA",
        "flow_code": "X", "flow_name": "Export",
        "partner_code": 276, "partner_iso3": "DEU", "partner_name": "Germany",
        "partner2_code": 0, "partner2_iso3": "W00", "classification_code": "H6",
        "cmd_code": "TOTAL", "cmd_name": "All Commodities",
        "customs_code": "C00", "mot_code": 0, "mot_name": "TOTAL MOT",
        "qty_unit_code": -1, "qty": 0.0, "net_weight": 0.0,
        "cif_value": null, "fob_value": 76472551326.0, "primary_value": 76472551326.0,
        "is_aggregate": true, "is_reported": false }
    ],
    "total": 1,
    "count": 1,
    "elapsed": "0.78 secs"
  },
  "evidence": [
    { "quote": "2023 USA → DEU Export TOTAL = 76472551326.0 USD",
      "url": "https://comtradeplus.un.org/" }
  ],
  "source": { "provider": "un_comtrade", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:38:50.837Z" }
}

**Reading it:**One row = one (reporter × partner × commodity × flow) observation; primary_value is the USD value, and fob_value / cif_value follow the flow (FOB for exports, CIF for imports — this run is an export, so fob_value matches the primary value and cif_value is null). reporter_code / partner_code are Comtrade's numeric area codes (USA=842, DEU=276); the ISO3 codes are translated by this layer through the area reference.

economy unsd_sdg_indicators

UN SDG indicator catalog (17 goals × 251 indicators × series codes)

Parameters:

Flag Required Meaning
--page no Local page slice (the upstream sends the whole catalog at once)
--per-page no Local page size (1–500, default 50)
--search no Local keyword scan (indicator code / description / series codes) — over the whole catalog, not the current page

**Note:**Paging (--page / --per-page) is a local slice, not upstream paging — --search filters the whole catalog before slicing, so keyword hits don't depend on the page; the catalog rolls with quarterly releases (the release field rides the series rows).

$ economy unsd_sdg_indicators --search poverty
{
  "reason": "UNSD SDG indicator catalog — 4 indicators match the keyword, 4 on this page, top 1.1.1 (goal 1, 2 series) = Proportion of the population living below the international poverty line by sex,",
  "result": {
    "rows": [
      { "goal": "1", "target": "1.1", "code": "1.1.1",
        "description": "Proportion of the population living below the international poverty line by sex, age, employment status and geographic location (urban/rural)",
        "tier": "1", "uri": "/v1/sdg/Indicator/1.1.1",
        "series_count": 2, "series_codes": ["SI_POV_DAY1", "SI_POV_EMP1"] }
    ],
    "total": 4,
    "count": 4
  },
  "evidence": [
    { "quote": "1.1.1 (goal 1) — Proportion of the population living below the international poverty line by sex, [SI_POV_DAY1, SI_POV_EMP1]",
      "url": "https://unstats.un.org/SDGAPI/v1/sdg/Indicator/1.1.1" }
  ],
  "source": { "provider": "unsd_sdg", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T02:10:43.376Z" }
}

**Reading it:**One row = one SDG indicator, with the series codes nested inside (series_codes — how unsd_sdg_series locates the data); goal / target give the hierarchy. 251 indicators / 713 series codes / 17 goals; --search scans the whole catalog (the upstream sends everything at once; paging happens locally). 7-day TTL.

economy unsd_sdg_series

UN SDG series observations (goal × geography × year)

Parameters:

Flag Required Meaning
--series yes SDG series code (e.g. SI_POV_DAY1, DC_ODA_POVLG — list candidates with unsd_sdg_indicators) — series granularity only; the whole-indicator endpoint is a 3.2M-row wall and is never called
--geo no Geography filter, applied locally (matches geoAreaCode or geoAreaName, case-insensitive) — the upstream area parameter is decorative (byte-identical with or without it)
--time no Period filter (upstream timePeriod, e.g. 2020) — the one upstream filter that works on this endpoint
--page no Page number, 1-based (upstream pager)
--page-size no Rows per page (1–1000, default 100)

Note:****--geo filters locally — the upstream area parameter is decorative (byte-identical with or without it) and the local filter only sees the fetched page (a geography off this page won't appear — narrow with --time or widen --page-size first); series granularity only — the whole-indicator endpoint answers 3.2M rows for one indicator and is never called here; --time is the one upstream filter that works on this endpoint.

$ economy unsd_sdg_series --series DC_ODA_POVLG --geo China --time 2020
{
  "reason": "UNSD SDG series DC_ODA_POVLG — 1 rows on this page of 138 total, geo China (local filter), period 2020, top China 2020 = 0.000165",
  "result": {
    "rows": [
      { "series": "DC_ODA_POVLG",
        "series_description": "Official development assistance grants for poverty reduction, by recipient countries (percentage of GNI)",
        "goal": "1", "target": "1.a", "indicator": "1.a.1",
        "geo_area_code": "156", "geo_area_name": "China",
        "period": "2020", "value": "0.000165", "value_type": "Float",
        "attributes": { "Nature": "C", "Units": "PERCENT" },
        "dimensions": { "Reporting Type": "G" },
        "source": "The Organisation for Economic Co-operation and Development (OECD).",
        "footnotes": ["Commitments, Based on OECD, CRS database, 2026, Current USD million, As percentage of GNI"] }
    ],
    "total": 138,
    "count": 1,
    "total_pages": 2,
    "page": 1,
    "geo_filtered": true
  },
  "evidence": [
    { "quote": "China (156) 2020 = 0.000165",
      "url": "https://unstats.un.org/SDGAPI/v1/sdg/Series/Data?seriesCode=DC_ODA_POVLG" }
  ],
  "source": { "provider": "unsd_sdg", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T02:11:12.884Z" }
}

**Reading it:**One row = one geography × period observation of the series; value is a string (value_type names the type), and attributes (Nature=C country data, G global monitoring) and dimensions (Reporting Type N national / G global / R regional) travel with the row. total is the upstream's full row count (138 rows for period 2020 here) and geo_filtered marks that the local geo filter applied. 24-hour TTL.

economy wb_countries

World Bank country reference (ISO3 × income band)

Parameters:

Flag Required Meaning
--page no Page number, 1-based (default 1)
--per-page no Rows per page (default 100)

**Note:**Of the 296 entries some are aggregates (world / regional totals) — this is not a pure sovereign-state list; income_level reads Aggregates on those rows; the default page is 100 rows, so ask for --per-page 300 to walk the whole table.

$ economy wb_countries --per-page 5
{
  "reason": "World Bank country reference — 296 entries in total, 5 on this page, top ABW Aruba (High income)",
  "result": {
    "rows": [
      { "iso3": "ABW", "iso2": "AW", "name": "Aruba", "region_id": "LCN",
        "region_name": "Latin America & Caribbean ", "admin_region": null,
        "income_level_id": "HIC", "income_level": "High income",
        "lending_type_id": "LNX", "lending_type": "Not classified",
        "capital_city": "Oranjestad", "longitude": "-70.0167", "latitude": "12.5167" },
      { "iso3": "AFE", "iso2": "ZH", "name": "Africa Eastern and Southern", "region_id": "NA",
        "region_name": "Aggregates", "admin_region": null,
        "income_level_id": "NA", "income_level": "Aggregates",
        "lending_type_id": null, "lending_type": "Aggregates",
        "capital_city": "", "longitude": "", "latitude": "" }
    ],
    "total": 296,
    "count": 5
  },
  "evidence": [
    { "quote": "ABW Aruba (High income, Latin America & Caribbean )",
      "url": "https://data.worldbank.org/country/ABW" }
  ],
  "source": { "provider": "wb", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:37:45.626Z" }
}

**Reading it:**One row = one country or one aggregate region; income_level (the income band) is the buyer-screen dimension and region_name the geographic grouping. The table mixes in aggregate entries (regions such as AFE), so don't read an aggregate as a country when you filter by ISO3. 7-day TTL.

economy wb_ids_indicators

World Bank debt-statistics catalog (577 DT.* debt codes)

Parameters:

Flag Required Meaning
--page no Page number, 1-based (default 1)
--per-page no Rows per page (default 600 — the whole IDS catalog fits one page)
--search no Keyword, scanned over the current page only (not an upstream filter)

**Note:**The source parameter means opposite things on the two faces — the catalog needs source=6, while the value endpoint with source=6 answers 175 indicator was not found (the API silently falls back to sourceid 2, which is what saves the day); the default --per-page 600 holds the whole 577-entry catalog on one page; --search is a local scan over the current page.

$ economy wb_ids_indicators --search "external debt"
{
  "reason": "World Bank International Debt Statistics catalog (source 6) — 577 indicators in total, 121 on this page, top DT.AMT.DECB.CD = Principal repayments on external debt, central bank (PPG) (AMT, current US$) — the keyword filter is a local scan over this page — the DT.* values are served by wb_wdi_values WITHOUT --source",
  "result": {
    "rows": [
      { "indicator_code": "DT.AMT.DECB.CD",
        "name": "Principal repayments on external debt, central bank (PPG) (AMT, current US$)",
        "unit": null, "source_id": "6",
        "source_name": "International Debt Statistics" }
    ],
    "total": 577,
    "count": 121
  },
  "evidence": [
    { "quote": "DT.AMT.DECB.CD = Principal repayments on external debt, central bank (PPG) (AMT, current US$)",
      "url": "https://data.worldbank.org/indicator/DT.AMT.DECB.CD" }
  ],
  "source": { "provider": "wb", "execution": "local", "from_cache": false, "observed_at": "2026-11-03T02:11:38.272Z" }
}

**Reading it:*One row = one DT. external-debt indicator code; the seven families are stocks (DOD) / interest (INT) / disbursements (AMT) / net flows (NFL) / debt service (TDS) / cancellations (DIS) / net transfers (NTR), plus the balance-of-payments mirrors. source_id=6 is IDS. Fetch the values through wb_wdi_values WITHOUT --source (the value endpoint breaks with source=6). 7-day TTL.

economy wb_wdi_indicators

World Bank indicator catalog (WDI codes)

Parameters:

Flag Required Meaning
--source no World Bank source id, 2 = WDI (default 2) — without it the catalog is every source at once
--page no Page number, 1-based (default 1)
--per-page no Rows per page (default 500)
--search no Keyword, scanned over the current page only (not an upstream filter) — candidates off-page need paging

**Note:**Without --source the catalog is every World Bank source at once (~29.5k indicators), so this face pins 2; --search scans the current page only (off-page candidates stay invisible); 7-day TTL.

$ economy wb_wdi_indicators --source 2 --search GDP
{
  "reason": "World Bank indicator catalog (source 2) — 1,498 indicators in total, 32 on this page, top BG.GSR.NFSV.GD.ZS = Trade in services (% of GDP) — the keyword filter is a local scan over this page",
  "result": {
    "rows": [
      { "indicator_code": "BG.GSR.NFSV.GD.ZS", "name": "Trade in services (% of GDP)", "unit": null,
        "source_id": "2", "source_name": "World Development Indicators" },
      { "indicator_code": "BM.KLT.DINV.WD.GD.ZS", "name": "Foreign direct investment, net outflows (% of GDP)", "unit": null,
        "source_id": "2", "source_name": "World Development Indicators" }
    ],
    "total": 1498,
    "count": 32
  },
  "evidence": [
    { "quote": "BG.GSR.NFSV.GD.ZS = Trade in services (% of GDP) (World Development Indicators)",
      "url": "https://data.worldbank.org/indicator/BG.GSR.NFSV.GD.ZS" }
  ],
  "source": { "provider": "wb", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:37:40.562Z" }
}

**Reading it:**One row = one indicator code (indicator_code is the only name); source_id=2 is WDI. --search is a local keyword scan over the current page's names / units / notes, not an upstream filter — to find an indicator by word, page through or narrow the keyword.

economy wb_wdi_values

World Bank indicator values (country × year × code)

Parameters:

Flag Required Meaning
--country yes Country ISO-3 code; several joined with ; (CHN;JPN)
--indicator yes One WDI indicator code (e.g. NY.GDP.MKTP.CD) — several codes answer 120 Invalid value upstream
--date no A year or a range: 2020 or 2020:2023
--per-page no Rows per page (default 100)

**Note:**One indicator code per call — joining several with ; gets 120 Invalid value upstream (a message in the body, not an HTTP code); use --country CHN;JPN for several countries; a missing observation is null, not 0.

$ economy wb_wdi_values --country CHN --indicator NY.GDP.MKTP.CD --date 2020:2023
{
  "reason": "World Bank WDI: CHN × NY.GDP.MKTP.CD — 4 rows (total 4), last updated 2026-10-08, top CHN 2023 = 18270356654533.2",
  "result": {
    "rows": [
      { "indicator_code": "NY.GDP.MKTP.CD", "indicator_name": "GDP (current US$)",
        "country_iso3": "CHN", "country_name": "China", "year": "2023",
        "value": 18270356654533.2, "unit": null, "obs_status": null, "decimal": 0 },
      { "indicator_code": "NY.GDP.MKTP.CD", "indicator_name": "GDP (current US$)",
        "country_iso3": "CHN", "country_name": "China", "year": "2022",
        "value": 18316765021690.2, "unit": null, "obs_status": null, "decimal": 0 }
    ],
    "total": 4,
    "count": 4,
    "last_updated": "2026-10-08"
  },
  "evidence": [
    { "quote": "CHN 2023 = 18270356654533.2 (GDP (current US$))",
      "url": "https://data.worldbank.org/indicator/NY.GDP.MKTP.CD?locations=CHN" }
  ],
  "source": { "provider": "wb", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:37:33.803Z" }
}

**Reading it:**One row = one country × one year × one indicator value; a null value means the observation is missing (never zero-filled); last_updated is the upstream's last refresh for that series. Compare across countries with the same indicator code; different statistical bases (World Bank vs EU official) are not merged. 24-hour TTL.

economy who_xmart_indicators

WHO indicator catalog (with the values entity set)

Parameters:

Flag Required Meaning
--filter no The upstream OData $filter verbatim (e.g. startswith(IND_NAME,'TB_')) — this is how you find indicators by word
--top no Upstream $top page size (1–5000, default 500)
--skip no Upstream $skip offset (default 0)
--search no Keyword, scanned over the current page only (not an upstream filter)

**Note:**Find indicators by word through --filter (the upstream OData $filter, verbatim, e.g. startswith(IND_NAME,'TB_')) — --search is only a local scan of the current page (--search tuberculosis --top 20 measured 0 rows: the word is not in the first 20 catalog entries); a malformed $filter gets an upstream 400, which this layer maps to usage_error rather than an upstream failure.

$ economy who_xmart_indicators --filter "startswith(IND_NAME,'TB_')" --top 20
{
  "reason": "WHO xMart indicator directory — 40 indicators match the upstream $filter, 20 on this page, top TB_ppm_pulm_num — Number of notifications of people diagnosed with a new episode of pulmonary TB",
  "result": {
    "rows": [
      { "IND_ID": "1297FB8CC21162", "IND_NAME": "TB_ppm_pulm_num",
        "IND_NAME_FULL": "Number of notifications of people diagnosed with a new episode of pulmonary TB",
        "IND_NAME_SHORT": "TB_ppm_pulm_num", "IND_CODE_GHO": "TB_ppm_pulm_num",
        "VALUE_TYPE": "COUNT", "IND_UNIT": "Number",
        "IND_URI_API": "https://xmart-api-public.who.int/DATA_/RELAY_TBPPM",
        "IND_URI_WEB": "https://data.who.int/indicators/1297FB8CC21162",
        "IND_PUBLISH_TIME_PREV": "2024-10-10", "DATA_PROVENANCE": "COUNTRY_REPORTED" },
      { "IND_ID": "94BFA31A52F4E8", "IND_NAME": "TB_e_attr_risk_num",
        "IND_NAME_FULL": "TB_e_attr_risk_num", "IND_NAME_SHORT": "TB_e_attr_risk_num",
        "IND_CODE_GHO": "TB_e_attr_risk_num",
        "VALUE_TYPE": "COUNT", "IND_UNIT": "number",
        "IND_URI_API": "https://xmart-api-public.who.int/DATA_/RELAY_TB",
        "IND_URI_WEB": "https://data.who.int/indicators/A1B2C3DE4F5G6H",
        "IND_PUBLISH_TIME_PREV": "2023-10-18", "DATA_PROVENANCE": "OFFICIAL_ESTIMATE" }
    ],
    "total": 40,
    "count": 20
  },
  "evidence": [
    { "quote": "TB_ppm_pulm_num — Number of notifications of people diagnosed with a new episode of pulmonary TB",
      "url": "https://data.who.int/indicators/1297FB8CC21162" }
  ],
  "source": { "provider": "who_xmart", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:48:22.037Z" }
}

**Reading it:**One row = one WHO indicator; the last segment of IND_URI_API is that indicator's values entity set (who_xmart_values locates the data table through it). IND_NAME is sometimes a full sentence rather than a code — the values face matches the row whose IND_NAME equals the code you hold. 24-hour TTL.

economy who_xmart_values

WHO indicator observations (indicator × M49 geography × year)

Parameters:

Flag Required Meaning
--indicator yes Indicator code (e.g. TB_ppm_enrol_tx_prct)
--geo no ISO-3 country code or a raw M49 code (translated through REF_GEO_WIDE)
--year no Year (the DIM_TIME string value, e.g. 2023)
--entity-set no The values entity set (required when one indicator name has several candidates)
--top no Upstream $top page size (1–5000, default 500)
--skip no Upstream $skip offset (default 0)

**Note:**One indicator name can live in several entity sets — this layer never auto-picks the first; more than one candidate is a usage_error that lists them, and you choose with --entity-set; --year is a string value (2023); the geography reference carries a 7-day TTL.

$ economy who_xmart_values --indicator TB_ppm_enrol_tx_prct --geo PAK --year 2023
{
  "reason": "WHO xMart TB_ppm_enrol_tx_prct (entity set RELAY_TBPPM) — 11 observations, geo 586, 2023, top 2023 586 = 100.0",
  "result": {
    "rows": [
      { "IND_ID": "TBABF2ETB_ppm_enrol_tx_prct", "IND_CODE": "TB_ppm_enrol_tx_prct",
        "DIM_TIME": "2023", "DIM_TIME_TYPE": "YEAR",
        "DIM_GEO_CODE_M49": "586", "DIM_GEO_CODE_TYPE": "COUNTRY",
        "DIM_1_CODE": "DIM_OWNERSHIP", "DIM_MEMBER_1_CODE": "PRIVATE_FOR_PROFIT",
        "DIM_2_CODE": "DIM_LEVEL", "DIM_MEMBER_2_CODE": "PRIMARY",
        "VALUE_NUMERIC": 100.0, "VALUE_LABEL": null, "OBSERVATION_STATUS": null }
    ],
    "total": 11,
    "count": 11
  },
  "evidence": [
    { "quote": "2023 586 PRIVATE_FOR_PROFIT = 100.0",
      "url": "https://xmart-api-public.who.int/DATA_/RELAY_TBPPM" }
  ],
  "source": { "provider": "who_xmart", "execution": "local", "from_cache": false, "observed_at": "2026-11-02T10:38:25.121Z" }
}

**Reading it:**One row = one observation: year × M49 geography × stratified dimensions (DIM_1_CODE / DIM_MEMBER_1_CODE and friends); VALUE_NUMERIC holds the number. The geography key is an M49 string (this layer translates ISO3 through REF_GEO_WIDE), and DIM_TIME is quoted too — both are string-typed.

The fine print

  • Never merge two statistical bases for one indicator: WDI and Eurostat carry the same indicator names (GDP / population) on different bases — pick one per use and never mix them.
  • Check the exchange-rate direction first: the ECB value reads "1 EUR = X units of that currency"; the currency unit columns (unit) on WDI and Eurostat are often null, so never assume USD.
  • A missing observation is null, never zero: WDI's empty values, FRED's . and Eurostat's blanks stay null in this layer — nothing is back-filled with zero.