Postal Codes Dataset for Turkmenistan, TM

596
Updated:
Files:1
Size:13.8 kB
Rows:153
Formats:csv

Postal Codes Dataset for Turkmenistan, TM 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
  • Turkmenpochta public branch locator -- factual directory data (branch name, postal code, public address); no licence or terms of use published by the source 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-tm/
https://datahub.io/logistics/postal-codes-tm/_r/-/.licensing-notes.md
https://datahub.io/logistics/postal-codes-tm/_r/-/.migration-notes.md
https://datahub.io/logistics/postal-codes-tm/_r/-/ATTRIBUTION.txt
https://datahub.io/logistics/postal-codes-tm/_r/-/README.md
https://datahub.io/logistics/postal-codes-tm/_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-tm/_r/-/datapackage.yaml
README.md— documentation
https://datahub.io/logistics/postal-codes-tm/_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-tm-sample


About this dataset

Turkmenistan (TM): migration notes

Internal record of the P5 migration from the old builder to the producer: the discrepancies found, their causes, and who decided what. This is a dated record (2026-10-11), so the numbers are as of the migration and not kept current. It is not shipped in the zip.

  • Issue: datopian/postal-codes#41
  • Commit: the producer commit on this branch (the old builder was already tracked, so there is no separate recovery commit)
  • Parity verdict: unexplained (gate: blocked), accepted under the owner's under-1% rule: 1 row added (0.66%) and 1 cell corrected, both caused by a bug in the old parser
  • Producer: custom, refresh disabled

Old builder, verified

build_postal_codes_product.py (2026-09-17) parsed the rendered text of the branch-locator page, captured once with a headless browser and saved as sources/postal_raw/tm_departments_raw.json. Re-run on that saved capture on 2026-10-11 it reproduces the live tm.csv byte for byte. That capture step was manual and is not reproducible from the repo.

Source

InputURLNotes
Turkmenpochta branch listhttps://post.tm/api/departmentsOne JSON document, regions and departments. This is the endpoint the locator page at https://post.tm/departments loads its list from (the page itself is an empty shell)
  • robots.txt: post.tm/robots.txt lists /api/ as disallowed, and the operator publishes no licence or terms of use. Building a producer against this endpoint was an explicit owner instruction (2026-10-11). It makes exactly one request per run, identifies itself in the User-Agent, and refresh.enabled is false, so it only ever runs when someone runs it by hand.
  • The shipped README, ATTRIBUTION and descriptor say only what is true: the source is the locator, no licence or terms are published, the content is factual directory data.

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

Rows: 152 live and 153 fresh. 1 row only in fresh, 0 only in live, 1 changed cell (admin_name3). The other 151 rows are identical and in the same order.

Cause: a bug in the old parser, not upstream drift. The JSON lists two separate departments that the text parser merged:

RowLiveFresh
944026 Kiosk-26admin_name3 = 43-nji PAN (the next department's name taken as its address)admin_name3 empty (the department has no address)
944042 43-nji PANmissingpresent, address Aşgabat.ş. Bagtyýarlyk etr. 2216 köçesi 12-nji jaýy

Decisions

DecisionByBasis
Build a fetching producer for tm, against /api/departmentsOwner, 2026-10-11Explicit instruction, after being told the endpoint is disallowed by robots.txt. Supersedes the 2026-10-09 note "do not re-capture"
Accept +1 row and 1 corrected cell (0.66%)Owner, 2026-10-11 ("if they differ by less than 1%, then ok")Traced to the old parser, above
Whitespace normalised the way the rendered page showed it (trim, collapse runs)Agent: a faithful portThe API returns raw text ("Üzümçilik ", double spaces, tabs); without this 5 rows would differ from live by a trailing space
Coordinates stay empty although the JSON has a location per departmentAgent: a faithful portUsing them would add content the live file never had; left for the owner
Drop the hardcoded 152-row and per-region assertsP5 ruleStructural checks (known regions, 6-digit codes, unique key, all 7 regions) stand in
LF line endings; README and ATTRIBUTION kept from the repoStanding rule / agentAs for every shared producer; the repo copies were corrected in #38

Transforms carried over

  • Region by the API's region name → English name and ISO 3166-2:TM code. Arkadag (a city of state importance created in 2023) has no code and keeps admin_code1 empty.
  • place_name = branch name; admin_name3 = street address; phone numbers dropped.
  • Rows grouped by region in the site's order, then the API's own order.

Open questions

  • The JSON gives a location (latitude, longitude) for every department. Adding coordinates is a content change and an owner decision.
  • R2 is untouched. The tm zip currently in R2 predates the corrected ATTRIBUTION; publishing replaces it.

Provenance

Written 2026-10-11 from the old builder re-run, one request to the endpoint above, scripts/parity.py tm (reads the live zip, writes nothing) and the Frictionless validation of the built zip.