Part of a Data Solution
- Explore →
Postal Codes Solution
Every worldwide postal-code dataset in one bundle — the ultimate global reference for precise postal codes.
Premium
You're viewing a free sample
Get the complete dataset — all rows and files — delivered instantly after checkout, with lifetime access to the latest version.
- Secure checkout via Stripe
- Instant download after payment
- Lifetime access to the latest version
- Creative Commons Attribution 4.0 — postal layer (MCMC, via data.gov.my) license
API Access
Access dataset files directly from scripts, code, or AI agents.
Browse dataset files
API Access
Access dataset files directly from scripts, code, or AI agents.
Each file has a stable URL (r-link) that you can use directly in scripts, apps, or AI agents. These URLs are permanent and safe to hardcode.
Start with these files — they give you everything you need to understand and access the dataset.
- 1. Fetch datapackage.yaml to inspect schema and resources
- 2. Download data resources listed in datapackage.yaml
- 3. Read README.md for full context
Data Files
postal-codes-my-sample
| Field | Type | Description | Constraints | Title |
|---|---|---|---|---|
| country_code | string | ISO 3166-1 alpha-2 country code — always MY | { "pattern": "^MY$", "required": true } | Country Code |
| postal_code | string | 5-digit Malaysian postcode. | { "pattern": "^\\d{5}$", "required": true } | Postal Code |
| place_name | string | City/town — the tier postcodes are assigned at. | { "required": true } | Place Name |
| admin_name1 | string | Negeri (state) / Wilayah Persekutuan (federal territory). | { "required": true } | Administrative Name 1 |
| admin_code1 | string | ISO 3166-2:MY code, MY- prefix stripped. | { "required": true } | Administrative Code 1 |
| admin_name2 | string | RESERVED — not populated. No licence-clean source currently maps place_name to a district (daerah); see project notes. | Administrative Name 2 | |
| admin_code2 | string | RESERVED — not populated. | Administrative Code 2 | |
| admin_name3 | string | RESERVED — not populated. No licence-clean mukim source was found; Malaysia's Copyright Act 1987 s.11 grants copyright to government works by default, unlike some other countries in this pipeline. | Administrative Name 3 | |
| admin_code3 | string | RESERVED — not populated. | Administrative Code 3 | |
| latitude | number | WGS84 latitude, decimal degrees, max 5 dp. From GeoNames, joined by postal code. | Latitude | |
| longitude | number | WGS84 longitude, decimal degrees, max 5 dp. From GeoNames, joined by postal code. | Longitude | |
| accuracy | string | GeoNames accuracy of latitude/longitude. GeoNames documents 1=estimated, 4=geonameid, 6=centroid of addresses or shape; other values (e.g. 3) occur upstream without documentation. Empty where GeoNames gives none. | Accuracy | |
| alternative_city_name | string | RESERVED — not populated on this build pass. | Alternative City Name |
Download
Download sample CSVAbout
- Last updated
- 3 October 2026
- Total rows
- 100
- Format
- CSV
- File size
- 5.46 kB
About this dataset
Malaysia (MY): migration notes
Internal record of the P5 migration from the old scripts to the producer: the discrepancies found, their causes, and who decided what. This is a dated record, so the numbers are as of the migration and not kept current. It is not shipped in the zip.
- Issue: pc-28e.7.37 (closed 2026-10-03)
- Commit:
c45efd0(worktree commitd57dfae, landed unchanged), batch 5 - Parity verdict:
format-only(CRLF → LF); passes the gate - Producer:
custom, refresh disabled
Sources
| Input | URL | Notes |
|---|---|---|
| MCMC Postcode Dataset, via data.gov.my | https://storage.data.gov.my/dictionaries/postcodes.csv | Stable URL (catalogue page data.gov.my/data-catalogue/poskod). Postal code, state, city |
| GeoNames postal export | https://download.geonames.org/export/zip/MY.zip | Coordinates only, joined on postal code |
Both are the inputs the old fetch_source.py already downloaded; nothing was switched.
Parity against the live zip (2026-10-03)
Rows: 2,931 live and 2,931 fresh, none only on one side. 0 changed cells. With CRs stripped, the live my.csv and the fresh data/my.csv are byte-identical, so neither upstream had drifted since the live build.
The public 100-row sample (postal.datahub.io/my/my.csv) came out unexplained with 92 unclassified cells (informational only). The agent didn't look into it.
Decisions
| Decision | By | Basis |
|---|---|---|
| Land without asking | Standing rule (row_order/CRLF-only, user, 2026-10-02) | format-only, equal rows, 0 changed cells |
| Remove row, distinct-code/place, coordinate-row and duplicate-PK counts from README ("8.6% of rows" → "Some rows"); keep "16 of 16 states" | Agent, per the README counts rule | ATTRIBUTION.txt untouched |
| Accuracy description replaced with the standard GeoNames wording | Agent, per the producer brief |
Transforms carried over (unchanged)
Folded from fetch_source.py → build_postal.py → build_deliverable.py → run_qa.py (the scripts README, delivery_README_template.md and publish_r2.py deleted):
- Every MCMC field is whitespace-trimmed first. Untrimmed, "Negeri Sembilan " and "Bestari Jaya " create a fake 17th state and a duplicate row. Exact (state, city, postcode) duplicates are then dropped.
- Coordinates joined on postal code only: the single GeoNames point for the code if there is one, else the unique city-name match (case- and space-insensitive), else empty. Never averaged.
- lat/lon rounded to 5 dp with trailing zeros stripped; accuracy passed through.
admin_code1= ISO 3166-2:MY without theMY-prefix, keyed on MCMC's state spelling.admin_name2/3,admin_code2/3andalternative_city_namestay empty.- Rows sorted by (admin_code1, postal_code, place_name).
- Old asserts and QA checks are now
ProducerErrors: unknown state, postal code not 5 digits, any of the 16 states missing, duplicate (postal_code, place_name), coordinates outside Malaysia's bounding box. No row-count assert.
Open questions
- The README Fields table still has a "Fill" column with row-derived percentages (e.g. 91.4%), and the Contents table still lists
validation_report.json, which neither the live nor the fresh zip contains. Flagged by the agent; left for the end-of-epic sweep (pc-hfz). .licensing-notes.mdstill carries counts ("2,931 rows"); left for pc-hfz.
Provenance
Reconstructed 2026-10-05 from the agent transcript d33e1b7e-5027-498a-a97f-ba914ee2524e/subagents/agent-a34cbfef792ad386c.jsonl, the orchestrator session d33e1b7e-… (landing under the standing rule), the commit message, the bd close reason and docs/parity/p5.md.