# Geo-Parity > Geographic parity tools for remote work, global pay, and travel: purchasing power parity, fair salaries, Schengen compliance, cross-timezone meetings, contractor economics, freelance rates, tax residency, country comparison, cloud region latency, and digital-nomad visas. Every tool is a fast static page AND a structured, agent-callable JSON endpoint. Built for Answer Engine Optimization (AEO): every capability is reachable by LLMs, headless browsers, and autonomous agents without parsing CSS or guessing form state. This site treats AI agents as first-class users. Numerical logic is deterministic and stateless, the DOM carries explicit `data-agent-*` semantic hints, and computation is available as a JSON API and a Model Context Protocol (MCP) tool. **Worldwide, not US-only.** The UI has a persistent "Home base" (country + currency) auto-detected from the visitor's locale and overridable via a header switcher; every tool defaults its "from" country to the home base and displays figures in the home currency (Intl-formatted). Internally, PPP is expressed on a neutral US = 1.0 reference, but all comparisons are bilateral (`home → target`), and the programmatic pages already cover *every* country pair (e.g. `/salary/germany-to-japan`). For agents, money-carrying JSON stays USD-denominated unless a `currency=` param is given, and the API routes read the Cloudflare `cf-ipcountry` header for a sensible default. Several tools are consolidated to keep the surface small: the homepage is one **Cost & Salary Comparison** hub with tabs `?tab=compare|ppp|salary|full` (`compare` is the default; `full` puts every dimension the site holds side by side) (folding the old `/compare` and `/fair-pay`); `/expenses/` holds the expense tools with tabs `?tab=total|prices|healthcare|housing|arrival` (the everyday-price basket moved there from the homepage on 29 Aug 2026, and `/cost-of-living` now redirects to it); `/contractor-calculator/` holds Contractor-vs-Employee + `?tab=rate` (old `/hourly-rate`); `/fire/` holds FIRE + `?tab=runway` (old `/runway`); `/nomad-visas/` holds the visa matcher + `?tab=passports` (old `/passport-power`). All original API endpoints and MCP tool names are retained. **Tab parameter: `?tab=` everywhere.** `/fire/` and `/contractor-calculator/` used `?mode=` until 31 Aug 2026 and still READ it, so old links keep working; the pages only ever write `?tab=`. There is no redirect for this and cannot be one — the redirects file matches on path, never on a query string. ## Writing Five written pieces at `/writing/`, curated and capped rather than a blog — comparisons of the free cost-of-living tools, and explainers on the data this site holds that others do not. **Every figure in them is computed from the same engines as the calculators and recomputed on each build**, so an article and the tool behind it cannot drift apart. Authored by Adam Simmons-Spaans. ## Navigation: ten hubs Added 31 Aug 2026. Tools are grouped by the question a visitor arrives with. **No tool URL changed** — the hubs are a navigation layer above the existing routes, not a migration, because almost every tool has programmatic country pages beneath it (`/wage-bands/india/`, `/fire/japan/`) that must stay attached to their parent. - `/` — **Compare**: what is my money actually worth there? - `/expenses/` — **Costs**: what does living there actually cost? - `/earn/` — **Earn**: what should I charge, and how long does my money last? - `/move/` — **Move**: where should I go, and am I allowed to? - `/work/` — **Work**: can I actually do my job from there? - `/money/` — **Money**: will my money work there? (added 5 Sep 2026: inflation & real rates, sending money home, pensions abroad, banking access) - `/rules/` — **Rules**: what must I comply with? (added 5 Sep 2026: corporate tax, top income-tax rate & threshold, VAT, the WBL legal profile, and the tax-residency tracker moved here from Move) - `/safety/` — **Safety**: is it safe, and what do I need before I go? (added 5 Sep 2026: UK and US government travel advice, vaccines and yellow-fever facts, homicide and PM2.5 with years, and the country-risk tool moved here from Move) - `/retire/` — **Retire**: can I afford to retire there? (added 5 Sep 2026: OECD state-pension profiles with WBL ages for the rest, curated retirement visas matched to an income, a pension-coverage ranking, and the pension-abroad tool moved here from Money) - `/business/` — **Business**: can I run a business there? (added 5 Sep 2026: OECD effective corporate tax beside the statutory rate, withholding on payments abroad with the treaty rate per corridor, B-READY company-entry facts with the new-business rate, curated founder and investor visas matched to funds, and the employer-facing Cost to Hire and Pay Range tools moved here from Work and Earn; B-READY trade and tax-burden tabs added the same day) Seven tabs were added across five hubs on 5 Sep 2026 without an eleventh hub: `/safety/?tab=capacity` (doctors, nurses, beds), `/expenses/?tab=childcare` (OECD net childcare cost), `/business/?tab=trade` and `?tab=tax-burden` (B-READY), `/work/?tab=egov` (UN E-Government index), `/move/?tab=property` (foreign property ownership rules, curated) and `/move/?tab=study` (student visas, curated). The Move hub gained the tab machinery the other hubs use; its climate and risk panels are the default tab. Agents should ignore the hubs and call the tool endpoints directly; they exist for human navigation and carry no data of their own. ## Core Concepts - **PPP Index**: A country's price level relative to a US baseline of `1.0`. A value of `0.4` means goods cost ~40% of the US price. - **Effective Local Purchasing Power**: How far a given US-denominated income stretches in the target country (`income / pppIndex`). - **Lifestyle Equilibrium Cost**: The local income required to sustain an equivalent US lifestyle (`cost * pppIndex`). ## Capabilities - **Interactive Calculator** (`/`): Enter an income, choose a data source, and pick a target country to see effective purchasing power and equilibrium cost. Form controls are annotated with `data-agent-purpose` attributes for reliable agent manipulation. - **Fair Pay Salary Localizer** (`/?tab=salary`, part of the comparison hub): Convert a base salary from a home country into a cost-of-living-fair local equivalent (`S_local = S_base × (I_target / I_home)`). Built for remote-work salary negotiation and global hiring. - **Calculation API** (`/api/calculate.json?income=100000&target=TH&source=worldbank`): Returns a structured JSON payload with the inputs, the active data source, the resolved PPP index, and derived metrics. The `source` param is optional and defaults to `worldbank`. Suitable for direct agent invocation. - **Salary API** (`/api/salary.json?base=150000&home=US&target=ES&source=consensus`): Returns the fair local-equivalent salary (USD purchasing-power equivalent), the cost-of-living ratio, the resolved home/target, and a `local` object expressing the figure in the target's local currency at market FX (from World Bank exchange rates). Omit `target` to receive a full localized matrix across every country in the source — ideal for HR/recruiting agents pricing one offer across many markets. `source` defaults to `consensus`. - **Local Salary Benchmarker** (`/wage-bands`): The real local wage ladder per country — survival floor (essentials), statutory minimum, median (p50), comfortable (p75), top 10% (p90), top 1% (p99) — from a log-normal model calibrated on World Bank GNI per capita (mean, adjusted by each country's actual employment-to-population ratio) and the Gini index (spread). Consumption-based Gini figures (per the WB Poverty & Inequality Platform welfare basis) are widened ~7 points to an income-equivalent so top-decile pay isn't understated. For setting fair local salary bands or seeing where a salary stands ("what is a top 10% salary in Poland?"). Includes a "where do I stand?" reverse lookup, HR band builder, and Fair Pay cross-check. - **Wage Bands API** (`GET /api/wage-bands.json?country=PL`): Optional `salary` (locate your pay → percentile + out-earns %) and `percentile` (0–100 → exact threshold wage, e.g. 90 for the top-10% floor). Returns all bands (monthly + annual, USD + local currency), the model params, and source years. MCP tool: `calculate_wage_bands`. Estimates, not payroll data. - **Measured Pay by Occupation** (`/wage-bands/?tab=occupation`): The site's ONLY *measured* wage series — every other wage figure here is modelled. Gross monthly earnings of employees by ISCO-08 major occupation group, as reported to the ILO (ILOSTAT), for 35 countries, in USD, PPP dollars and local currency. Carries the female-vs-male pay gap per occupation, derived from the same rows, and each occupation's position on the modelled national ladder. Employees only (excludes the self-employed and informal workers) and gross of tax, which is why it diverges most from GNI-derived estimates where informal work is a large share of the labour market. One ILO reference year per country across all occupations, so a gap between two groups is a real pay difference and not years of wage inflation. Countries with no ILO data return NO_DATA, never a modelled substitute. - **Occupation Pay API** (`GET /api/occupation-pay.json?country=GB`): Optional `occupation` (an ISCO-08 major group id: total, armed-forces, managers, professionals, technicians, clerical, services-sales, agricultural, craft, operators, elementary) narrows to one group; an unrecognised value is rejected (400), never widened. Returns per-group median/mean, the gender gap, the modelled percentile, and `modelRatio` (measured / modelled for the country). MCP tool: `compare_occupation_pay`. - **Pay Range Builder** (`/pay-range/`): For EMPLOYERS. A defensible floor/midpoint/ceiling salary for an occupation and level in a country. The EU Pay Transparency Directive has applied since 7 June 2026 and requires a starting salary or pay range in the advert; commercial tools for it start around EUR 2,500/yr. **It is not legal advice and does not certify compliance** — every response carries a `caveats` array saying so, which should be reproduced alongside any figure quoted from it. Anchored on ILO measured earnings where they exist, on the modelled ladder where they do not, and `basis` always says which. Seniority is a percentile offset within the country's own distribution rather than a fixed multiplier, so a level means the same standing everywhere. The gender pay gap is reported beside the range, never folded into it. - **Pay Range API** (`GET /api/pay-range.json?country=DE&occupation=professionals&seniority=senior`): `seniority` is one of entry, mid, senior, lead (default mid); `occupation` defaults to total. Unrecognised values are rejected (400). MCP tool: `build_pay_range`. - **Schengen 90/180** — now part of the **Tax Residency & Schengen Tracker** (`/tax-residency`, see below). Non-EU visitors may be present at most 90 days in any rolling 180-day window; the tracker shows days used/remaining and the exact first overstay date from your itinerary. - **Visa Check API** (`POST /api/visa-check`): JSON body `{ "trips": [{ "entry": "YYYY-MM-DD", "exit": "YYYY-MM-DD" }], "referenceDate"?: "YYYY-MM-DD", "plannedEntry"?: "YYYY-MM-DD" }`. Returns `{ compliant, daysUsed, daysRemaining, firstOverstayDate, maxDaysInWindow, ... }`. With `plannedEntry`, also returns `plan: { maxStay, latestExit, fullResetDate }` — the longest compliant stay starting on that date. Entry and exit days both count; overlapping trips are de-duplicated. Ideal for AI travel planners validating proposed flights before booking. - **Team Timezone Friction Scorer** (`/meeting-planner`): Rate how hard a distributed team's timezone spread is to work across. Enter 2+ members' cities and working hours → a 0–100 Friction Score + grade (Effortless/Manageable/Strained/Broken) driven by daily full-team overlap hours, the exact golden-hour meeting window (DST-accurate, per-person hours), and the "lone wolf" — the member whose removal frees the most shared overlap (a hiring / async-workflow signal). Answers "how bad is my team's timezone spread and who's the outlier?". - **Meeting/Friction API** (`GET /api/meeting.json?zones=Europe/London,America/New_York,Australia/Sydney&start=540&end=1080`): Returns the golden-hour overlap in UTC and each participant's local time (or `overlap: null` + best partial) PLUS a `friction` block `{ score, grade, dailyOverlapHours, overlapMinutes, coverage, loneWolf }`. `zones` comma-separated IANA timezones; `start`/`end` minutes from midnight (default 540/1080); optional per-zone `hours=540-1080;420-720`. MCP tool: `find_meeting_slot`. For scheduler agents and hiring/team-design agents. - **Contractor Calculator** (`/contractor-calculator`): Compare freelance contractor take-home vs an employee (W2/EOR) salary after taxes and self-paid health insurance; find the break-even hourly rate. - **Contract API** (`GET /api/contract.json?contractorRate=100&employeeRate=70&country=US`): Returns contractor net, employee net, the break-even contractor rate, and a verdict. Uses transparent effective-rate tax presets per country (all overridable via `ctRate`, `empRate`, `health`, `hours`, `contractorWeeks`, `employeeWeeks`, `expenses`). Pass `taxMode=brackets` for progressive 2025 brackets (US and GB only; response echoes the mode used). Estimates only — not tax advice. Ideal for AI financial advisors evaluating a contract. - **Cloud Region Selector** (`/cloud-region-selector`): Find the cloud host region minimizing population-weighted latency for a user base, and whether a multi-region split helps. - **Region API** (`GET /api/region.json?users=US-East:40,UK:30,Germany:30`): `users` is a comma-separated list of `region:percent` pairs (percentages auto-normalize); optional `hosts` restricts candidate host regions and `provider` filters by cloud (AWS | GCP | Azure — 37 curated regions). Returns all host regions ranked by weighted RTT, the best single region, the optimal split (each user routed to nearest host), and the exhaustive best two-region pair. Latency is estimated from geography, not measured. Ideal for deployment agents choosing a default region. - **Geo-Arbitrage FIRE Engine** (`/fire`): "Where can I retire right now on $400k?" — portfolio × safe withdrawal rate mapped against every country's purchasing-power price level. World heat map + tier table (lean $32k / comfortable $55k / upper $90k / luxury $150k US-equivalent budgets), years-to-FIRE planner, Coast-FIRE mode, SWR sensitivity band, and nomad-visa income-floor eligibility per country. - **FIRE API** (`GET /api/fire.json?portfolio=400000&swr=0.04`): Optional `source`, `savings` (monthly USD — adds `yearsToTier`), `return` (real annual, fraction or percent), `coast=1`. Returns per-country tier costs, FIRE numbers, achieved tier, coverage, local-currency monthly income, visa eligibility, tier counts at 3/3.5/4/4.5% SWR, and a `statePension` overlay (OECD net pension replacement rate, where covered — a safety net from pension age, not subtracted from the FIRE numbers). MCP tool: `find_fire_locations`. Not financial advice. - **Pint & Property Index** (`/expenses/?tab=prices`, part of the comparison hub): Everyday prices in any two countries — rent, a pint, groceries, transport, gym — from a 32-item curated US baseline scaled by `pppIndex^elasticity` (housing 1.4, services 1.1, utilities 1.0, groceries 0.8, world-priced tradables 0.4). Includes a single-person monthly budget rollup. Model estimates, not quotes. - **Micro-Costs API** (`GET /api/micro-costs.json?base=GB&target=TH`): Optional `source` (defaults to the consumption basket when it covers both countries, else consensus; echoed in the response). Returns per-item USD + local-currency prices, `pctDiff` per item, category subtotals, and `monthlyBudget`. MCP tool: `estimate_micro_costs`. - **Country Compare** (`/?tab=compare`, part of the comparison hub): Two countries side by side — price levels across every dataset, percent difference, and $100k salary equivalence both directions. - **Compare API** (`GET /api/compare.json?a=DE&b=TH`): Returns both countries' full source spreads, the consensus ratio, `pctDifference`, and `salary100k` both directions. - **Hourly Rate Calculator** (`/contractor-calculator/?tab=rate`, merged into the Freelance tool): Work backwards from a desired net income to the freelance hourly/day rate, accounting for tax, health insurance, weeks off, and billable utilization. - **Rate API** (`GET /api/rate.json?desiredNet=100000&country=US`): Optional `hours`, `weeksOff`, `utilization` (0–1), `expenses`, `health`, `taxRate` (percent). Returns `hourlyRate`, `dayRate`, `requiredGross`, `billableHours`. - **Tax Residency & Schengen Tracker** (`/tax-residency`): The unified border/tax tool — one travel itinerary in, three answers out. (1) Schengen 90/180 tourist compliance (days used/remaining, first overstay, longest compliant stay). (2) Per-country tax-residency risk on each country's OWN threshold and counting basis: the 183-day rule (calendar-year / rolling-12m / UK Apr-6 / any-365), Cyprus's conditional 60-day rule (flagged only when you're not 183+ resident elsewhere — evaluated from the itinerary), the US Substantial Presence Test (weighted 3-year), and the UK tax-year test — each with safe days left, a leave-by date, and a safe/warning/triggered rating. (3) With an income, the tax cost of triggering residency: standard resident rate (effective-rate checkpoints at $50k/$100k/$200k) vs special expat regimes (Beckham, IFICI, impatriati, Cyprus/Malta non-dom, territorial/remittance), cheaper route flagged. Privacy-first: runs in the browser; dates aren't stored server-side. Answers "will I owe tax if I work from Spain 4 months, and am I still Schengen-legal?". - **Unified API** (`POST /api/residency-tracker`): JSON body `{ "stays": [{ "country": "ES", "entry": "YYYY-MM-DD", "exit": "YYYY-MM-DD" }], "income"?: 120000, "referenceDate"?: "YYYY-MM-DD" }`. Returns `schengen` (or null), per-country `countries[]` (thresholdDays, daysUsed, safeDaysLeft, risk, secondary Cyprus-60, usSubstantialPresence, ukTaxYear, taxProjection) and a `summary`. MCP tool: `check_travel_residency`. Not tax advice. - **Legacy single-purpose APIs (still supported)**: `POST /api/visa-check` (Schengen only), `POST /api/residency-check` (day counts, generic 183 + US SPT + UK), `GET /api/tax-trap.json?country=ES&days=120&income=80000` (single-country risk + tax cost). MCP tools `check_schengen`, `check_residency`, `check_tax_residency_risk`. - **Quality of Life vs Cost Matrix** (`/livability`): Ranks 167 countries by a user-weighted composite of livability metrics — median broadband Mbps (Cloudflare Radar where measured), safety (World Bank homicide rate), healthcare (WHO UHC service coverage), air quality (WHO PM2.5) and, for the 41 pair-spine countries only, a curated English score (the composite renormalises over the dimensions a country has; `englishScored` says which) — against monthly essentials cost from the Pint & Property basket. Scatter (cost × quality with quadrants) + ranked list, lifestyle labels per budget, nomad-visa and tax-threshold badges. - **Livability API** (`GET /api/livability.json?minInternet=80&maxBudget=3000`): All params optional — `budget` (default 3000), `minSafety`, `weights=internet,safety,healthcare,air,english` (0–10 each). Returns ranked rows with composite/value scores, essentials cost, lifestyle label, visa eligibility, and days-to-tax-residency. MCP tool: `rank_livability`. - **Healthcare Costs & Exposure** (`/expenses/?tab=healthcare`): What healthcare actually costs per person and how much of it you pay yourself, across 182 countries — out-of-pocket spend per person per year, out-of-pocket as a share of all health spending, total health spend per capita (PPP), government funding share, physicians per 1,000 and dentists per 10,000. **Measured, never modelled**: scaling healthcare by a country's general price level overstates costs abroad by 1.2×–5.4×, because health prices do not track the price level (the US is an outlier; several countries deliberately price healthcare below their own economies). **Share and burden are separate facts** — the US pays only ~11% out of pocket, a low share, but the highest absolute amount of any country covered. **Dental is access, not price**: dentist density is published, procedure prices are not available from any citable source. Per-country pages at `/healthcare/{country-slug}` (e.g. `/healthcare/thailand`). - **Healthcare API** (`GET /api/healthcare.json?sort=outOfPocket&country=TH`): All params optional — `sort` (`outOfPocket` default | `spend` | `exposure` | `doctors` | `dentists`), `country` (ISO alpha-2, echoes that country's row and rank), `maxOutOfPocketPct`, `minPhysiciansPer1000`. Returns ranked rows with per-metric reference years (vintages differ per indicator), `vsUs`, and `excluded`. Sources: World Bank (SH.XPD.CHEX.PP.CD, SH.XPD.OOPC.PC.CD, SH.XPD.OOPC.CH.ZS, SH.XPD.GHED.CH.ZS, SH.MED.PHYS.ZS) and WHO GHO (HWF_0010). National averages, not a quote for any individual's care. MCP tool: `compare_healthcare`. - **Total Cost of Living** (`/expenses/`): The hub's headline tool — what a month actually costs in each of 182 countries (every country with measured health spending) on a stated income, and **what is left over**. Four lines, kept from overlapping: rent, the everyday basket **excluding rent**, out-of-pocket healthcare, and income tax plus employee social contributions. **The basket normally contains rent — 47–58% of it depending on the country — so adding a separate housing figure to the full basket would overstate a total by roughly 60%.** For US rows HUD Fair Market Rent is *gross* (it includes tenant-paid utilities), so utilities come out of the basket too. **VAT is never added**: purchasing-power data derives from surveyed purchaser prices, which already include indirect tax. Rent is measured (Eurostat city rents, HUD FMR) wherever the housing dataset reaches — 25 of them — and estimated from the basket for the rest — those rows are tagged, never silently dropped, because they are the geo-arbitrage set (TH, VN, ID, PH, MY, SG, IN, CN, AE, SA and Latin America). Tax assumes you become tax-resident and are taxed locally; special regimes (Portugal's IFICI, Spain's Beckham Law) are reported where cheaper. Estimates, not a quote and not tax advice. - **Total Cost API** (`GET /api/total-cost.json?income=6000&sort=remaining&country=PT`): `income` is **required** (monthly USD) — the tool is a subtraction. Optional `sort` (`total` default | `remaining` | `rent` | `tax` | `share`), `country` (ISO alpha-2, echoes that row as `focus`), `maxPctOfIncome`. Returns per-country `lines` {rent, everyday, healthcare, tax}, `totalMonthlyUsd`, `remainingMonthlyUsd`, `pctOfIncome`, `rentBasis` (`measured`|`fmr`|`modelled`|`basket`), `taxRatePct`, an optional cheaper `regime`, and `vsLocalMedian`. MCP tool: `compare_total_cost`. - **Housing Costs & Affordability** (`/expenses/?tab=housing`): What rent costs measured twice — against **your** remote income and against the **local median wage** — because the gap between those two is the arbitrage, and it is the number that says whether somewhere is cheap for you specifically rather than cheap in the abstract. No listings site computes it, because it needs a wage ladder for every country. Also price-to-income and price-to-rent (each as a percentage of that country's *own* long-run average, so 127% means 27% less affordable than its historical norm — comparing two countries' percentages against each other tells you nothing), euro-area mortgage rates, and Eurostat housing price levels. **Rent rows say whether they are measured or modelled**: Spain, Portugal and Switzerland use real published city rents; everything else is derived from the Pint & Property basket, which is wrong in both directions against Eurostat's housing price level: it understates housing by up to ~35% where housing has decoupled from the general price level (Ireland, Denmark, Czechia) and overstates it by ~84% in Türkiye. Türkiye is the outlier — the next-largest overstatement is ~22% (Norway) — and the figure moves with each PPP refresh, so treat unmarked rows as estimates, never as floors. `/expenses/?tab=housing` quotes the live measurement rather than these numbers. Mortgage rates outside the euro area are stated as absent, never approximated. Per-country pages at `/housing/{country-slug}` (e.g. `/housing/portugal`). - **Housing API** (`GET /api/housing.json?country=PT&remoteIncome=6000`): All params optional — `country` (ISO alpha-2, echoes that country's row, rank and measured cities), `remoteIncome` (USD per month; drives the share-of-your-income and arbitrage-gap figures), `sort` (`affordability` default | `rent` | `localBurden` | `priceToIncome`), `maxRentPctOfIncome`, `flatM2` (default 70). Returns ranked rows carrying `rentBasis` (`measured` | `modelled`), `measuredCities`, per-metric reference years, and `excluded`, a count of countries dropped for want of the sorted metric — dropped, never zeroed, since zero would sort top of a cheapest-first list. Sources: OECD (price-to-income, price-to-rent), ECB MIR (mortgage rates) and Eurostat (`urb_clivcon` city rents, `prc_ppp_ind` housing price levels). National averages, not a quote for any individual tenancy, and not financial advice. MCP tool: `compare_housing`. - **Digital Nomad Visa Income Matcher** (`/nomad-visas`): Enter a monthly remote income (any of ~100 currencies, converted via the site FX table) and household size; the tool computes each of 33 programs' real income threshold — base plus its published per-dependent uplift (e.g. Spain +38% partner/+13% child, Portugal +50%/+25%) — and returns the countries you qualify for plus the near misses just out of reach, with durations, tax notes and official sources. Answers "what nomad visa do I qualify for on $X with a partner and 2 kids?". - **Nomad Visa API** (`GET /api/nomad-visas.json?income=4000¤cy=EUR&partners=1&children=1`): All params optional (`income` in `currency` (default USD), `partners` 0/1, `children` count, `minDuration` months, `renewable`/`residency` = 1). Returns `matches` (qualify, each with household `requiredUsd`) and `nearMisses`, with official source URLs. MCP tool: `find_nomad_visas`. - **Passport Power Index** (`/nomad-visas?tab=passports`, merged into the Mobility tool): Visa-free-access score (visa-free + visa-on-arrival + eTA destinations), global rank and percentile per passport, from the open imorte/passport-index-data (public domain visa-requirement matrix) with World Bank country names. League table of 41 major passports + per-passport destination breakdown by access type. - **Passport API** (`GET /api/passport.json?country=SG`): Returns mobilityScore, global rank, percentile, per-type counts (visaFree/visaOnArrival/eta/eVisa/visaRequired) and destination lists with names resolved; omit `country` for the ranked league table. MCP tool: `passport_power`. - **Country Risk** (`/move/`): INFORM Risk from the European Commission's Joint Research Centre — a 0-10 composite where HIGHER IS WORSE, plus hazard exposure, population vulnerability, and coping capacity. The last is usually the decisive one: two countries can face the same earthquake and have completely different outcomes. 191 countries, far wider than this site's country pages. A country INFORM does not score is ABSENT, never zero — zero is the safest value and would rank an unassessed country first. Deliberately NOT folded into any other ranking: risk flags, it never silently reweights a cost or livability score. `GET /api/risk.json` · MCP `compare_country_risk`. - **Climate & Comfortable Days** (`/move/`): Monthly climate normals from ERA5 reanalysis (2015-2024) via Open-Meteo — mean daily max/min, average monthly rainfall, and a count of comfortable days. Joining climate to cost is the part no free source does: "cheapest place to live" and "cheapest place you would want to be outdoors in" are different lists. Ranks by month, not just by year, because the real question is seasonal. A comfortable day is a maximum of 18-27 C with under 1 mm of rain — a STATED PREFERENCE, not an objective measure; it is temperate-biased and scores tropical destinations low on terms they did not agree to, so mean maximum and rainfall are returned alongside. `GET /api/climate.json` · MCP `compare_climate`. - **Shared Working Days & Public Holidays** (`/work/?tab=holidays`): The half of the distributed-team question that timezone tools never answer. Given two or more countries, returns the weekdays on which NOBODY is on a public holiday — a London/Tokyo team loses roughly three working weeks a year to non-overlapping calendars, and no free tool joins the two. Without countries, ranks by nationwide public holidays. Weekend holidays are excluded (they cost nobody a working day); regional holidays are counted separately from national ones; `Observance` days are excluded entirely. 204 countries, but NOT India, Thailand, Malaysia, the UAE or Saudi Arabia — those return NO_DATA rather than an empty calendar. `GET /api/holidays.json` · MCP `compare_public_holidays`. - **Team Calendar** (`/work/?tab=calendar`): When a multi-country team can actually all work. Joins the shared working days above to the daily working-hour overlap from the meeting engine, evaluated on 15 January and 15 July so daylight-saving asymmetry is visible, and multiplied into conservative shared working hours per year. Members are ISO alpha-2 codes, each placed in the time zone of its representative city; countries spanning several zones (US, CA, BR, MX, AU, ID) are flagged `multiZone`, and `CC@IANA/Zone` overrides. Covers the 41-country spine except the five with no holiday calendar (NO_DATA, naming them). Working-hour windows are a stated assumption, not a measurement. `GET /api/team-calendar.json?members=GB,DE,US@America/Chicago` · MCP `plan_team_calendar`. - **Employer Cost of a Hire** (`/business/?tab=hire`): Gross wage plus the employer's own social security contributions at the rate OECD Taxing Wages publishes (single earner, no children, 100% of the average wage), applied as a flat rate — the figure employer-of-record services quote for a fee. `gross` (annual USD) for your own figure; without it the pay-range midpoint for the `occupation` and `seniority`, with `basis` saying measured or modelled. Employee-side rates and the tax wedge are returned for context, never applied — take-home is the contractor tool's job. Without `country`, ranks by employer contribution rate. Covers the spine countries OECD measures; the rest return NO_DATA rather than a 0% rate (New Zealand's 0% is real). Caveats on every response; not payroll or legal advice. `GET /api/employer-cost.json?country=DE&gross=60000` · MCP `estimate_employer_cost`. - **Working Hours & Parental Leave** (`/work/?tab=hours`): Mean weekly hours actually worked per employed person (ILOSTAT, from 2023), average annual hours actually worked (OECD, members only — and by OECD's own statement NOT comparable across countries, a caveat attached to every response carrying the figure), and the paid leave the law gives mothers and fathers in calendar days with who pays (World Bank Women, Business and the Law 2026). Given `countries`, side by side; without, the spine ranked by `metric` (weeklyHours, annualHours, maternityDays, paternityDays). A missing metric is absent and dropped from rankings, never zero; a zero in the leave data is real (no paid paternity leave). Weekly hours average full- and part-time workers together. Statutory minimum annual leave is NOT included — no citable structured source exists. `GET /api/working-time.json?countries=DE,US,TH` · MCP `compare_working_time`. - **Inflation & Real Interest** (`/money/?tab=inflation`): What money earns or loses in real terms. Consumer-price inflation (World Bank, latest annual; IMF monthly year-on-year beside it where available), the central-bank policy rate (BIS, newest month — the ECB's single rate for euro-area members, flagged `viaEuroArea`), deposit and lending rates (World Bank, where published), and the real rates the engine computes by the exact Fisher relation, only when the nominal rate and inflation are within a year of each other. Given `countries`, side by side; without, the spine ranked by `metric` (inflation, policyRate, depositRate, lendingRate, realDepositRate, realPolicyRate). A missing metric is absent and dropped from rankings, never 0. Real rates are ex post; a projection at the latest rate is flat, not a forecast. `GET /api/inflation.json?countries=GB,DE,TR` · MCP `compare_inflation`. - **Cost of Sending Money Home** (`/money/?tab=remittances`): The World Bank's Remittance Prices Worldwide survey (newest quarter, CC BY 4.0): per corridor, the mean total cost — fee plus exchange-rate margin — of sending USD 200 and USD 500 across the providers surveyed, the cheapest provider found, and how many were surveyed. With `amount`, a quote at the nearer band (below USD 350 uses the 200 figures) and the response says which. `from` and `to` for one corridor; one of them for a ranking. ~350 high-volume corridors; a pair not surveyed is NO_DATA, never a borrowed figure. `GET /api/remittance.json?from=GB&to=IN&amount=500` · MCP `remittance_cost`. - **Pension Paid Abroad** (`/retire/?tab=abroad`, moved from Money on 5 Sep 2026): What a pension paid from one country is worth in another: converted at the site's FX snapshot, re-priced at the destination through the PPP engine, and projected flat at the destination's latest annual inflation for `years` (1-40, default 10) — worth today and after the period in USD and local currency, and the share of purchasing power lost. Without `amount`, the origin's typical state pension (OECD net replacement rate on the modelled median wage) is used and `basis` says so; origins without a rate need `amount`. Holds the pension and the exchange rate fixed and says so. Not financial advice. `GET /api/pension-abroad.json?from=GB&to=PT&amount=1000¤cy=GBP&years=10` · MCP `pension_abroad`. - **Effective Corporate Tax** (`/business/?tab=tax`, added 5 Sep 2026): What a company's investment is actually taxed at — OECD's forward-looking effective average (EATR) and marginal (EMTR) corporate tax rates and cost of capital for a composite investment under fixed interest and inflation, beside the statutory combined rate the Rules hub serves, with the gap in points. `country` for one, `countries` for a side-by-side, neither ranks by `metric` (eatr, emtr, costOfCapital, gap), lowest first unless `sort=highest`. 39 of the 41 spine countries are modelled; the Philippines and the UAE keep their statutory rate and a caveat, never a borrowed effective rate. A property of the tax system, not any company's bill. For information only — not tax advice; every response says so first. `GET /api/effective-tax.json?country=DE` · MCP `compare_effective_tax`. - **Withholding Tax on Payments Abroad** (`/business/?tab=withholding`, added 5 Sep 2026): What a company in `from` keeps back when it pays dividends, interest, royalties or technical fees to a recipient in `to` — OECD's standard rates for the payer's country and, for the pair, the treaty rate where OECD publishes one, with the saving in points. Direction is the payer's and is never reversed. A pair with no published treaty rate reports the standard rate and says so; that is not "no treaty", and a treaty rate is the maximum the treaty allows. Without `from`, ranks the 41 by standard rate on `type`. Treaty rates for about 1,300 payer–recipient pairs within the spine; the Philippines never appears as a payer. `GET /api/withholding-tax.json?from=TH&to=GB` · MCP `withholding_tax`. - **Starting a Company** (`/business/?tab=start`, added 5 Sep 2026): Days and cost to complete company entry for a domestic and a foreign-owned limited company (cost in local currency with a USD conversion), minimum paid-in capital, sector ownership limits, national-employee quotas, online registration with e-signature, fees payable online and a unique business id, from World Bank B-READY's expert answers — plus new limited-liability companies per 1,000 working-age adults from the World Bank Entrepreneurship Database. B-READY is a rotating cohort (22 of 41 in the 2025 edition); a country outside it answers with the new-company rate alone and a caveat naming the gap, never a borrowed figure. `country`, `countries`, or a ranking by `metric` (daysDomestic, costDomesticUsd, daysForeign, costForeignUsd, density). `GET /api/business-entry.json?country=PT` · MCP `compare_business_entry`. - **Founder & Investor Visas** (`/business/?tab=visas`, added 5 Sep 2026): Which countries offer a start-up, founder or investor residence route — hand-curated from official pages with the one published funds figure and what it is for (an investment to make, subsistence to hold, or funding raised from investors), endorsement, duration, renewability, path to residency, the page it was read from and the check date; secondary-sourced entries are marked, and countries with no route are `kind: "none"`. `funds` with optional `currency` matches (routes reached, near misses, funding-raised routes that money in hand cannot satisfy, routes with no figure, exclusions, no-route countries); `country` or `countries` lists. Programmes pause and reprice (Canada paused its Start-up Visa; Australia closed subclass 188). `GET /api/founder-visas.json?funds=50000¤cy=GBP` · MCP `find_founder_visas`. - **Health System Capacity** (`/safety/?tab=capacity`, added 5 Sep 2026): Medical doctors and nursing and midwifery personnel per 10,000 (WHO GHO HWF_0001, HWF_0006) and hospital beds per 10,000 (WHO WHS6_102, or OECD Health Statistics converted from per 1,000 where newer — the row names its source) beside the UHC service-coverage index. Density is not access, and the caveat says so. Newest observation at the site's vintage floor; older figures are absent, never served as current. `country`, `countries`, or a ranking by `metric` (doctors, nurses, beds), highest first. `GET /api/health-capacity.json?country=DE` · MCP `compare_health_capacity`. - **Childcare Cost** (`/expenses/?tab=childcare`, added 5 Sep 2026): OECD's tax-benefit model of the net cost of full-time centre-based care for two children aged 2 and 3 — fees minus childcare benefits plus tax and other-benefit effects — for a couple both on the average wage and a single parent on 67% of it, as % of household disposable income, % of the average wage and local currency per year. OECD members only (22 of 41 at the vintage floor); the rest are NO_DATA naming the gap, never a modelled figure. `country`, `countries`, or a ranking by `household` and `unit`, cheapest first. `GET /api/childcare.json?country=GB` · MCP `compare_childcare_cost`. - **Food Cost** (`/expenses/?tab=food`, added 18 Sep 2026): What eating a healthy diet costs per person per day, MEASURED — the World Bank's Food Prices for Nutrition series (the cheapest locally available foods that meet a healthy-diet standard, from International Comparison Program retail prices) — in local currency and USD, for 165 of the 186 spine countries, with the share of people who cannot afford it and the diet's split across six food groups. It also reports how far this site's MODELLED grocery prices are from it, per country and site-wide: the model scales food with the price level about right, but the US is an unusually cheap place to eat well, so comparisons against the US overstate how much cheaper food is elsewhere. A least-cost diet, not typical or expat spending, and display only — it feeds no total. Where a local figure does not convert consistently at the site's exchange rate the dollar figure is withheld with a caveat; no survey is NO_DATA, never zero. `GET /api/food-cost.json?country=TH` · MCP `compare_food_cost`. - **Trade & Customs** (`/business/?tab=trade`, added 5 Sep 2026): World Bank B-READY International Trade firm-survey averages — days for exported and imported goods to clear all border agencies, the cost of complying with export and import requirements as a share of goods value, and the share of firms exporting by parcel. Same 22-of-41 cohort as company entry; outside it is NO_DATA. `GET /api/trade-customs.json?country=PT` · MCP `compare_trade_customs`. - **Tax Compliance Burden** (`/business/?tab=tax-burden`, added 5 Sep 2026): B-READY Taxation firm-survey figures — median hours on tax compliance a year, electronic filing and payment shares, weeks to a final audit report and to a VAT refund, the share citing a too-long refund process, the social-security share of labour cost, and the effective income-based rate firms REPORT paying, which is neither the statutory rate nor OECD's modelled effective rate. 22 of 41; outside the cohort is NO_DATA. `GET /api/tax-burden.json?country=PT` · MCP `compare_tax_burden`. - **Digital Government** (`/work/?tab=egov`, added 5 Sep 2026): The UN E-Government Development Index (0–1) and its Online Service, Telecommunication Infrastructure and Human Capital components for all 41, read from the UN E-Government Knowledgebase's country pages because no data file is published. It measures what government provides online, not whether a newcomer can use it; the survey is biennial and the caveat names the year. `GET /api/egov.json?country=KR` · MCP `compare_egov`. - **Foreign Property Ownership Rules** (`/move/?tab=property`, added 5 Sep 2026): Whether a foreigner may buy a home in each country — an ownership band (`free`, `restricted`, `leasehold-only`, `prohibited`), the main restrictions, whether land may be owned, and the headline transfer tax with a note on surcharges — hand-curated from official pages with the page and check date per row (secondary-sourced entries marked). Without `country` or `countries`, all 41 ranked free-first then by transfer tax, optionally within one `band`. Rules change by decree (Canada's ban to 2027; Australia's established-home ban to March 2027). `GET /api/property-rules.json?country=TH` · MCP `property_rules`. - **Statutory Employment Rules** (`/rules/?tab=employment`, added 13 Sep 2026): The floors a job's law sets in each of the 41 spine countries — minimum paid annual leave with its working- or calendar-day basis, minimum notice for employer and employee, the probation ceiling and the weekly-hours ceiling — hand-curated from labour authorities with the page and check date per row (secondary-sourced entries marked). A fact the law does not set is absent, never zero (the US sets no paid leave). Without `country` or `countries`, ranks by `metric`, most first unless `sort=fewest`. Statutory floors only. For information only — not legal advice; every response says so first. `GET /api/employment-rules.json?country=DE` · MCP `employment_rules`. - **Driving Rules Abroad** (`/safety/?tab=driving`, added 13 Sep 2026): Which side of the road, default speed limits in the unit signed there (never converted), the blood-alcohol limit, equipment the law requires carried and whether an International Driving Permit is needed (GOV.UK's per-country table), hand-curated with the authority page and check date per row. A limit not set nationally is absent (Germany's motorways). Without `country` or `countries`, ranks by `metric` within optional `drivesOn` and `idpRequired` filters. `GET /api/driving-rules.json?country=FR` · MCP `driving_rules`. - **Student Visas** (`/move/?tab=study`, added 5 Sep 2026): Student routes for the 41 countries — the funds a student must show (amount, currency, per month or year), work hours allowed in term, post-study stay in months, path to residency, the official page and check date; secondary-sourced entries marked. No tuition figures: no citable structured source exists. `funds` with optional `currency` and `per` matches (routes reached, near misses, no-figure routes, exclusions, no-route countries); `country` or `countries` lists. `GET /api/student-visas.json?funds=20000¤cy=GBP` · MCP `find_student_visas`. - **Which Country Fits Me** (`/move/?tab=fit`, added 19 Sep 2026): Countries ranked by a fit score blending the livability composite (internet speed, safety, healthcare access, air quality, English — measured) with how far a monthly USD budget goes against modelled essentials, by 0–10 weights per dimension (`cost`, `internet`, `safety`, `healthcare`, `air`, `english`, default 5). Region, budget and nomad-visa eligibility are filters, never weights. Free with explicit weights; describing preferences in words (POST `preferences`) is part of the paid plans and uses TypeSafe Jev to turn words into weights — Jev never ranks. A ranking of published figures, not a recommendation. `GET /api/country-fit.json?budget=2500&safety=9&healthcare=8` · MCP `find_country_fit`. - **Banking Access** (`/money/?tab=banking`, extended 17 Sep 2026): Whether a newcomer can open a personal account in each of the 186 spine countries (`yes`, `restricted`, `no`) with the documents usually asked for, the statutory deposit guarantee per depositor per bank in local currency and converted to USD, the country's instant payment systems (World Bank Project FASTT), the EU basic-account right under Directive 2014/92/EU where it applies, and a FATCA flag where banks commonly decline US citizens. A hand-curated register with the scheme or regulator page and check date per row (secondary-sourced entries marked, separately for the access rule and the figure); a country with no deposit-insurance scheme has no guarantee block, never a zero, and a country absent from FASTT is not a country without instant payments. `internationalOptions` describes kinds of cross-border account and what protects the money — categories only, never a named provider. Without `country`/`countries`, ranks by `metric` (`depositGuaranteeUsd`, `instantPaymentsSince`). For information only — not financial advice; every response says so first. `GET /api/banking-access.json?country=PT` · MCP `banking_access`. - **Account ownership & remittances** (`/money/?tab=banking`): The share of adults with an account at a financial institution or mobile-money provider (World Bank Global Findex, triennial — the survey year travels with each figure) and personal remittances received as a share of GDP. Says whether adults CAN bank, not whether a newcomer can open an account — that is `banking_access` above. `GET /api/banking.json?countries=GB,NG,IN` · MCP `compare_banking_access`. - **Country Dossier** (agent surface, no page): One country, every hub, the headline figures only — three to six per section (compare, costs, earn, move, work, money), each with the id of the source that produced it, the MCP tool to call for detail per section, and a `sources` list derived from what was included. A section the site has no data for is ABSENT, never null. `income` (monthly USD) unlocks the total-cost figures. About 5-8 KB: built so an agent answering "tell me about moving to Portugal" makes one call, not twelve. `GET /api/dossier.json?country=PT&income=5000` · MCP `country_dossier`. - **Datasets registry** (agent surface, no page): Every dataset behind the site's figures with the date it last changed, whether it is fetched by a script or reviewed by a person, the page it appears on and the refresh script. `since=YYYY-MM-DD` returns only the datasets strictly newer, so a cached figure can be re-fetched only when its dataset moved. No figures, so no attribution block. `GET /api/datasets.json?since=2026-09-01` · MCP `list_datasets`. - **Internet Quality** (`/work/?tab=connectivity`): Measured connection quality per country from Cloudflare Radar — median download/upload (Mbps) and median idle latency/jitter (ms), aggregated from real connections over 28 days rather than crowdsourced. Reports a call-quality verdict from latency and jitter, not bandwidth: a video call fails on latency and jitter long before it fails on throughput, which is why a download figure alone cannot answer “can I work from here”. Coverage is wider than the site's country pages, so it answers for places with no page here; a country with too little data is absent, never zero. `GET /api/connectivity.json` · MCP `compare_connectivity`. - **Runway Multiplier** (`/fire/?tab=runway`, merged into the Geo-Arbitrage tool): Bootstrap-buffer calculator for founders/freelancers — how many extra months of savings runway relocating buys. Splits burn into fixed (location-independent: subscriptions, debt, insurance) and local; only the local slice scales by the target's cost-of-living ratio (city-level via the Capital-to-Rural multiplier where a curated hub is chosen — Chiang Mai, Tbilisi, Buenos Aires, Medellín… — else national). Compares up to 3 hubs, any input currency. Answers "how much longer does my £20k last in Chiang Mai vs Tbilisi?". - **Runway API** (`GET /api/runway.json?savings=20000&burn=3000&fixed=800¤cy=GBP&home=GB&targets=TH:chiang-mai,AR:buenos-aires,GE`): `targets` is a comma list of `COUNTRY` or `COUNTRY:citySlug` (1–3). Returns the home baseline and each hub's monthly burn, runway months, extra months, run-out date and ×multiplier (sorted best-first), plus `fixedFloorMonths`. MCP tool: `calculate_runway`. - **Programmatic reference pages** (static, data-driven): `/ppp/{country-slug}` — cost of living vs the US per country (e.g. `/ppp/thailand`); `/salary/{home-slug}-to-{target-slug}` — fair-salary conversion for every country pair (e.g. `/salary/united-states-to-spain`); `/meeting/{cityA}-and-{cityB}` — working-hours overlap for major remote-work hub pairs (e.g. `/meeting/london-and-tokyo`); `/fire/{country-slug}` — FIRE numbers per lifestyle tier at 3–4.5% withdrawal rates per country (e.g. `/fire/thailand`); `/cost-of-living/{a-slug}-vs-{b-slug}` — everyday price comparison for every country pair (e.g. `/cost-of-living/united-kingdom-vs-thailand`); `/tax-residency/{country-slug}` — residency threshold + basis, secondary rules (e.g. Cyprus-60), resident tax rates, and expat regimes per country (e.g. `/tax-residency/spain`, `/tax-residency/cyprus`); `/livability/{country-slug}` — livability scores and what $2k/$3k/$5k budgets buy per country (e.g. `/livability/thailand`); `/wage-bands/{country-slug}` — local wage ladder (minimum, median, top 10%) per country (e.g. `/wage-bands/poland`); `/passport-power/{country-slug}` — visa-free destinations, rank and access breakdown per passport (e.g. `/passport-power/singapore`); `/runway/{city-slug}` — worked example of how far $40k stretches in a nomad hub vs the US (e.g. `/runway/chiang-mai`, `/runway/tbilisi`). Slugs are kebab-case country/city names; all pages carry FAQPage + BreadcrumbList JSON-LD and are listed in the sitemap. - **MCP Server** (`https://geo-parity.com/api/mcp`): A live Model Context Protocol server over Streamable HTTP, exposing every tool below as a callable MCP tool. Dual-era: it implements the modern per-request revision `2026-07-28` (including `server/discover`) **and** the initialization-handshake revisions `2025-11-25`, `2025-06-18`, `2025-03-26` and `2024-11-05`, echoing back whichever version your client asks for. **Open — no auth, no key, no sign-up**; metered by IP like the rest of the API, and an optional `Authorization: Bearer gp_live_…` only raises the ceiling. Add it to any MCP client, e.g. `claude mcp add --transport http geo-parity https://geo-parity.com/api/mcp`. It also serves **Resources** and **Prompts**, not tools alone. Resources are bulk reads that would otherwise cost a call per country: `geo-parity://countries` (every country with its price level, currency and which pages exist), `geo-parity://datasets` (every dataset with the date it last changed), `geo-parity://exchange-regimes` (the curated register of countries whose price-level sources disagree, with the evidence), `geo-parity://methodology/price-levels` (how a price level is decided and when one is withheld), and the template `geo-parity://country/{code}` for a one-read dossier. Prompts are workflows rather than tool wrappers - `relocation_brief`, `fair_local_salary`, `retire_on_budget`, `price_level_provenance`, `remote_work_setup` - each composing several tools in the order that makes the answer honest. Tools: `calculate_ppp`, `localize_salary`, `compare_countries`, `estimate_micro_costs`, `calculate_wage_bands`, `compare_contract`, `required_rate`, `find_fire_locations`, `calculate_runway`, `find_meeting_slot`, `compare_public_holidays`, `plan_team_calendar`, `estimate_employer_cost`, `compare_working_time`, `compare_connectivity`, `compare_inflation`, `remittance_cost`, `pension_abroad`, `compare_banking_access`, `compare_tax_rates`, `legal_profile`, `compare_vat`, `travel_advice`, `health_prep`, `compare_safety_stats`, `compare_pension_systems`, `find_retirement_visas`, `retire_on_budget`, `compare_effective_tax`, `withholding_tax`, `compare_business_entry`, `find_founder_visas`, `compare_health_capacity`, `compare_childcare_cost`, `compare_food_cost`, `compare_trade_customs`, `compare_tax_burden`, `compare_egov`, `property_rules`, `employment_rules`, `banking_access`, `driving_rules`, `find_student_visas`, `find_country_fit`, `country_dossier`, `list_datasets`, `check_travel_residency` (plus the legacy `check_schengen` / `check_residency` / `check_tax_residency_risk`), `find_nomad_visas`, `passport_power`, `rank_livability`, `compare_healthcare`, `compare_housing`, `compare_total_cost` and `select_region`. Each returns the same payload as its JSON endpoint, `attribution` block included — they are the same code path, not two implementations. Tools whose UI pages were merged keep their original names and endpoints. - **MCP server card** (`/.well-known/mcp.json`): machine-readable metadata for registries and crawlers — the tool schemas plus the `remotes` entry pointing at the server above. Generated from the same catalog the server reads, so the two cannot disagree. - **Markdown twins** (every indexable page, added 5 Sep 2026): append `index.md` to any page URL with a trailing slash — `https://geo-parity.com/ppp/thailand/index.md` — for the page's main content as Markdown: YAML front matter (`title`, `description`, `canonical`, `json` where the page has a JSON twin), the headings, prose, `data-agent` tables and lists, and a closing `Source:` line to quote. No nav, footer, scripts or map; about a tenth of the HTML's tokens. Each page's `` advertises it with ``. Written after every build from the built HTML, so it cannot drift from the page; served `text/markdown; charset=utf-8` with `X-Robots-Tag: noindex` and not listed in the sitemap. This is a URL, not `Accept: text/markdown` negotiation — the zone is on Cloudflare's Free plan, where Markdown for Agents is unavailable. `noindex` pages (account, auth, report previews) have no twin. - **WebMCP** (browser agents): every page registers the same 62 tools with the browser's `document.modelContext` (falling back to `navigator.modelContext`) when the API is present, so an AI agent running inside a visitor's browser can call them directly. Each call is a JSON-RPC `tools/call` to `/api/mcp` — the same code path as the MCP server, so the payload is identical — marked with an `X-Geo-Parity-Surface: webmcp` header. All tools are read-only calculators (`readOnlyHint`). Active for Chrome/Edge origin-trial visitors when the page carries the trial token, and for anyone with the WebMCP flag enabled. - **Discovery manifests**, all generated from the same catalogue: an RFC 9727 API catalog at `/.well-known/api-catalog` (advertised by a `Link: rel="api-catalog"` header on `/`), an Agent Skills index at `/.well-known/agent-skills/index.json` with the skill document at `/.well-known/agent-skills/geo-parity/SKILL.md`, and an Agentic Resource Discovery manifest at `/.well-known/ard.json` (also served as `/.well-known/ai-catalog.json`; `Agentmap:` in robots.txt). robots.txt carries Content Signals `search=yes, ai-input=yes, ai-train=yes`. - **OpenAPI 3.1 spec** (`/openapi.json`): Machine-readable description of every endpoint, parameter, and error convention — import it into any HTTP tool-calling framework. ## Data Figures are real, drawn from multiple providers and stored in a swappable registry (`/src/data/datasets`). Each dataset shares the same shape and a US baseline of `1.0`. `pppIndex` is a US-relative price level derived as `PPP conversion factor ÷ market exchange rate` (or rebased to US = 1.0 for Penn World Table), using the latest year available per country (each country carries its reference `year`). - **`consensus`** — Per-country **median** across the GDP-based providers below. Default source; the most robust single figure. - **`worldbank`** — World Bank GDP-based price level (`PA.NUS.PPP ÷ PA.NUS.FCRF`). ~41 countries. - **`imf`** — IMF World Economic Outlook implied PPP (`PPPEX ÷ market exchange rate`). Broadest coverage, recent estimates. - **`oecd`** — OECD PPP-for-GDP price level (`DSD_NAMAIN10@DF_TABLE4: PPP_B1GQ ÷ EXC_A`). OECD members + key partners only (~34 countries). - **`pwt`** — Penn World Table price level of GDP (`pl_gdpo`, rebased to USA = 1.0). Academic benchmark. - **`worldbank-cons`** — World Bank household-consumption price level (`PA.NUS.PRVT.PP ÷ PA.NUS.FCRF`). Reflects a consumption basket. - **`bigmac`** — The Economist Big Mac index: a US-relative consumer price level from the price of a single standardized good (`local Big Mac price in USD ÷ US price`). Relatable but narrow — ~40 countries, one product; euro-area members share the Euro-area price. - **`eurostat`** — Eurostat surveyed Price Level Indices for Actual Individual Consumption (`prc_ppp_ind`, EU27=100), rebased to US=1.0. A direct observed basket comparison (not GDP-derived), covering European countries plus the US anchor and Japan — the strongest independent cross-check for the ~19 countries it covers. - **`factbook`** — CIA World Factbook coverage filler: a US-relative price level for ~100 micro-states and territories the macro sources ignore (Monaco, Bermuda, Cayman, Tuvalu, Malta, Georgia, Qatar…), derived as `GDP(official exchange rate) ÷ Real GDP(PPP)` normalized to US=1.0. Coarse whole-economy estimate, not a consumer basket — for reaching obscure locations only. Coverage and reference years differ by source, so the set of valid `target` codes depends on the selected `source` (e.g. Thailand and Nigeria appear in most sources but not OECD or Eurostat). Data is refreshed at build time via `npm run data:fetch` (World Bank + IMF + OECD + Penn World Table), `npm run data:bigmac` (The Economist Big Mac index), `npm run data:eurostat` (Eurostat observed price levels), `npm run data:factbook` (CIA World Factbook micro-states), and `npm run data:fx` (World Bank market exchange rates for every entity — ~140 currencies, with territories filled by currency inheritance). Reference data (not PPP): **Airport lookup** (`GET /api/airports.json?country=TH` | `?iata=BKK` | `?near=13.7,100.5&limit=5`): the scheduled-service large/medium airports from the open OurAirports dataset — by IATA code, by country, or nearest to a coordinate with great-circle distance. A static travel backbone for distance/nearest-airport queries. **Coverage fallback.** When a `target`/country isn't in the chosen (or default) source and no `source` was pinned, the PPP calculator (`/api/calculate.json`) and cost comparison (`/api/micro-costs.json`) fall back across sources — reaching the ~100 Factbook micro-states/territories rather than erroring. Such responses carry `coverage: { approximate: true, note }` because the Factbook figure is a coarse whole-economy estimate. Pinning an explicit `source` disables the fallback (it will error if the code isn't in that source). **Sub-national (city) costs.** The `calculate.json` and `micro-costs.json` APIs accept optional city slugs (`city` / `baseCity`+`targetCity`, e.g. `london`, `san-francisco`, `hull`). The engine applies a Capital-to-Rural multiplier on top of the national price level: curated per-city overrides where known, US-metro BEA Regional Price Parities for US cities, else a population-tier heuristic (tier-1 city >1M ×1.15, tier-2 ×1.0, rural ×0.85). Unknown city → national figure. Estimates for orientation, not measured local prices. US metro data refreshes via `npm run data:bea` (requires a free BEA_API_KEY). ## Attribution Every successful JSON response carries an `attribution` block, so an agent never has to guess where a figure came from or reconstruct a link: - `sources[]` — each provider behind the figure: dataset `id` (the same value the `source` param takes), `label`, the provider's own `attribution` line, `updated` (when we last refreshed it), `year` (reference year of the figures) and `url` (where the provider publishes it). - `citation` — one ready-to-quote sentence, e.g. `Geo-Parity — Cost of Living & Salary Comparison. Data: World Bank (2024). https://geo-parity.com/ppp/thailand/`. - `permalink` — the human-readable page answering that exact query. Programmatic pages are preferred over the tool root, so `/api/calculate.json?target=TH` cites `/ppp/thailand/`. - `terms` — free to use and quote with attribution; figures are estimates, not advice. Error responses deliberately carry no `attribution`: a 422 has nothing to cite, and the message matters more. `GET /api/passport.json` without a `country` is the one exception to the shape — its league table keeps an older top-level `attribution` **string**, unchanged so existing callers do not break. Programmatic pages also advertise their JSON twin in the HTML head: ``. Landing on `/cost-of-living/united-kingdom-vs-thailand/` therefore costs one hop to structured data rather than an HTML parse. ## Access & rate limits Every endpoint above stays **free, open and key-free**, CORS-enabled, with no sign-up. There are two ceilings: a **monthly quota** (the allowance) and a **per-minute burst** (so no one caller saturates the service). - **Anonymous (no key): 1,500 requests/month per IP, 30/minute.** No registration. - **With an API key:** 2,000/month on a free account, 4,000 on Lite, 20,000 on Pro, 75,000 on Pro Plus, 150,000 on API Starter, 600,000 on API Scale. Bursts are 60, 60, 90, 150, 200 and 300/minute respectively. See `/pricing`. Quotas reset on the 1st (UTC). A key is metered per **account**, not per key, so holding several keys does not raise the allowance. Human-readable setup, the full quota ladder and the error codes: `/developers/`. Send a key as `Authorization: Bearer gp_live_…` (or `?key=…` where headers can't be set). Keys are created at `/account` and only raise the ceiling — they never change the response. Every response carries `X-RateLimit-Limit`/`-Remaining`/`-Reset` for the minute window and `X-Quota-Limit`/`-Remaining`/`-Reset` for the month (both epoch seconds on reset). Over either ceiling returns HTTP **429** with a `Retry-After` header and one of two codes — treat them differently: - `RATE_LIMITED` — too fast. `retryAfterSeconds` is under a minute; back off and retry. - `QUOTA_EXCEEDED` — the month's allowance is spent. Retrying will not help until the 1st; get a key or a plan at `/pricing`. Paid plans are billed through Polar, which acts as merchant of record and adds any local tax at checkout; payment never affects the numbers a tool or endpoint returns. ## Notes - Figures are real, drawn from the providers above (World Bank, IMF, OECD, Penn World Table), and are illustrative — informational only, not investment, relocation, tax, or legal advice. - The math engine is pure and stateless: identical inputs always yield identical outputs across the UI and the API.