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.yaml to inspect schema and resources
- 2. Download data resources listed in datapackage.yaml
- 3. Read README.md for full context
Data Files
postal-codes-ua-sample
| Field | Type | Description | Constraints | Title |
|---|---|---|---|---|
| country_code | string | ISO 3166-1 alpha-2 -- always UA | Country Code | |
| postal_code | string | Ukrainian postal code (5 digits) | { "pattern": "^\\d{5}$" } | Postal Code |
| place_name | string | Locality/place name (Cyrillic), as GeoNames' postal export records it | Place Name | |
| admin_name1 | string | Oblast / city-with-special-status -- 26/27 covered, resolved via a coordinate-based join against GeoNames' own gazetteer, see ATTRIBUTION.txt | Administrative Name 1 | |
| admin_code1 | string | ISO 3166-2:UA code | Administrative Code 1 | |
| admin_name2 | string | Raion (district) -- 130/136 covered; empty for Kyiv City and Sevastopol City, which are not subdivided into national raions | Administrative Name 2 | |
| admin_code2 | string | GeoNames' own raion code (not an independently verified official code) | Administrative Code 2 | |
| admin_name3 | string | Not populated -- no source reaches a third tier nationally | Administrative Name 3 | |
| admin_code3 | string | Not populated | Administrative Code 3 | |
| latitude | number | GeoNames postal-export latitude (WGS84) | Latitude | |
| longitude | number | GeoNames postal-export longitude (WGS84) | Longitude | |
| accuracy | string | AREA throughout -- coarse city/town-level point, shared across all codes in that place | Accuracy | |
| alternative_city_name | string | Not populated in this release | Alternative City Name |
Download
Download sample CSVAbout
- Last updated
- 2 October 2026
- Total rows
- 100
- Format
- CSV
- File size
- 5.72 kB
About this dataset
Ukraine (UA) — internal licensing notes
Source research, 2026-08-31
Clean GO on GeoNames; no official bulk source exists; real admin-tier recovery is available via the same-source dump-join technique (RS/ZA pattern).
What's currently live
R2's ua/ua.csv (29,571 rows, matches _meta/catalog.json's stale
2026-07-30 entry) is a near-raw GeoNames postal export, corrupted the
same way as PL/AL/TH/RS/BG: admin_name3 is the literal string "nan"
on every row (verified: 29,571/29,571), and accuracy is float-formatted
("4.0" instead of "4") — both classic pandas round-trip artifacts.
admin_code1 is GeoNames' own internal numbering ("01"–"27"), not
ISO 3166-2:UA — using it as-is would ship the wrong codes.
datapackage.yml's declared resource (7,465 bytes, dated 2024-11-07)
doesn't match the live object (2,373,590 bytes) either — stale metadata
on top of the data defect, same pattern as every other legacy placeholder
audited this batch.
Source 1 — GeoNames UA postal export (the base)
https://download.geonames.org/export/zip/UA.zip # 29,571 rows
Licence CC BY 4.0, verified against export/zip/readme.txt on
2026-08-31 — no per-country caveat for Ukraine.
Real limitation, verified directly against the raw file (not the sold
copy): the postal export itself has no raion (district) tier at
all — admin_name2 simply duplicates admin_name1 (the oblast name)
on every row, and admin_code2/admin_name3/admin_code3 are blank.
This is a genuine source gap, not something introduced downstream.
Source 2 — GeoNames UA gazetteer dump (admin enrichment, same publisher)
https://download.geonames.org/export/dump/UA.zip # 45,380 entries
Same licence, same publisher, not a new source. Carries GeoNames' own
admin1 (27 codes: 24 oblasts + Crimea + Kyiv City + Sevastopol City)
and admin2 (raion-level, 146 codes) fields on 33,505 of its own
populated-place entries.
Real finding, cross-checked against a primary account of Ukraine's own 2020 reform (Verkhovna Rada resolution, 2020-07-17, reported by The Ukrainian Weekly and KyivPost): Ukraine consolidated 490 old raions into 136 new raions (including 10 in Crimea, de facto outside Ukrainian control since 2014). GeoNames' dump carries 146 UA admin2 codes — exactly 136 (the new national raion count) + 10 (Kyiv City's own internal city districts, a separate tier that sits under Kyiv City rather than being one of the 136 national raions). This is strong, specific evidence the dump reflects the post-reform structure, not a stale pre-2020 one — the opposite risk to the one caught for Norway's fylke reform, checked here before trusting the dump at scale.
Join feasibility, checked before committing to a build
The postal export's place names are Cyrillic (Черкаси); the dump's
name/asciiname fields are Latin transliterations (Cherkasy) — a
naive name-to-name join against name/asciiname alone matches zero
rows. The dump's alternatenames column does carry the Cyrillic form as
one of several comma-separated aliases. Matching against
name ∪ asciiname ∪ alternatenames recovers 22,224/29,571 (75%)
exact matches before any coordinate disambiguation or nearest-neighbour
fallback (the RS/ZA pattern) — a workable base for a future build, though
this needs the fallback pass run and measured (not yet done — this is a
research pass, not a build) before a real coverage number can be quoted.
❌ Ukrposhta — no bulk source, not a licensing block
No official Ukrposhta open-data bulk download or API was found (checked
2026-08-31) — same shape as Serbia's Posta Srbije and Poland's situation
before its PDF-only book edition: real-world lookup exists
(services.ukrposhta.com/postindex_new/) but nothing bulk/open. This is
a data-availability gap, not a resale prohibition.
ISO 3166-2:UA — GeoNames' internal numbering is NOT the ISO scheme
Verified against en.wikipedia.org/wiki/ISO_3166-2:UA on 2026-08-31.
GeoNames' admin1 codes (01–27) are an internal, unrelated numbering.
A verified name-based crosswalk (all 27 GeoNames admin1 names match one
ISO entry each, zero misses):
| GeoNames name | ISO code | GeoNames name | ISO code |
|---|---|---|---|
| Cherkasy | UA-71 | Kyiv Oblast | UA-32 |
| Chernihiv Oblast | UA-74 | Luhansk | UA-09 |
| Chernivtsi | UA-77 | Lviv | UA-46 |
| Crimea | UA-43 | Mykolaiv | UA-48 |
| Dnipropetrovsk | UA-12 | Odesa | UA-51 |
| Donetsk | UA-14 | Poltava | UA-53 |
| Ivano-Frankivsk | UA-26 | Rivne Oblast | UA-56 |
| Kharkiv | UA-63 | Sevastopol City | UA-40 |
| Kherson | UA-65 | Sumy | UA-59 |
| Khmelnytskyi | UA-68 | Ternopil | UA-61 |
| Kirovohrad | UA-35 | Vinnytsia | UA-05 |
| Kyiv City | UA-30 | Volyn | UA-07 |
| Zakarpattia | UA-21 | ||
| Zaporizhzhia | UA-23 | ||
| Zhytomyr Oblast | UA-18 |
Disclosure needed for any future build — factual, not political
Crimea (UA-43) and Sevastopol City (UA-40) are Ukrainian territory under ISO 3166 and under Ukraine's own law, and are included on that basis — same treatment this project already gives other administratively-defined regions. But they have been outside actual Ukrainian civil administration since Russia's 2014 annexation, and parts of Donetsk (UA-14), Luhansk (UA-09), Zaporizhzhia (UA-23) and Kherson (UA-65) oblasts have been under Russian occupation since 2022. This is a real postal-service currency question, not an administrative-boundary question: any rows in occupied territory should be labelled as sourced from GeoNames' (pre-war) postal data rather than implied to reflect current, operating Ukrainian postal service in those areas. Disclose in README/ATTRIBUTION if built — do not omit the regions (that would misrepresent Ukraine's actual administrative structure) and do not silently imply full current postal operability either.
licence_status
{
"channel": "postal-codes-r2",
"source_url": "https://download.geonames.org/export/zip/UA.zip",
"licence_id": "CC-BY-4.0",
"collected_at": "2026-08-31",
"decision": "compatible",
"decided_by": "claude-session-2026-08-31",
"decided_at": "2026-08-31",
"note": "No official bulk source exists to consolidate onto GeoNames; admin enrichment is same-publisher/same-licence GeoNames-to-GeoNames (postal export + gazetteer dump), not a second source with its own terms."
}
Proposed tier
B ($49). Single publisher (GeoNames, both exports) normalised in
place with real derivation work — same-source raion-tier recovery via
the dump join, verified ISO 3166-2:UA crosswalk (GeoNames' numbering is
unrelated to ISO's), and fixing the "nan"/float-accuracy corruption — but
no independent second-source consolidation, so this doesn't clear tier
A's bar per docs/PRICING_TIERS.md. Same shape as RS/ZA/BG.
Moat
Low-Medium. GeoNames is openly downloadable, and the dump-join technique is now standard in this catalogue (RS/ZA). What's not entirely trivial to redo: catching the Cyrillic/Latin naming mismatch that zeroes out a naive join, and independently verifying the dump reflects the post-2020 raion reform (146 = 136 + Kyiv's 10 city districts) rather than assuming it and shipping a stale structure.
Build — 2026-08-31 (local only, not published)
Built via datasets/ua/scripts/build_postal_codes_product.py. Results,
measured directly:
| value | |
|---|---|
| Final rows | 29,571 |
| Distinct postal codes | 26,579 |
| Regions covered | 26/27 — Sevastopol City (UA-40) has zero rows: GeoNames' postal export has no codes there at all, consistent with Ukraine not administering postal service there since 2014 |
| Raions covered | 130/136 |
| Exact-name matches (incl. alternatenames) | 20,304 |
| Fallback nearest-neighbour matches | 9,267 |
| Unresolved | 0 |
| Duplicate (postal_code, place_name) pairs | 0 |
| Literal "nan" strings in output | 0 |
Frictionless validation: valid: True.
Status: built and validated locally only. Nothing published to R2,
nothing committed to git. datasets/ua/README.md and datapackage.yml
updated in place (tier B, premium_source_key: ua/ua.zip, real
sources/licenses, replacing the "Multiple sources" placeholder).