firmapanel / trade-country-data
Trade-focused country reference data for procurement, logistics, customs, sourcing, and import-export software.
Package info
github.com/FirmaPanel/trade-country-data
Language:Python
pkg:composer/firmapanel/trade-country-data
Requires
- php: >=8.1
- ext-json: *
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-07 18:40:55 UTC
README
Trade-focused country reference data for procurement, logistics, customs, sourcing, and import-export software.
Direct downloads: Raw JSON · Raw CSV
npm: npm install @firmapanel/trade-country-data
PyPI: python -m pip install firmapanel-trade-country-data
Composer: composer require firmapanel/trade-country-data
FirmaPanel tools: Free procurement and import-export tools
This project is not another general-purpose list of capitals, flags, calling codes, or time zones. It connects stable country identifiers to currencies, trade-group memberships, customs relationships, and verified official trade resources.
The project is maintained by FirmaPanel, a B2B supplier discovery and procurement platform.
Why this dataset exists
International trade applications often need more than a country selector. Procurement, sourcing, customs, and logistics workflows need normalized answers to questions such as:
- Which trade groups include this country?
- Does the country participate in a documented customs relationship?
- Where is the official customs or import-export guidance?
- Which organization represents the country in national standardization?
- Which source supports each published value, and when was it checked?
This repository supplies those joins without publishing volatile tariff rates, duty rates, tax percentages, sanctions status, trade volumes, or other values that should be obtained from a current legal or operational source.
Snapshot and coverage
The current release is v0.3.0, with an as_of_date of 2026-09-07.
Coverage figures are calculated from the committed data:
| Dataset area | Coverage |
|---|---|
| ISO 3166-1 country and area records | 249 |
| Records joined to a UN M49 country/area row | 248 |
| Records with a UN M49 regional assignment | 247 |
| Records with one or more active tender currency codes | 248 |
| Country/customs-territory WTO members | 165 |
| Trade groups and agreements | 11 |
| Customs relationships | 5 |
| Countries with a verified customs authority | 65 |
| Countries with a verified official trade portal | 65 |
| Countries with a verified trade agency | 65 |
| Countries with a verified national standards body | 65 |
Print the calculated table or verify that these published figures are current:
python3 scripts/report_coverage.py python3 scripts/report_coverage.py --check
Official-resource coverage is intentionally conservative. Missing records use
null or an empty array and never a fabricated placeholder.
The reviewed official-resource set covers 65 countries. It now includes every EU member state and every direct-country member in the G20, EFTA, GCC, ASEAN, and the active MERCOSUR state-party set represented by this snapshot. Shared official services are modeled once and linked to each country they serve.
The landlocked field is also conservative in this release. The 32 entries
marked true are supported by the UN M49 Land Locked Developing Countries
classification. Every other entry is null; null does not mean coastal.
Published data
JSON files are canonical. The country CSV is a deterministic generated export.
| File | Purpose |
|---|---|
countries.json |
Compact country and area records with stable references |
countries.csv |
Flat spreadsheet and database export |
trade-groups.json |
Typed memberships for trade groups, organizations, and agreements |
customs-relationships.json |
Scoped customs unions and arrangements |
customs-authorities.json |
Verified national customs authorities |
official-trade-portals.json |
Official import, export, customs, and trade guidance |
trade-agencies.json |
Trade and export-promotion organizations |
standards-bodies.json |
Verified national standards bodies |
regions.json |
UN M49 region hierarchy |
sources.json |
Machine-readable provenance registry |
Every JSON file has the same dataset envelope:
{
"schema_version": "0.3.0",
"as_of_date": "2026-09-07",
"record_count": 249,
"records": []
}
Quick start
Clone and run the dependency-free integrity checks with Python 3.9 or later:
git clone https://github.com/FirmaPanel/trade-country-data.git
cd trade-country-data
python3 scripts/build_csv.py --check
python3 scripts/validate.py
Read a country record in Python:
import json from pathlib import Path document = json.loads(Path("data/countries.json").read_text(encoding="utf-8")) turkiye = next(record for record in document["records"] if record["iso2"] == "TR") print(turkiye["trade_group_ids"]) print(turkiye["customs_relationship_ids"])
Or install the dependency-free Python package:
python -m pip install firmapanel-trade-country-data
from firmapanel_trade_country_data import load_dataset countries = load_dataset("countries") turkiye = next(record for record in countries["records"] if record["iso2"] == "TR") print(turkiye["trade_group_ids"])
See the PyPI package documentation for dataset, schema, and CSV access.
PHP applications can install the Composer package:
composer require firmapanel/trade-country-data
<?php use FirmaPanel\TradeCountryData\TradeCountryData; require __DIR__ . '/vendor/autoload.php'; $countries = TradeCountryData::loadDataset('countries'); $turkiye = array_values(array_filter( $countries['records'], static fn (array $record): bool => $record['iso2'] === 'TR', ))[0]; print_r($turkiye['trade_group_ids']); print_r($turkiye['customs_relationship_ids']);
See the Composer package documentation for dataset, schema, CSV, and canonical file-path access.
Fetch the same canonical data in JavaScript (Node.js 18 or later):
const url = "https://raw.githubusercontent.com/FirmaPanel/trade-country-data/main/data/countries.json"; const response = await fetch(url); if (!response.ok) { throw new Error(`Dataset request failed: ${response.status}`); } const { records } = await response.json(); const turkiye = records.find((record) => record.iso2 === "TR"); console.log(turkiye.trade_group_ids); console.log(turkiye.customs_relationship_ids);
Or install the zero-dependency npm package, which includes TypeScript types and supports both ESM and CommonJS:
npm install @firmapanel/trade-country-data
import { countries, tradeGroups } from "@firmapanel/trade-country-data"; const turkiye = countries.records.find((record) => record.iso2 === "TR"); console.log(turkiye.trade_group_ids); console.log(tradeGroups.as_of_date);
Raw JSON, CSV, and JSON Schema files are also exported. See the npm package documentation for all entry points.
Or query the published JSON without cloning:
curl -fsSL \ https://raw.githubusercontent.com/FirmaPanel/trade-country-data/main/data/countries.json \ | jq '.records[] | select(.iso2 == "TR")'
Country record
Country records remain compact and link to richer datasets through stable IDs:
{
"name": "Türkiye",
"official_name": "Republic of Türkiye",
"iso2": "TR",
"iso3": "TUR",
"numeric_code": "792",
"region_id": "asia",
"subregion_id": "western-asia",
"intermediate_region_id": null,
"currency_codes": [
"TRY"
],
"trade_group_ids": [
"group-of-twenty",
"world-trade-organization"
],
"customs_relationship_ids": [
"eu-turkiye-customs-union"
],
"wto_member": true,
"customs_authority_id": "tr-general-directorate-of-customs",
"trade_portal_ids": [
"tr-easy-export-platform"
],
"trade_agency_ids": [
"tr-turkiye-exporters-assembly"
],
"standards_body_id": "tr-turkish-standards-institution",
"landlocked": null,
"aliases": [],
"source_ids": [
"un-m49",
"unicode-cldr"
]
}
The abbreviated source_ids above are illustrative; the canonical record
contains every applicable source reference. See the field reference
and data model for the complete contract.
Relationship semantics
The project deliberately uses trade groups, not a generic trade_blocs
field. Each group has a controlled relationship_type that distinguishes:
- customs unions;
- free-trade areas and trade agreements;
- economic and political unions;
- international or intergovernmental organizations; and
- informal intergovernmental groups.
Participants are typed as either country or trade-group. A G20 reference to
the African Union, for example, cannot be confused with an ISO country code.
Membership statuses distinguish members and parties from signatories or
suspended participants.
Customs relationships include a scope note. They must never be interpreted as a promise that every product receives the same treatment.
Scope methodology
The country scope is the current 249-entry ISO 3166-1 assigned set represented by
the iso-codes source package. Of these, 248 join to the English UN M49 country
or area table. The single ISO-only entry is retained with its M49 region fields
set to null; Antarctica is present in M49 but has no regional assignment.
This approach includes countries, dependencies, territories, and special areas with officially assigned ISO codes. It excludes user-assigned, reserved, transitional, and deleted codes. Inclusion is a coding and interoperability decision and does not express a position on political status, recognition, borders, or sovereignty.
Currency arrays contain active tender currencies from Unicode CLDR at the
dataset as_of_date. An empty array means no value was published by that method;
it does not mean that commerce cannot occur in the area.
Read SOURCES.md and the source policy before interpreting or extending the dataset.
Validation and development
Install the standards-validation dependencies and run the complete CI-equivalent check:
python3 -m pip install -r requirements-dev.txt make check
The checks verify:
- every JSON document against JSON Schema Draft 2020-12;
- coverage metrics in this README against the canonical JSON;
- dataset metadata, controlled values, dates, IDs, and HTTPS URLs;
- unique ISO codes, record IDs, members, participants, and resource URLs;
- every country, group, relationship, region, resource, and source reference;
- consistency between WTO flags and WTO group membership;
- absence of prohibited volatile data fields; and
- byte-for-byte synchronization of canonical JSON and generated CSV.
Run the unit suite with measured branch coverage:
make coverage
Continuous integration requires at least 95% total coverage.
Do not edit data/countries.csv directly. Edit the canonical JSON, run
python3 scripts/build_csv.py, and commit both files. See the
maintenance guide for the full workflow.
Repository layout
trade-country-data/
├── data/ # Canonical JSON and generated country CSV
├── docs/ # Field, model, source, maintenance, and legal guides
├── schema/ # JSON Schema Draft 2020-12 contracts
├── scripts/ # Build and validation utilities
├── tests/ # Unit and CLI regression tests
├── .github/ # CI workflow and contribution templates
├── SOURCES.md # Human-readable provenance methodology
├── ATTRIBUTION.md # Reuse and attribution guidance
├── CONTRIBUTING.md # Contribution and source requirements
├── CITATION.cff # Citation metadata
└── LICENSE # CC BY 4.0 for the compilation and documentation
Versioning and maturity
Releases follow semantic-versioning principles for the dataset contract:
- patch releases correct data, URLs, or source metadata;
- minor releases add records or backward-compatible fields; and
- major releases make incompatible schema, ID, or classification changes.
The project remains v0.x while official-resource coverage expands and the
schemas receive real-world use. A v1.0.0 release requires reviewed provenance,
stable schemas, complete core identity data, and fully resolving relationships.
Tagged releases are recommended for reproducible downstream use.
Contributing
Corrections and carefully sourced additions are welcome. Contributions must identify the affected record, provide an authoritative source URL and retrieval date, and explain any replacement of an existing value. Unsourced trade or customs relationships will not be accepted.
Read CONTRIBUTING.md and the Code of Conduct before opening an issue or pull request.
License and attribution
FirmaPanel's original compilation, normalization, schemas, and documentation are
available under the Creative Commons Attribution 4.0 International License.
Maintenance utilities in scripts/ are available under the
MIT License.
Some normalized facts originate from upstream sources with their own terms. CC BY 4.0 does not replace those terms or grant rights in ISO standards, legal texts, organization names, or third-party material. See SOURCES.md and ATTRIBUTION.md.
Preferred attribution:
FirmaPanel Trade Country Data, version 0.3.0, by FirmaPanel, https://doi.org/10.5281/zenodo.22639118, licensed under CC BY 4.0.
Disclaimer
This repository provides general reference data for software and informational use. Trade agreements, customs rules, tariffs, sanctions, taxes, and import/export requirements may change and may depend on product, origin, destination, and other factors.
Always verify current requirements with the relevant official authority before making legal, customs, tax, compliance, or commercial decisions. See the full legal and accuracy disclaimer.
About FirmaPanel
FirmaPanel connects B2B product discovery with private inquiries, supplier quotations, and trade tracking. Trade Country Data is part of FirmaPanel's open-data initiative for procurement, sourcing, and international trade developers, maintained through the FirmaPanel GitHub organization.