Postal Codes Dataset for Benin, BJ

224
Updated:
Files:1
Size:183 kB
Rows:3,760
Formats:csv
License:CC-BY-4.0

Postal Codes Dataset for Benin, BJ including name of the city, town, or place, various administrative divisions and alternative city names.

Part of a Data Solution

  • Postal Codes Solution

    Every worldwide postal-code dataset in one bundle — the ultimate global reference for precise postal codes.

    Explore →

API Access

Access dataset files directly from scripts, code, or AI agents.

Browse dataset files
Dataset Files

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.

/logistics/postal-codes-bj/
https://datahub.io/logistics/postal-codes-bj/_r/-/.licensing-notes.md
https://datahub.io/logistics/postal-codes-bj/_r/-/.migration-notes.md
https://datahub.io/logistics/postal-codes-bj/_r/-/ATTRIBUTION.txt
https://datahub.io/logistics/postal-codes-bj/_r/-/README.md
https://datahub.io/logistics/postal-codes-bj/_r/-/datapackage.yaml
Key Files

Start with these files — they give you everything you need to understand and access the dataset.

datapackage.yaml— metadata & schema
https://datahub.io/logistics/postal-codes-bj/_r/-/datapackage.yaml
README.md— documentation
https://datahub.io/logistics/postal-codes-bj/_r/-/README.md
Typical Usage
  1. 1. Fetch datapackage.yaml to inspect schema and resources
  2. 2. Download data resources listed in datapackage.yaml
  3. 3. Read README.md for full context

Data Files

Explore with AI

postal-codes-bj

Download

Download CSV

About

Last updated
6 October 2026
Total rows
3,760
Format
CSV
File size
183 kB

About this dataset

Benin (BJ): migration notes

Internal record of the P6 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.8.3
  • Commit: see git log -- datasets/bj/ (P6 bj commit on feat/single-source-of-truth, base c51b72a)
  • Parity verdict: format-only (gate: pass, exit 0); CRLF→LF only
  • Producer: custom, refresh disabled

Sources

InputURLNotes
GeoNames gazetteer dumphttps://download.geonames.org/export/dump/BJ.zipBJ.txt, filtered to feature class P. The old builder read a local sources/BJ.txt snapshot of this file
GeoNames admin1 tablehttps://download.geonames.org/export/dump/admin1CodesASCII.txtUsed only to check GeoNames' department labels against the crosswalk. The old builder read a local sources/geonames_admin1CodesASCII.txt snapshot
  • Both URLs are stable, unversioned GeoNames URLs. The fetch date and sha256 are recorded in bj.inputs.json; --no-fetch reuses the cache.
  • Benin has no postal-code system and GeoNames has no postal export for BJ (export/zip/BJ.zip is a 404), so postal_code is empty on every row. pipeline.postal_code_required: false tells build.py this is intended.

Parity against the live public CSV (2026-10-05)

Rows: 3,760 live and 3,760 fresh, none only on one side, 0 changed cells, no cell classes. Once CRLF is normalised to LF the fresh bj.csv is byte-identical to the live CSV, including row order. Live sha256 6ffc99b4…, fresh 1a08c492… (the only difference is line endings).

No discrepancies to explain. The GeoNames dump at migration time still has 3,760 populated places, 14 of them on the reserved admin1 code 00, as on 2026-09-17.

Decisions

DecisionByBasis
Accept the CRLF→LF differenceStanding rule (P5 sign-off: row_order/CRLF-only pre-approved)Equal rows, 0 changed cells
Drop the exact-count asserts (3,760 places, 14 unresolved)P6 briefReplaced by structural checks: all 12 departments present, primary key unique, GeoNames labels match the crosswalk
An admin1 code other than 00/blank that isn't in the crosswalk stops the buildAgent: port choiceThe old builder blanked it silently (only its exact unresolved-count assert would have caught it); blanking a real but new department would hide a crosswalk gap
latitude/longitude typed number; accuracy stays stringAgent, per the briefaccuracy is empty on every row (the gazetteer dump has no accuracy field), so it isn't numeric data and doesn't get the GeoNames accuracy description
primaryKey: [place_name, latitude, longitude]Agent, from the produced CSVUnique in the produced CSV; it is the old builder's own PK. (place_name, admin_code1) is not unique
pipeline.postal_code_required: falseAgentbuild.py refuses empty postal codes otherwise and names this flag; bj is the first dataset to use it
Add admin1CodesASCII.txt to the descriptor sourcesAgentIt is a fetched input
Field descriptions taken from the old builder's datapackage.json (minus counts)AgentThe P3 generic descriptions said "Postal code for the location", which is wrong for bj

Transforms carried over

From build_postal_codes_product.py:

  • Feature class P only; place_name is the dump's name column; latitude/longitude copied verbatim.
  • admin_code1 → ISO 3166-2:BJ via the bucket-code crosswalk (BJ.07–BJ.18), admin_name1 in ISO spelling (Atakora→Atacora BJ-AK, Kouffo→Couffo BJ-KO). Every GeoNames label is checked so an upstream rename stops the build.
  • Reserved admin1 00 → blank admin_name1/admin_code1.
  • postal_code, accuracy, alternative_city_name and admin tiers 2–3 empty.
  • Sorted by (admin_code1, place_name), ties in dump order.
  • Not ported: the old builder's own datapackage.json, README, ATTRIBUTION and zip writing (build.py / committed docs handle those) and publish_r2.py.

Open questions

  • Resolved: README.md was the generic stub ("We don't have postal code data for Benin yet … No data is currently available"), which contradicts the published locality directory. It has no counts or licence line, so the agent left it; the orchestrator rewrote it afterwards (below).
  • .licensing-notes.md and data/ATTRIBUTION.txt still carry dated counts; left for pc-hfz.

Orchestrator follow-up (2026-10-05)

  • README.md was the stale "no data yet" stub although the live CSV is a full locality directory. The orchestrator rewrote it from the old builder's README text, without counts and without the stale licence_status line. README text confirmed by the user (2026-10-05).