Skip to main content

Agent guide: querying Internacia data

Platform-neutral workflow for looking up countries, borders, org membership, and entity linking. Works with Cursor, Claude Code, Copilot, Codex, and any agent with file or API access.

Before querying​

  1. Read llms.txt for join keys and gotchas (compact index).
  2. Use exported datasets — do not parse data/countries/*.yaml or data/intblocks/**/*.yaml unless authoring.
  3. Full consumption contract: ai-consumers.md.
  4. Verified recipes: query-examples.md (DuckDB), query-examples-polars.md (Polars / Parquet), query-examples-r.md (R / dplyr), query-examples-observable.md (Observable / Plot).

Access paths​

MethodPath / URL
DuckDB (preferred, in-repo)data/datasets/internacia.duckdb
Parquetdata/datasets/countries.parquet, intblocks.parquet, blocktypes.parquet, memberships.parquet
Version checkSELECT * FROM _meta; or data/datasets/*.manifest.json
Python SDK (no full checkout)https://github.com/datenoio/internacia-python
HTTP APIhttps://github.com/datenoio/internacia-api (self-host only; no public hosted instance)

Join keys​

EntityPrimary keyAlso useful
Countrycode (alpha-2)iso3code, numeric_code, wikidata_id
Intblockidwikidata_id, blocktype, partof
Membershipincludes[].id → country codeNot includes[].name
Blocktype taxonomyblocktypes.idmatches values in intblocks.blocktype list
Bordersalpha-3 in bordersjoin on neighbor iso3code

Scope (in / out)​

In scope: ISO identifiers, geography, demographics with source/year, World Bank classifications, languages/currencies/timezones, org membership, Wikidata links.

Out of scope: HDI, GDP, government type, internet penetration, time-series indicators — enrich downstream from other datasets.

Canonical queries (DuckDB)​

Version and schema:

SELECT dataset, version, schema_hash, build_date FROM _meta;

Current ISO countries (249):

SELECT code, name FROM countries
WHERE code_status = 'official_iso3166_1' ORDER BY code;

UN members:

SELECT code, name FROM countries WHERE un_member = true ORDER BY name;

Country attribute fields (former attribute intblocks — prefer these over retired LHTRAFFIC / DVD_* / WS* / LS* / *GAUGE ids; remap via attribute_intblock_migrations.json):

SELECT code, name FROM countries WHERE car_side = 'left';
SELECT code, name FROM countries WHERE dvd_region = 1;
SELECT c.code, c.name FROM countries c, UNNEST(c.writing_directions) t(d) WHERE d.id = 'rtl';
SELECT c.code, c.name FROM countries c, UNNEST(c.legal_systems) t(l) WHERE l.id = 'common_law';

Land neighbors (alpha-3 borders — join on iso3code):

SELECT n.code, n.name
FROM countries th,
UNNEST(th.borders) AS b(neighbor_iso3)
JOIN countries n ON n.iso3code = b.neighbor_iso3
WHERE th.code = 'TH'
ORDER BY n.name;

Org members (NATO example):

SELECT m.id AS member_code, m.name AS member_label, m.status
FROM intblocks i, UNNEST(i.includes) AS t(m)
WHERE i.id = 'NATO' AND m.type = 'country';

Orgs that include a country (Laos example):

SELECT i.id, i.name
FROM intblocks i, UNNEST(i.includes) AS t(m)
WHERE m.id = 'LA' AND m.type = 'country'
ORDER BY i.name;

Resolve intblock alias before join (Python):

import json
import pandas as pd

aliases = {a["alias"]: a["target"] for a in json.load(open("data/datasets/intblocks_aliases.json"))}
blocks = pd.read_parquet("data/datasets/intblocks.parquet")
blocks["id"] = blocks["id"].map(lambda x: aliases.get(x, x))

Structured population field (Pandas — .struct needs the Arrow dtype backend):

df = pd.read_parquet("data/datasets/countries.parquet", dtype_backend="pyarrow")
pop = df["population"].struct.field("value")

Common mistakes​

MistakeCorrect approach
Join borders on alpha-2Use alpha-3; join borders → iso3code
Join intblocks on includes[].nameUse includes[].id (country code)
Assume 256 codes are all ISO officialFilter code_status = 'official_iso3166_1'
Read plain number from populationUse struct field .value (pandas: dtype_backend="pyarrow"; Polars: .struct.field("value"))
Expect HDI/GDP in this datasetOut of scope; enrich downstream
Ignore alias remapsLoad intblocks_aliases.json before joining on intblock id

DuckDB struct lists​

Unnest list-of-struct columns: UNNEST(i.includes) AS t(m) then reference m.id, m.type, m.status.