Compare countries' unemployment programmatically
Ranking countries on one indicator usually means one request per country, then aligning years by hand. A comparison endpoint does that in a single call.
The problem
Cross-country comparisons break on the details. Countries report for different latest years, some have gaps, and country names are inconsistent between sources. If your agent fetches each country separately it also pays latency and rate-limit costs ten times over, and it has to sort and rank the results itself.
How /compare answers it
GET /compare takes countries, either a comma-separated list of up to 10 ISO codes or a group name (G7, BRICS, NORDICS, EUROPE_BIG4), and an indicator such as unemployment, inflation, gdp_per_capita, gdp_growth or debt_to_gdp. For each country it takes the most recent available observation, sorts descending (or ascending with order=asc) and returns a ranking with rank, name, ISO codes, year and value. Countries without data are listed under noData instead of failing the whole call. Because each row carries its own year, you can see when two figures are not from the same period.
Request and response
Example: unemployment across the G7.
$ curl -i "https://macrolens.imac2014ville.workers.dev/compare?countries=G7&indicator=unemployment"
HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6Mi4uLn0= # base64 JSON: scheme "exact", network eip155:8453,
# asset USDC, amount 10000 (= $0.01)
# An x402 client signs the payment, then retries with a PAYMENT-SIGNATURE header.
The paid response (abridged to three of the seven G7 rows):
{
"ok": true,
"indicator": { "key": "unemployment", "code": "SL.UEM.TOTL.ZS", "units": "%",
"name": "Unemployment, total (% of total labor force) (modeled ILO estimate)" },
"order": "descending",
"note": "Each value is the most recent available observation for that country; compare the year field.",
"ranking": [
{ "rank": 1, "country": "France", "iso2": "FR", "year": 2025, "value": 7.542 },
{ "rank": 2, "country": "Canada", "iso2": "CA", "year": 2025, "value": 6.907 },
{ "rank": 7, "country": "Japan", "iso2": "JP", "year": 2025, "value": 2.451 }
],
"source": "World Bank Open Data (CC BY 4.0)"
}
JavaScript with @x402/fetch
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
const signer = privateKeyToAccount(process.env.PRIVATE_KEY); // wallet holding USDC on Base
const pay = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(signer) }],
});
const res = await pay("https://macrolens.imac2014ville.workers.dev/compare?countries=SE,NO,DK,FI&indicator=gdp_per_capita&order=desc");
const { ranking } = await res.json();
for (const r of ranking) console.log(r.rank, r.country, Math.round(r.value), r.year);
Pricing
/compare costs $0.01 per call, whatever the number of countries (up to 10). There is no API key and no account: each request is paid in USDC on Base over x402. Malformed input returns 400 and failed lookups return a non-2xx status, so those are not charged.
Limitations
- The comparison uses each country's latest observation, so the years may differ. Check
yearbefore drawing conclusions. - A maximum of 10 countries per call; groups expand to their fixed members (G7 is US, JP, DE, GB, FR, IT, CA).
- World Bank estimates of unemployment are model-based and may differ from national figures.
More guides
MacroLens overview/openapi.jsonllms.txt
Sister services
- BaseLens: Base chain tools: tx explainer, wallet snapshot, x402 endpoint check, web-to-markdown
- DepVet: npm and PyPI package vetting before install
- TokenGuard: honeypot and rug pull checks for Base tokens, plus pre-screened new launches
- SkyFeed: weather forecasts, US alerts, earthquakes and public holidays
- ChainRead: gas, balances, ENS and Basename resolution on Base and Ethereum