Postal Codes Dataset for Ukraine, UA

364
Updated:
Files:1
Size:3.05 MB
Rows:29,571
Formats:csv
License:CC-BY-4.0

Postal Codes Dataset for Ukraine, UA 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
  • Creative Commons Attribution 4.0 International license
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-ua/
https://datahub.io/logistics/postal-codes-ua/_r/-/.licensing-notes.md
https://datahub.io/logistics/postal-codes-ua/_r/-/.migration-notes.md
https://datahub.io/logistics/postal-codes-ua/_r/-/ATTRIBUTION.txt
https://datahub.io/logistics/postal-codes-ua/_r/-/README.md
https://datahub.io/logistics/postal-codes-ua/_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-ua/_r/-/datapackage.yaml
README.md— documentation
https://datahub.io/logistics/postal-codes-ua/_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-ua-sample


About this dataset

Ukraine (UA): 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.55 (closed 2026-10-02)
  • Commit: e4ba518 (worktree commit 92b4f3a, same content), landed in batch 3
  • Parity verdict: explained (row_order only); signed off under the standing rule
  • Producer: custom, refresh disabled

Sources

InputURLNotes
GeoNames postal exporthttps://download.geonames.org/export/zip/UA.zip
GeoNames gazetteer dumphttps://download.geonames.org/export/dump/UA.zipPopulated places (class P) with admin1/admin2
GeoNames admin2 codeshttps://download.geonames.org/export/dump/admin2Codes.txtRaion names. Added to the descriptor's sources in this commit

The old builder read all three from local files; the producer now fetches them. Ukrposhta has no bulk download, only a single-address lookup (.licensing-notes.md, 2026-08-31).

Parity against the live zip (2026-10-02)

Rows: 29,571 live and 29,571 fresh, none only on one side. 0 changed cells. The only class is row_order: places sharing a postal code come out in a different order (e.g. 10421 Субине / Горбачі, and Батьківщина / Булахівка, swapped). A line-by-line diff showed 1,912 positions differing; keyed on (postal_code, place_name) the rows are identical. The live CSV is already LF.

The informational sample check against https://postal.datahub.io/ua/ua.csv came back unexplained. It is outside the gate and was not traced.

Decisions

DecisionByBasis
Accept the row_order verdict and landStanding rule (row_order/CRLF-only, user, 2026-10-02)Equal rows, 0 changed cells
Replace the old brute-force nearest-place scan with a grid searchAgentExact distance bound, ties to the first dump entry, so the same place is picked; ~5 s instead of minutes. Parity shows 0 changed cells
"Every region present" check exempts SevastopolAgentGeoNames has no Sevastopol postal codes
Keep the existing accuracy description, not the standard GeoNames wordingAgentThe column is the constant AREA, not a GeoNames code. Not put to the user
Remove the row and distinct-code counts; keep 26/27 regions and 130/136 raionsOrchestrator instruction (the user's README counts rule)
Drop the README sentence "licence_status.decision is compatible"Orchestrator instructionBrief: no such field
No row-count assertOrchestrator instructionBrief: structural checks only

Transforms carried over

From build_postal_codes_product.py (2026-08-31):

  • Each postal row is joined to a gazetteer populated place by name against the dump's name, asciiname and each alternatename (postal names are Cyrillic, name/asciiname Latin; matching only those matched nothing). Nearest same-named place within 50 km, else the nearest place of all within 100 km; otherwise an error.
  • GeoNames admin1 01–27 → English name and ISO 3166-2:UA via the 27-region crosswalk (e.g. 05 Donetsk → UA-14).
  • admin_name2 from admin2Codes.txt, admin_code2 is GeoNames' own raion code; both empty for Kyiv City and Sevastopol City.
  • admin_name3/admin_code3 and alternative_city_name empty; accuracy AREA; latitude/longitude rounded to 5 dp; stable sort by postal_code.
  • The old asserts are now ProducerErrors: 12-column UA rows, 5-digit codes, no literal "nan", every row resolved within the fallback, every region but Sevastopol present, unique (postal_code, place_name).

Open questions

  • ATTRIBUTION.txt still carries the old join counts (e.g. 20304 exact-name rows, 9267 fallback rows); it belongs to the pc-hfz sweep.

Provenance

Reconstructed 2026-10-05 from the agent transcript 2479b1c9-c4dd-47e5-be82-34ccf8d49a80/subagents/agent-a4c7e115fb7db5133.jsonl, the orchestrator session 2479b1c9-… (also checked 068ca403-… and 803a95aa-…: no ua decisions), the commit message, the bd close reason and docs/parity/p5.md.