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 International 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 Algeria, DZ
| 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
- 17 September 2026
- Total rows
- ...
- Format
- CSV
- File size
- 933 kB
About this dataset
Algeria (DZ) — internal licensing notes
Source research, 2026-09-17 — first audit of this country
No .licensing-notes.md existed for DZ before this pass. datapackage.yml
has no licenses: array and its sources: entry is the same
non-informative placeholder already flagged elsewhere in this project
(sources: [{title: "Multiple sources", path: https://datahub.io/collections/postal-codes-datasets}] — see
feedback_datapackage_no_sources). is_premium: true with nothing behind
it. Same starting state CH/PR/CO were in before their 2026-09-16 audits.
Extra wrinkle here, not present in the CH case: datapackage.yml
itself is stale relative to the live file. It describes one resource,
bytes: 5398, modified: '2024-11-07' — a ~5KB file. The file actually
live on R2 today is 1,007,993 bytes. The descriptor was never updated
when the file behind it changed. Whatever validation or row-count check
this project's tooling does against the declared resource size would
silently pass a completely different file than the one described.
The public product page (datahub.io/logistics/postal-codes-dz, checked
live this pass) states: "The data files used in this dataset are sourced
from official and publicly available records." This claim is not
supported by what was actually found in the file (§1) — worth flagging
alongside the licensing gap, since it's a customer-facing sourcing claim,
not just an internal metadata omission.
1. What the current R2 file (dz/dz.csv, 1,007,993 bytes, 2026-07-30) actually is — VERIFIED
Fetched directly from the main postal-codes R2 bucket (read-only,
R2_ACCESS_KEY/R2_SECRET_KEY from this repo's own .env).
15,951 data rows + header.
The same bucket also holds an automated pipeline's output for this
country: dz/geonames/2026-09-01/0.csv and dz/geonames/latest/0.csv
(both 1,007,999 bytes), produced by scripts/geonames/geonames_parse_to_R2.py
— the shared GeoNames→R2 conversion script this project already runs for
other countries. Row-for-row, dz/dz.csv and the 2026-09-01 GeoNames
pipeline snapshot are the same dataset: sorting both files and diffing
shows only 2 rows differ (both just a changed alternative_city_name
value, consistent with GeoNames' own community-edited alternate-names
table shifting slightly between fetches — e.g. row 39005 El Meghaier
carries alternative_city_name "El M'Ghair" in the older file vs.
"Ehl'-Megajer" in the newer one). dz/dz.csv is a GeoNames pass-through
built by this project's own generic pipeline script, not a bespoke
Algeria build and not an official-source rebuild.
Fetched https://download.geonames.org/export/zip/DZ.zip (CC BY 4.0)
directly for comparison: DZ.txt also has exactly 15,951 rows and the
same content, confirming the chain source → geonames_parse_to_R2.py →
dz/dz.csv end to end.
Defects confirmed in the shipped file, traced to specific bugs in geonames_parse_to_R2.py
(a) accuracy is float-formatted. 1.0 / 3.0 / 4.0 instead of
GeoNames' own integer 1 / 3 / 4 (12 rows ship with accuracy blank).
Distribution: 8,672 rows accuracy=3.0, 5,288 rows accuracy=1.0, 1,979
rows accuracy=4.0, 12 blank. Same class of bug already documented for CH
and hard-aborted-on in datasets/lk/scripts/publish_r2.py
(if r["accuracy"].endswith(".0")) — DZ ships with it live, same as CH
did.
(b) Literal the string "nan" in admin_name2 and admin_name3 —
on every single one of the 15,951 rows, not a minority. Traced to
clean_and_normalize() in the pipeline script: it runs
df[column] = df[column].astype(str) over
['place_name', 'admin_name1', 'admin_name2', 'admin_name3'] before
checking for missing values. Algeria's raw GeoNames extract has no
admin2/admin3 data at all (both columns empty in DZ.txt), so pandas
reads them as NaN, and astype(str) turns every one of those NaN
into the literal 3-character string "nan". admin_code2 and
admin_code3 are not in that column list, so they correctly stay blank
— only the two _name columns are corrupted. Example row as shipped:
DZ,01000,Ouled Ali,Adrar,1,nan,,nan,,28.07,0.1158,1.0, — that nan is
not data, it is the word "not a number" leaking into a delivered CSV
column, on literally every row in the file.
(c) admin_code1 has its leading zero stripped — genuinely a
regression from a correct source value, not a source defect. Raw
GeoNames DZ.txt codes each wilaya 01 through 48 (confirmed by
direct inspection of the downloaded zip — 01<TAB>Adrar, 02<TAB>Chlef,
… 48<TAB>Relizane), which is already the correct ISO 3166-2:DZ-style
zero-padded format. The pipeline's pd.read_csv(..., usecols=COL_POSTAL_CODE)
call has no dtype argument, so pandas auto-infers admin_code1 as a
numeric column (all values are digit-only strings) and silently drops
the leading zero — 01 becomes 1, 08 becomes 8, etc. The shipped
file's 48 distinct admin_code1 values are 1 through 48 with no
zero-padding, confirmed by direct enumeration. This is the same failure
mode the project's postalCode string-typing rule exists to catch
(pd.read_csv coercing a zero-padded numeric-looking string), just
hitting an admin code column instead of the postal code column, and with
no schema-typed datapackage.yml in place here to catch it either.
The one thing that IS correct at the admin-code level, once the zero is restored
Checked the 48 (admin_code1, admin_name1) pairs against the real
ISO 3166-2:DZ list: every one matches the official wilaya name and
number exactly — 01 Adrar, 02 Chlef, 03 Laghouat, … 48 Relizane, in the
right order, no GeoNames-internal numbering substituted for a real code.
The zero-stripping (§1c) is a formatting bug on top of an otherwise
correct value, not a "false friend" code of the kind flagged for other
countries in this project.
2. Coverage: the file reflects a wilaya structure that is now two reorganizations out of date
This is the most consequential finding of this audit, independent of the formatting bugs above.
The shipped file covers exactly 48 wilayas (codes 01–48). Algeria's official province count has moved twice since then:
- 2019 reorganization (bill passed 26 Nov 2019, provinces created 18 Dec 2019): 10 new wilayas carved mostly from southern provinces — Timimoun, Bordj Badji Mokhtar, Ouled Djellal, Béni Abbès, In Salah, In Guezzam, Touggourt, Djanet, El M'Ghair, El Meniaa — assigned ISO 3166-2:DZ codes 49–58, bringing the total to 58.
- 2025 reorganization (Council of Ministers, 16 Nov 2025, per President Tebboune): 11 more districts in the High Plateaus and south promoted to full wilaya status — Aflou, Barika/Bir El Ater area, Ksar Chellala, Messaad, Aïn Oussera, Boussaâda, El Abiodh Sidi Cheikh, El Kantara, Ksar El Boukhari, El Aricha, and one more — bringing the total to 69 wilayas and 1,541 communes, confirmed via multiple independent 2025/2026 news sources (Morocco World News, Horizons/dz, DzairTube) in addition to Wikipedia's Provinces of Algeria article.
Both reforms are absent from the shipped file. dz/dz.csv ships as
if Algeria still had the 1984–2019 administrative structure. This is not
a case of GeoNames merely lagging by a few months — the file is missing
21 of the country's current 69 administrative units (30% of all wilayas),
and has been missing the first 10 of them since December 2019.
This is a GeoNames-side gap, not something introduced by this
project's pipeline. Raw DZ.txt fetched directly from
download.geonames.org this pass also stops at code 48 — GeoNames
itself has not extended its Algeria postal-zip gazetteer to the
post-2019 wilayas. Nothing in geonames_parse_to_R2.py drops rows; the
upstream source simply doesn't have them.
One genuine open question, not resolved in this pass: it is not
established whether Algeria's postal code system (as opposed to the
administrative wilaya numbering) has itself been extended to give the
new wilayas their own 2-digit prefixes, or whether mail routing for
wilayas 49–69 still runs through their parent wilaya's original prefix
during a transition period (this is a common pattern — administrative
splits often precede postal-infrastructure updates by years). The
French Wikipedia postal-code list (fr.wikipedia.org/wiki/Liste_des_codes_postaux_d'Algérie,
checked this pass) is itself still organized around only 48 wilayas and
carries its own "this article needs updating" banner, last refreshed
January 2021 from "an update list on Algeria's postal service website" —
so even a semi-official secondary source hasn't caught up either. This
needs a direct answer from Algérie Poste before a rebuild assumes either
"new wilayas have no postal codes yet" or "new wilayas reuse the parent
prefix" — don't guess at build time.
3. Official tier-1/2 sources checked, per the standing GeoNames-is-fallback rule
Algérie Poste (poste.dz) — could not reach it this pass; not ruled out
poste.dz timed out on both a direct curl (20s, no response,
connection eventually times out — 80.249.65.101:443) and a WebFetch
attempt (ECONNREFUSED) from this environment. This reads as either
geo-blocking/network filtering from outside Algeria, or a genuinely slow/
down host at the time of this check — not evidence one way or the other
that no bulk postal-code download exists there. The French Wikipedia
citation above indicates poste.dz did publish at least a browsable
postal-code update list as recently as January 2021, so the site is a
real candidate worth another attempt (ideally from a different network/
IP, or via a cached/archived copy) before defaulting to GeoNames as
final. Not confirmed either way whether poste.dz offers a bulk CSV/API,
an open-data page, or only a manual lookup tool.
ONS (Office National des Statistiques) — reachable, not deeply investigated this pass
ons.dz responds normally (plain HTTP 200, old SPIP-based CMS). ONS is
Algeria's national statistics office and a plausible tier-2 source for
the administrative reference (current wilaya/commune nomenclature,
NIS codes) even if it doesn't publish postal codes itself — this would
be the natural source to confirm the current 69-wilaya structure
authoritatively and to source real admin_code2/commune-level data,
neither of which the current file has. Not fetched/searched in depth
this pass; flagged as a next step rather than ruled out.
GeoNames — fallback baseline, evaluated per the standing rule (checked last, confirmed as what's actually shipping)
download.geonames.org/export/zip/DZ.zip → 200, CC BY 4.0, 15,951 rows,
stuck at the pre-2019 48-wilaya structure. Already characterized in full
above (§1–2) since it is also what dz/dz.csv is built from. Its
admin-code fidelity for the 48 wilayas it does cover is genuine (real
ISO 3166-2:DZ names and numbers, once the zero-stripping bug is
corrected), but its coverage is two reorganizations stale and it carries
no admin2/admin3 data for Algeria at all.
4. Western Sahara — checked, not applicable here
The task brief flagged Western Sahara's disputed status (Morocco vs.
Polisario Front, which Algeria backs) as a sensitivity to watch for.
Checked the shipped file directly (grep for Sahara/Western/Polisario/
Sahrawi terms): the only related hit is Tindouf (wilaya 37), which
is a real, uncontested Algerian wilaya — notable as the location of
Sahrawi refugee camps, but that is a geographic/political fact about the
region, not a data defect or a disputed-boundary claim appearing in this
dataset. Western Sahara itself is a separate ISO entity (EH) and does
not appear in DZ.txt/dz.csv at all. No disputed-territory content
found in this file; nothing to resolve or flag further for DZ
specifically.
Verdict
Do not treat this file as validated. It fails on three independent
grounds: it is unattributed (CC BY 4.0 GeoNames data shipped with no
licence block at all), it has live formatting bugs (float accuracy,
literal "nan" strings on every row, a stripped leading zero on
admin_code1), and — the most substantive problem — it represents an
administrative structure that is 30% incomplete against Algeria's actual
current 69-wilaya map, a gap that predates this file and traces to
GeoNames' own upstream extract, not to this project's conversion script.
The public product page's claim of "official and publicly available records" is not supported by what's in the file — it's an unfiltered community gazetteer export, not a rebuild from Algérie Poste or ONS.
Recommended next step (not executed in this pass — research/audit only):
- Make a second, better-network attempt at
poste.dz(and check the Internet Archive Wayback Machine for it) to determine whether a bulk/open postal-code download exists, and specifically whether wilayas 49–69 have been assigned their own postal prefixes yet. - Check
ons.dzfor an authoritative current wilaya/commune nomenclature (NIS codes) to at least fix the admin reference layer even if postal codes stay GeoNames-sourced short-term. - Regardless of which source wins, fix the three packaging bugs before
anything ships again: integer
accuracy(not"4.0"), no literal"nan"strings (empty string instead, when GeoNames has no admin2/admin3 data for a country), and zero-paddedadmin_code1preserved as a string end to end (needs the samedatapackage.ymlTable Schema string-typing this project already applies elsewhere — DZ currently has no schema-level protection for any column). - Regenerate
datapackage.yml's resource metadata (byte count, date) from the file that's actually live, and write a reallicence_statusblock per the provenance gate (licence_id: CC-BY-4.0if GeoNames stays the source,decision: "unresolved"until a human signs off,channel: "postal-codes-r2") instead of the current placeholdersources: [{title: "Multiple sources", ...}]. - Do not extend or "finish" wilaya coverage by inventing codes 49–69 — any backfill needs a real source for both the admin structure (ONS) and, separately, confirmation of what postal prefix (if any) those wilayas currently use.
Build, 2026-09-17 — packaging fix on the 48-wilaya GeoNames base
Executed the recommendation from the audit above: a local, LOCAL-ONLY
rebuild in datasets/dz/, fixing the three confirmed packaging bugs and
disclosing the coverage gap — not a coverage upgrade. No new source was
found or used for wilayas 49–69; nothing was invented for them.
What was done:
- Re-fetched
https://download.geonames.org/export/zip/DZ.zipfresh this pass (same file the audit already characterized): 15,951 rows, 48 distinctadmin_code1values (01-48, zero-padded in the raw file),admin_name2/admin_name3blank on every row, no duplicate(postal_code, place_name)pairs. Matches the audit's findings exactly — nothing changed upstream since the audit. - Wrote
datasets/dz/scripts/build_postal_codes_product.py(csv module only, no pandas — modeled ondatasets/keanddatasets/lk), readingDZ.txtdirectly withcsv.readerso none of the three pandas-driven bugs can occur:accuracy— passed through as the raw string ("1"/"3"/"4", 12 rows blank), never cast to float. Script asserts no value ends in.0.admin_name2/admin_name3— passed through as empty string (Algeria's raw export has no admin2/admin3 data at all). Script asserts no field is the literal string"nan".admin_code1— raw zero-padded value ("01"-"48") kept intact and prefixed to"DZ-01".."DZ-48"(ISO 3166-2:DZ format). Script asserts every value matchesDZ-\d{2}. No crosswalk was needed for admin_code1/admin_name1 — the audit already verified all 48 pairs match the official ISO 3166-2:DZ wilaya list exactly, in order; this script only restores formatting, it does not renumber or rename anything.
- Coverage-gap disclosure added to
datapackage.json'sdescription,ATTRIBUTION.txt, andREADME.md: 48/69 of Algeria's current wilayas are covered; the dataset reflects the pre-2019 structure; the 21 wilayas created Dec 2019 (10) and Nov 2025 (11) are not represented because no source — official or GeoNames — has yet published their postal-code assignments. Stated as a real, current limitation, not hedged. licence_statuswritten per the provenance gate:licence_id: CC-BY-4.0,decision: "compatible",channel: "postal-codes-r2", dated 2026-09-17, with a note pointing back to this file.
Result: 15,951 rows, 48/69 wilaya coverage (unchanged from the
audit — this was never intended to be a coverage upgrade). Frictionless
validate() run from inside datasets/dz/data/ against the freshly
written datapackage.json: valid: True, 0 errors, 0 warnings.
Declared resource rows (15,951) matches the actual row count in
dz.csv. Output written to datasets/dz/data/ (dz.csv, datapackage.json,
README.md, ATTRIBUTION.txt, dz.zip) — local only, per instruction:
not uploaded to R2, not committed, datapackage.yml and _meta/catalog.json
left untouched.
Still not done, per the audit's own next steps (not in scope for this
pass): re-attempting poste.dz/Wayback for an official bulk source,
checking ons.dz for an authoritative current wilaya nomenclature, and
resolving whether wilayas 49–69 have real postal-prefix assignments at
all. This pass is a packaging fix only, exactly as requested.