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 (GeoNames) 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.yml to inspect schema and resources
- 2. Download data resources listed in datapackage.yml
- 3. Read README.md for full context
Data Files
Postal Codes Data Resource for France, FR
| Field | Description | Title |
|---|---|---|
| country_code | ISO 3166-1 alpha-2 code for the country. | Country Code |
| postal_code | Postal code for the location. | Postal Code |
| place_name | Name of the city, town, or place. | Place Name |
| admin_name1 | Primary administrative division (e.g., state, region). | Administrative Name 1 |
| admin_code1 | Code for the primary administrative division. | Administrative Code 1 |
| admin_name2 | Secondary administrative division (e.g., county, district). | Administrative Name 2 |
| admin_code2 | Code for the secondary administrative division. | Administrative Code 2 |
| admin_name3 | Tertiary administrative division (e.g., municipality, borough). | Administrative Name 3 |
| admin_code3 | Code for the tertiary administrative division. | Administrative Code 3 |
| latitude | Latitude coordinate of the place. | Latitude |
| longitude | Longitude coordinate of the place. | Longitude |
| accuracy | Accuracy level of the latitude and longitude coordinates. | Accuracy |
| alternative_city_name | Alternative name(s) for the city or place. | Alternative City Name |
Download
Download sample CSVAbout
- Last updated
- 24 August 2026
- Total rows
- ...
- Format
- CSV
- File size
- 4.55 MB
About this dataset
France (FR) — internal licensing notes
Status: RESOLVED AND REPUBLISHED (2026-08-24). Provenance identified, licence clean and now attributed, and the severe data-quality defect that was found alongside it has been fixed and republished to R2. See "Corrected republish — executed" at the foot of this file for what shipped.
Two separate findings below; don't conflate them.
The problem as filed (datahub-next#941 §3, opened 2026-08-08)
"France — a single raw CSV with no research.json, qa_log, validation report
or README. Provenance is unknowable; cannot be sold at any price until
re-sourced."
The "no provenance record" half is accurate and confirmed. The "unknowable" half is not — the data fingerprints cleanly against a known source.
Provenance — identified with HIGH confidence as GeoNames FR
Investigated 2026-08-24 by forensic fingerprinting (the same method used for Isle of Man), because no documentary trace survives anywhere:
countries/FRA/in fedex-agents-prototype holds exactly one file and no research.json, script, qa_log or README. Git shows it was added wholesale in a single commit (bcd0fcb, 2026-05-11, 51,661 lines, no accompanying code).- The postal-codes repo has no France parser —
scripts/custom_parsing_scripts/contains Brazil and Canada only, andgit log --allshows no France script ever existed.
Finding 1 — the file actually ON SALE is GeoNames, and the match is exact.
R2 fr/fr.csv has 51,611 data rows; GeoNames FR.txt has 51,611 lines.
Every row was traced:
| Bucket | Rows |
|---|---|
| Direct match on (postal code, place name) | 47,677 |
| Match once the zero-padding bug is undone | 3,281 |
| CEDEX / SP special codes | 653 |
| Genuinely unexplained | 0 |
Coordinates, admin_code1/2/3 and accuracy all carry through
identically (e.g. Paris 75000 → 48.8534, 2.3488, accuracy 5).
Correction (2026-08-24, verified during the rebuild): an earlier draft of
this note said admin_code1 uses GeoNames' "pre-2016 numeric region codes …
not an INSEE or ISO scheme". That is wrong on both counts. The current
GeoNames FR export carries the post-2016 13-region structure with official
INSEE region codes — 84 Auvergne-Rhône-Alpes, 27 Bourgogne-Franche-Comté,
44 Grand Est, 32 Hauts-de-France, 75 Nouvelle-Aquitaine, 76 Occitanie
are all post-2016 merged regions, and the export contains exactly 13 distinct
region codes, not the pre-2016 22. 11 Île-de-France and 94 Corse merely
happen to be unchanged across the reform, which is what made the older reading
look plausible. No region remapping is needed or wanted for France — unlike
Italy, where GeoNames' admin_code1 genuinely is a non-official internal
numbering that had to be replaced.
Finding 2 — the local FedEx-schema file is also GeoNames-derived, not a
second independent source. countries/FRA/data/France_2026_updated.csv
(51,660 rows) matches GeoNames at 92.65% on (full postal code + normalised
place name); the residual is explained by the corruption documented below. It
is a reprocessed variant: 9-column FedEx schema, accents stripped, hyphens
title-cased, and regions remapped to the post-2016 13-region names with
official INSEE codes (ARA, BFC, BRE, COR, CVL, GES, HDF, IDF, NAQ, NOR, OCC,
PAC, PDL).
Ruled out — La Poste's official base is NOT the source. Its "Base officielle des codes postaux" has 39,192 rows and matches our non-CEDEX rows at only 80.55%, against GeoNames' 99.53% on the same subset.
On the "49-row discrepancy" in the original brief: it is a false premise. The two files are different artifacts, not two copies of one thing — R2 has 51,611 (= GeoNames exactly) and the local FedEx file has 51,660 (a reprocessed variant). The near-coincidence of both sitting around 51.6k is what made them look like the same file with rows missing.
Licence — CC BY 4.0, commercial resale permitted
GeoNames' own readme.txt, shipped inside FR.zip:
"This work is licensed under a Creative Commons Attribution 4.0 License.
This means you can use the dump as long as you give credit to geonames
(a link on your website to www.geonames.org is ok)"
France is not on GeoNames' restricted list. That readme names Chile, Ireland and Malta as truncated "for copyright reasons", and China, Argentina and Brazil as truncated without stated reason. France appears in none of them — full codes, no caveat. Contrast Saudi Arabia, Guinea and Maldives, where GeoNames has no export at all.
So France is cleanly resolvable with attribution — it is NOT a withdrawal
case. Attribution is a licence condition and is currently not being
shipped: neither the R2 objects nor datasets/fr/datapackage.yml credited
GeoNames before this pass.
Worth noting for completeness: La Poste's official base is also cleanly licensed — data.gouv.fr publishes it under the Licence Ouverte / Open Licence version 2.0, which permits commercial reuse. It is a legitimate re-source option (see below) if the quality problems argue for a rebuild rather than a patch.
The real problem: the file on sale is severely malformed
Licensing is clean; the data is not. Found in R2 fr/fr.csv — the file
customers actually receive:
- Every postal code is destroyed. All 51,611 are zero-padded to a
fixed 15 characters —
75000ships as000000000075000. 73.2% carry five or more leading zeros. There is no French postal code format this matches; the primary field of a postal-code product is unusable as-is. admin_code1float-coerced on 51,610 of 51,611 rows —11ships as11.0.- 361 rows carry the literal string
nanin an admin name field. - Hyphens stripped from place names —
Le Bellay-en-Vexinships asLe Bellay en Vexin. - Bare CSV only — no
datapackage.json, noREADME.md, no.zip, unlike a complete publish.
These are the same signature as the float-coercion and punctuation-stripping
defects found in PT and DE earlier in this review, all traceable to
scripts/geonames/geonames_parse_to_R2.py (pandas, no dtype=str). France is
the worst instance found so far because the corruption reaches the postal code
itself rather than an admin column.
The local FedEx-schema variant has a different and independent set of defects, recorded here so they are not lost:
- 315 rows carry an English-translated region name in
cityName— e.g. postal code75000(Paris) ships withcityName = "Upper France"(Hauts-de-France) andalternativeCityName = "Hauts de France". Wrong field, wrong language, wrong region. - Mojibake where accents were deleted rather than transliterated:
Crteil(Créteil),Paris La Dfense(La Défense),IvrysurSeine(Ivry-sur-Seine) — inconsistent with the cleanArdeche/Correzetransliteration elsewhere in the same file, suggesting two processing paths. - Cities sitting in the département field: Bobigny, Nanterre, Pantin, Montreuil, Paris 02, Paris 09 — inflating the département count to 108 against France's real 101.
- Duplicate casing:
Val-D'oiseandVal-d'Oiseboth present. - No overseas départements (Guadeloupe, Martinique, Guyane, La Réunion, Mayotte are absent) while uninhabited Clipperton Island is present with empty region, department and city.
Recommendation
Licensing: resolvable now — outcome (a). Add GeoNames attribution and the
CC BY 4.0 licenses: block to datasets/fr/datapackage.yml (done in this
pass, locally) and to the R2 objects when they are next republished.
Quality: this should not stay on sale in its current state, and that is a
separate decision from the licensing one. is_premium: true is set on a
file whose every postal code is malformed. Options, in order of preference:
- Republish from GeoNames FR with a corrected parser (
dtype=str, no punctuation stripping) — restores real postal codes, keeps the licence clean, and fixes PT/DE-class defects at the same time. - Rebuild from La Poste's official base (Licence Ouverte 2.0, commercial reuse permitted) if authoritative provenance is preferred over GeoNames' coverage — but note it has 39,192 rows against GeoNames' 51,611 and omits the CEDEX layer.
- Gate with
data_available: falseuntil either is done.
Deliberately not done here: no is_premium/data_available flag was
changed, no R2 object was written, nothing was committed. Those are human
decisions.
Investigated 2026-08-24. Sources verified directly: GeoNames FR.zip +
bundled readme.txt; La Poste "Base officielle des codes postaux" via
data.gouv.fr; R2 fr/fr.csv; both repos' git history.
Corrected republish — EXECUTED 2026-08-24
Option 1 from the recommendation above was carried out: rebuilt from GeoNames FR
with a corrected parser and republished to R2. Reproducible scripts live in
datasets/fr/scripts/ (fetch_source.py → build_base.py →
integrity_checker.py → package.py → publish_r2.py); see that folder's
README for run order and full verification.
Licence position, now shipping. GeoNames CC BY 4.0 attribution is carried in
the published README.md and datapackage.json, and in
datasets/fr/datapackage.yml. Before this pass it appeared nowhere — that was
live non-compliance with the licence that makes the dataset sellable, and it is
now closed.
All four defects fixed and asserted against.
| Defect | Before | After |
|---|---|---|
| Postal codes zero-padded to 15 chars | 000000000075000 | 75000 |
admin_code1 float-coerced | 11.0 | 11 |
Literal nan string cells | 461 | 0 |
| Punctuation stripped from place names | Le Bellay en Vexin | Le Bellay-en-Vexin |
integrity_checker.py now fails the build on any of the four, so a regression
cannot reach R2 silently. datapackage.json additionally declares postal_code
as a string with an explicit France pattern (^\d{5}( (CEDEX( \d{1,2})?|SP \d{1,2}|AIR|CITYSSIMO))?$), so a schema-aware reader cannot re-coerce it.
Root cause of the padding, for the record. France's postal column is mixed
width — the CEDEX/SP/AIR/CITYSSIMO business-delivery layer runs up to 15
characters (78078 CITYSSIMO). A max-width zero-fill over that column padded
every short code to 15. This is why the bug hit the primary field here and only
admin columns in PT/DE.
Row count: 51,611 source → 51,585 published. The 26-row difference is 24
groups of coordinate-only duplicates — same postal code, place name and full
administrative hierarchy, differing only by roughly 100–200 m (two gazetteer
entries for one commune centroid, e.g. 70230
Roche-sur-Linotte-et-Sorans-les-Cordiers). Dropped so (postal_code, place_name) holds as a primary key; counted in data/build_stats.json, not
silently discarded.
Published and verified. Four objects now live under the fr/ prefix where
previously only a bare CSV existed:
| Object | Bytes |
|---|---|
fr/fr.csv | 4,545,018 (was 5,215,242) |
fr/datapackage.json | 3,754 (was absent) |
fr/README.md | 3,828 (was absent) |
fr/fr.zip | 648,556 (was absent) |
Round-trip verified: the objects were downloaded back from R2 and the
downloaded copy re-validated with Frictionless from inside its own
directory — valid, 51,585 rows, zero padded/nan/float-suffixed cells,
Paris 75000 present.
Still outstanding after this republish
- The public 100-row sample is still corrupt.
https://postal.datahub.io/fr/fr.csvreturns000000000075000,11.0andÎle de France— it is the old broken extract. That object lives in thepostal-codes-samplesbucket, which thepostal-codestoken cannot write to (seedocs/R2_ACCESS.md§3), so it could not be fixed here. This is the copy prospective buyers see. It needs regenerating by whoever holds access to that bucket. _meta/catalog.jsonwas not touched by this work — itsfrentry still reflects the old byte count and lacks the three new files. Deliberate: that file is shared state and was being updated serially elsewhere.- The shared parser was not fixed.
scripts/geonames/geonames_parse_to_R2.pyis the root cause and is used by many countries; correcting it is a separate, wider job. PT and DE are already known to carry the same defect class. is_premium/data_availableflags were not changed — human decision.