API

Every table is also published as plain JSON files at fixed addresses. There is no key, no sign-up and no rate limit: they are static files, so you can fetch them from a script, a spreadsheet or a browser.

The addresses

/api/index.json
The list of datasets.
/api/<dataset>.json
One dataset: description, licence, citation and its tables with their addresses.
/api/<dataset>/<table>/page-1.json
A table’s rows in pages of 5,000 (one object per row), with next and prev links, pages and the total.
/api/<dataset>/<table>/schema.json
Each column’s name, label and plain definition.
/download/<dataset>/<table>.csv
The whole table as CSV (UTF-8, with a header row). Tables over 20 MB are published compressed instead, as .csv.gz: the list below links each table’s file.

There is no whole-table JSON file: the largest tables would be 30 to 75 MB, more than the web host takes per file. Follow the pages from page-1.json (the example below does it in a few lines), or take the CSV.

Values are text exactly as the source tables hold them, so numbers keep the digits the document printed. Empty means not stated.

Examples

Command line

curl https://data.oscarleo.com/api/citizenship-by-investment/numbers/page-1.json

JavaScript

let url = "https://data.oscarleo.com/api/citizenship-by-investment/numbers/page-1.json";
const rows = [];
while (url) {
  const page = await (await fetch(url)).json();
  rows.push(...page.rows);
  url = page.next && new URL(page.next, url).href;
}

Python (pandas)

import pandas as pd
df = pd.read_csv("https://data.oscarleo.com/download/citizenship-by-investment/numbers.csv.gz", dtype=str)  # .csv.gz files are read as they are

What the files contain

  • The same rows the tables on this site show: numbers we would have had to work out ourselves, and numbers a later correction replaced, are left out.
  • status says what kind of figure each number is. derived means calculated by us from official records (the recipe is in notes).
  • reading implied means the document states the number only in words; unit_basis inferred or guessed means the unit is not printed. Treat those with care.
  • Rows point to the sources table through source_id.

Every table

Residence by investment

/api/residence-by-investment.json

Whistleblower rewards

/api/whistleblower-rewards.json

Licence

CC BY 4.0: Free to use, share and adapt, also commercially, as long as you credit the source. Credit “Oscar Leo, https://data.oscarleo.com”. Each dataset’s page has a ready-made citation.