Postal Codes Dataset for Kuwait, KW

272
Files:1
Formats:csv

Postal Codes Dataset for Kuwait, KW 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 →

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
20% off
$49.90$39.92
one-time payment

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-kw/
https://datahub.io/logistics/postal-codes-kw/_r/-/.licensing-notes.md
https://datahub.io/logistics/postal-codes-kw/_r/-/.migration-notes.md
https://datahub.io/logistics/postal-codes-kw/_r/-/ATTRIBUTION.txt
https://datahub.io/logistics/postal-codes-kw/_r/-/README.md
https://datahub.io/logistics/postal-codes-kw/_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-kw/_r/-/datapackage.yaml
README.md— documentation
https://datahub.io/logistics/postal-codes-kw/_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

postal-codes-kw-sample


About this dataset

Kuwait (KW): migration notes

Internal record of the SST migration. This is a dated record (2026-10-09) and is not shipped in the zip.

  • Issue: none for the SST conversion (the beads database was unavailable locally); the producer port had none either.
  • Producer: scripts/produce.py (custom), ported 2026-10-09. The dataset stays frozen (no pipeline:): the licence is unresolved, so nothing runs the producer automatically. Run it by hand.
  • Parity: parity.py only runs the frozen check on a dataset with no pipeline:, so the comparison was done by hand (see below).

History

  • P3 migrated kw as a no-data dataset (data_available: false, header-only CSV).

  • main then gained 7f56647 (2026-10-08): Kuwait rebuilt from the Ministry of Communications tables and sold as premium tier B (premium_source_key: kw/kw.zip). That commit changed only metadata (datapackage.yml, README.md, .licensing-notes.md); no builder script was committed.

  • The branch merged main taking its datasets/kw as-is (1a88856), and this commit converts that descriptor to the SST shape.

  • a811e1f (2026-10-08) committed the builder: scrape_moc.py (Playwright replay of the page's server action) and build_kw.py, plus package_kw.py and publish_r2.py.

  • 2026-10-09: ported to scripts/produce.py + test_produce.py; the old scripts were removed (they're in a811e1f).

What was carried over

  • Description, sources, tier B and kw/kw.zip source key, and the field descriptions, taken from 7f56647. Nothing about pricing was decided here.
  • ATTRIBUTION.txt copied verbatim from the live zip.
  • No licenses entry: the licence is unresolved and the owner chose to omit it (see .licensing-notes.md). Frozen datasets may omit it.
  • Schema stays all-string with no primaryKey (no producer owns it). For a future producer: (postal_code, place_name, admin_name3) is unique in the live CSV, and postal_code alone is not.

Checked against R2 (2026-10-09, read only)

  • Premium bucket kw/kw.zip (uploaded 2026-10-08) holds kw.csv with 5,656 rows, 5,586 distinct codes, all 6 governorates, and no coordinates.
  • Public postal.datahub.io/kw/kw.csv is the first 100 rows of that CSV (byte-exact prefix).

Producer port (2026-10-09)

  • Fetching without a browser. The page's server action works over plain HTTP. The producer finds the action id the way the browser does, from the page's /_next/static/chunks/*.js (createServerReference("<id>", …, "requestPayloadCollection")); the id changes with each site deploy. It sends the same request body as scrape_moc.py (same query, no sort), but with page size 1000 instead of 10, so a full run takes 14 table requests (1 s apart) instead of about 1,130. The server accepts 1000.
  • TLS. moc.gov.kw doesn't send its intermediate certificate. Python's urllib, unlike curl and browsers, doesn't fetch it via AIA. The producer downloads the DigiCert intermediate from the certificate's AIA URL and adds it to the default context, with partial chains off, so the chain must still end at a trusted root.
  • Paging guard. An unsorted listing could skip or repeat rows across pages, so the producer fails unless each table yields exactly totalDocs distinct ids.
  • Transforms. All of build_kw.py is ported unchanged: $1: reference resolution, the ISO 3166-2:KW substring crosswalk, the PO Box / Block units, Arabic names matched by id, duplicates collapsed on (code, governorate, area, unit), and the sort. write_outputs then reorders rows within each postal code by bytes (canonical_order). Its checks became ProducerErrors: every code is 2-6 digits, all 6 governorates are present, every governorate is mapped, and every relation resolves. The old warnings (codes on several rows, PO Box gaps/overlaps, non-integer blocks, records missing an Arabic counterpart) describe the source and weren't ported.
  • Comparison with live (by hand). There's no .env.prod in this checkout, so the premium zip wasn't read. Fresh output, 2026-10-09: 5,656 rows, 5,586 distinct codes, 6 governorates and no coordinates, matching the counts recorded from the live zip above. The public sample (postal.datahub.io/kw/kw.csv, the zip CSV's first 100 rows) is a byte-exact prefix of the fresh CSV.

Decisions

DecisionByBasis
Re-migrate kw on top of main's versionUser, 2026-10-09PR #37 conflict with 7f56647
Frozen (no producer)Standing rule (user, 2026-10-03)No builder scripts in the repo to port (superseded by the next two rows)
Port the a811e1f builder to produce.pyUser, 2026-10-09The builder is now in the repo
Stay frozen (no pipeline:) after the portUser, 2026-10-09Licence unresolved; SST §9 says the frozen rule is the licence enforcement
Plain HTTP instead of Playwright; page size 1000Port choice, 2026-10-09Same source and request; no browser dependency; ~80x fewer requests

Open questions

  • Resolved: the builder was committed in a811e1f and ported. Unfreezing (adding pipeline:) waits on the licence decision.
  • pending: Byte-for-byte check of the fresh CSV against the premium zip kw/kw.zip once .env.prod is available.
  • pending: The retrieval date differs. The datapackage and README say 2026-10-08; the zip's ATTRIBUTION.txt and datapackage.json say 2026-10-06.

Provenance

Written 2026-10-09 from 7f56647, the live zip and sample, and the merge session. Producer-port sections added 2026-10-09 from a live run of produce.py.