countries-states-cities-database Documentation

Discover our global repository of countries, states, and cities! πŸ™οΈ Get comprehensive data in JSON, SQL, PSQL, SQLSERVER, MONGODB, SQLITE, XML, YAML, and...

9,890 stars Python Python 2 files Β· ~8,178 tokens #cities#countries#country#csv#geographical-data#psql#regions#state
RAW Doc

Technical Documentation: dr5hn/countries-states-cities-database

ℹ️ Provenance: Multi-Tier Ingestion Β· CodeWiki Reference

Overview (README.md)

Total Regions : 6
Total Sub Regions : 22
Total Countries : 250
Total States/Regions/Municipalities : 5,299
Total Cities/Towns/Districts : 153,765
Total Postcodes : 725993 (116 countries)
Total Timezones : 427 (100% IANA coverage)
Last Updated On: October 19, 2026



The two managed products below are the fastest path to shipping. They're actively maintained, billed for sustainability, and back the rest of the ecosystem.

REST API β€” `api.countrystatecity.in`

Query countries, states, cities, and postcodes from any language. Free tier for prototyping; paid tiers for production.

bash
curl https://api.countrystatecity.in/v1/countries/IN/states/MH/cities \
  -H "X-CSCAPI-KEY: $YOUR_API_KEY"

Python applications can use the official sync and async client:

bash
pip install countrystatecity-api
export CSC_API_KEY="YOUR_API_KEY"
python
from countrystatecity import CountryStateCity

with CountryStateCity() as client:
    states = client.get_states_of_country("IN")
    print([state["name"] for state in states[:3]])

Get a free API key β†’ Β·
Compare plans Β·
Documentation Β·
Interactive playground Β·
OpenAPI spec Β·
Status

Export Tool β€” `export.countrystatecity.in`

Build tailored datasets in your browser β€” pick country, region, format, and field selection, then download.

Launch the Export Tool β†’


Other ways to use the data

NPM (JavaScript / TypeScript)

Package GitHub NPM
@countrystatecity/countries GitHub npmjs.com
@countrystatecity/countries-browser GitHub npmjs.com
@countrystatecity/currencies GitHub npmjs.com
@countrystatecity/timezones GitHub npmjs.com
@countrystatecity/translations GitHub npmjs.com
@countrystatecity/cli GitHub npmjs.com

PyPI (Python)

Use countrystatecity-api for live, managed data. The suffixed packages are versioned offline snapshots.

Package Use GitHub PyPI
countrystatecity-api Live REST API client GitHub pypi.org
countrystatecity-countries Offline snapshot GitHub pypi.org
countrystatecity-timezones Offline snapshot GitHub pypi.org
countrystatecity-currencies Offline snapshot GitHub pypi.org
countrystatecity-translations Offline snapshot GitHub pypi.org
countrystatecity-phonecodes Offline snapshot GitHub pypi.org
countrystatecity-regions Offline snapshot GitHub pypi.org
countrystatecity-postal-codes Offline snapshot GitHub pypi.org

Direct download (gzipped exports)

Countries, states, counties, cities, and postcodes are separate datasets. Counties contain official intermediate
administrative units; cities can link to them through a nullable county_id. See
the county field shape and link rules.

Every format ships as a .gz asset on each GitHub Release.

bash
curl -LO https://github.com/dr5hn/countries-states-cities-database/releases/latest/download/json-cities.json.gz
gunzip json-cities.json.gz
curl -LO https://github.com/dr5hn/countries-states-cities-database/releases/latest/download/json-counties.json.gz
gunzip json-counties.json.gz

Smaller reference files (countries, states, counties, schema) live in the repo. Use git clone --depth 1 for a fast clone.

Other packages and platforms


What's in the data

  • 250 countries Β· 5,329 states / regions Β· 14,058 counties Β· 153,513 cities Β· 840k+ postcodes across 125 countries
  • 19 languages of country and state names plus native script
  • 100% IANA timezone coverage for cities
  • Validated foreign keys on every contribution
  • Formats: JSON, MySQL, PostgreSQL, SQLite, SQL Server, MongoDB, XML, YAML, CSV, GeoJSON, TOON (LLM-optimised, ~40% fewer tokens than JSON), Parquet (columnar, analytics-ready)
Format Export time Size Compressed
CSV 1s 40 MB 9 MB
MongoDB dump 1s 30 MB 20 MB
MySQL SQL 3s 86 MB 22 MB
JSON 4s 271 MB 18 MB
TOON 5s 23 MB 20 MB
Parquet 7s 31 MB 27 MB
GeoJSON 8s 208 MB 24 MB
XML 9s 91 MB 15 MB
YAML 17s 68 MB β€”
SQLite 45s 89 MB β€”

Contributing

The easiest way is the Community Manager β€” submit corrections through a web UI with end-to-end tracking.

To edit JSON directly:

  1. Fork and clone (git clone --depth 1).
  2. Edit files under contributions/cities/, contributions/states/, contributions/countries/, contributions/counties/, or contributions/postcodes/.
  3. Required for new cities: name, state_id, state_code, country_id, country_code, latitude, longitude. Optional: timezone, wikiDataId, native.
  4. Omit id, created_at, updated_at, flag β€” auto-managed on import.
  5. Open a pull request with a clear data source. If it removes, repurposes or restores ids, include its reviewed
    ledger events keyed by event_pr in that same PR.
    The Ledger migrations check validates the merge preview; all ids must be final at that preview.
json
{
  "name": "San Francisco",
  "state_id": 1416,
  "state_code": "CA",
  "country_id": 233,
  "country_code": "US",
  "latitude": "37.77493",
  "longitude": "-122.41942",
  "timezone": "America/Los_Angeles",
  "wikiDataId": "Q62"
}

Contributions guide Β·
Contribution guidelines Β·
Multi-level territories policy Β·
Data versioning Β·
Disputed and special territories Β·
Administrative structure policy Β·
The cities.type field

Don't edit the auto-generated directories (json/, csv/, xml/, yml/, sql/, etc.). They're rebuilt from MySQL on every release.


License and attribution

Licensed under the Open Database License (ODbL v1.0). Commercial use, modification, and redistribution all permitted. Attribution is required, and derivatives must be shared under the same license.

text
Data by Countries States Cities Database
https://github.com/dr5hn/countries-states-cities-database | ODbL v1.0

Some records also carry names or points copied from open sources that ask for credit: GeoNames
(CC BY 4.0), Β© OpenStreetMap contributors
(ODbL 1.0) and Wikidata (CC0). Points are selected per record and
rounded to eight decimals; the per-record source ledgers are in .github/fixes-docs/ledgers/.
Official registers matched to records (categories, codes and unit names) also ask for credit:

Country names in some languages follow Unicode CLDR 48.2: Copyright Β© 2015-2024 Unicode, Inc., under the Unicode License v3, whose notice must travel with copies.

Source credits and notices for 63 sources are in .github/licenses/SOURCES.txt; export releases attach it with the other notices. The register also identifies 233 sources whose redistribution basis remains under review. Keep the applicable credits and notices when redistributing the data.


Support

If this project saves you time, please consider supporting its continued maintenance.


You can also plant a tree on behalf of the project.

Reach out: gadadarshan [at] gmail [dot] com



Sponsors

Disclaimer

Community-maintained data may contain errors or lag behind geopolitical changes. Verify critical data with official sources. Report issues.



Releases V5.0.0 (`docs/releases/v5.0.0.md`)

Countries States Cities Database v5.0.0

Counts describe source commit
d8a54626622012ee9f520108fddfdd8d11f29ae8,
compared with the v4.0 snapshot.

What this release changes

v5 is the corrective major after v4. It repairs ids that disappeared during the v4 export series,
separates administrative territories from the places that serve as their seats, and replaces
postcode values whose source support was missing. It also introduces cities without a state and
counties that belong to several regions.

This is a major because it removes keys, repairs ids that had come to denote another entity,
and changes the schema and documented settlement filters. From v5 onward, an id identifies one
geographic entity within its table. Regular releases can correct its facts and add records;
removals and incompatible contract changes wait for a major. Retired ids cannot be assigned to
another entity. A reviewed restoration of the same entity is allowed.
See the data versioning contract.

Breaking changes

Removed and repaired ids

Keys present in v4.0 but absent from this candidate:

Table Removed ids Main reasons
Countries 0 No country id retired in this comparison.
States 8 Achaea moved to counties; seven states retired by the four reforms below.
Counties 9 Connecticut's 8 historical counties, with no successor; Alaska's Valdez-Cordova, split in two.
Cities 3,485 Administrative units moved to other tables, unit/seat distinctions, reviewed duplicates, no proved successors, and identity repairs.
Postcodes 133,243 Unsupported source or locality scope, replaced code namespaces, and reviewed duplicate removal.

These are endpoint counts, not a count of all historical removal events. The migration manifest
also reports events and restorations. Use the individual reviewed reason, rather than assuming
that a retired row represents a place or postal code that disappeared in the real world.

1,353 city ids that had come to denote a different entity are retired, with fresh ids for
the later entity. An administrative district and its seat town are distinct entities even when
their names match. Do not replace every retired unit id with its seat's id. The migration files
separately describe the original entity and the later entity.

Cities without a state

state_id and state_code may both be null for a city in a country with no states. Accept the
null pair in storage, response models and filters. A mandatory join through states would lose
these cities. In nested country exports, read the country-level cities array as well as cities
inside states; MongoDB omits a state reference for such a city.

Western Sahara has 3 such cities in contributions/cities/EH.json: Gueltat Zemmour, Imlili
and Smara. Their city ids stay the same when they move from MA to EH. They do not acquire a
Moroccan state or a fabricated EH state.
See the nullable-state change
and the territory data changes.

Counties in several regions

7 New Zealand councils now have 16 county-region links. A county either has its
usual state pair, or has both fields null and a states list of {state_id, state_code} pairs.
A linked city still has its own state, which must be one of the county's regions.

Relational exports use county_states (county_id, state_id). CSV and PLIST supply a separate
county-state relation file; Parquet and TOON encode the list as JSON text. Update consumers
that assume a county always has one state. See the format and schema changes.

Schema and SQL imports

Apply the nullable city-state and county-region schema upgrades before loading into an existing
database, or rebuild using the schema supplied with this snapshot. SQL INSERT statements now
name their columns. Importers that parse positional INSERTs must accept column lists; a custom
schema must still provide the named columns and compatible types.
See the database upgrade instructions
and the dump change.

Migrating ids you have stored

Pin the exact data snapshot you use. An API protocol version or npm/PyPI package version alone
is not a data snapshot. The owner will confirm API and package rollout dates separately; this
page does not mean those products have already switched.

The first v5 export's builder supplies migrations-from-v4.0.tar.gz, with
MIGRATIONS_SHA256SUMS and MIGRATIONS_SOURCE. Verify the archive checksum and source commit.
Inside, release_manifest.json identifies from.sha, to.sha, release versions, per-table
counts and file checksums. The candidate uses migration format 3.

Use removed_ids.jsonl (or its CSV view) to look up (old_table, old_id), not an id alone.
Check present_at_from, present_at_to and restored_at: the file is a history of removals,
and a key that was later restored and is present at the target is not currently retired.
current_targets follows relations to the end of the interval. Multiple targets need a choice;
empty targets or a terminal no-successor outcome supply no replacement.

Read identity_changes.jsonl too. For a repaired id, current_targets refers to what the id
originally denoted; later_entity_targets refers to what it later came to denote. Match the
meaning in your stored record. A prior entity marked ended or unrecorded can have no target.
Neither identity repair nor territorial succession, split, dataset move or seat relationship
permits an automatic redirect.

Only a current_targets entry whose automatic_redirect is true can be applied automatically:
every step must be a reviewed merge of the same entity. For example, the reviewed duplicate
postcode 85289 β†’ 85290 keeps the existing Larnaka record; the
postcode change records that merge.
A guarded lookup looks like this:

python
import json
for line in open('removed_ids.jsonl', encoding='utf-8'):
    event = json.loads(line)
    if (event['old_table'], event['old_id']) != ('postcodes', 85289):
        continue
    if event['present_at_to']:
        continue  # not retired at the target snapshot
    for target in event['current_targets']:
        if target['automatic_redirect']:
            print(target['table'], target['id'])  # postcodes 85290

Back up your mappings, apply reviewed choices to your own references, and check that every
resulting (table, id) exists in the pinned v5 snapshot. Keep unresolved cases for manual review.
added_ids.jsonl lists additions; changed_fields.jsonl gives typed before/after values and
presence flags for retained keys.

If you use a later v4 export, load v5 data fresh and use the cumulative history to map the ids
you stored. Do not patch that export with the cumulative added/changed files: those are relative
to v4.0, and some ids in later exports did not exist at that baseline. The current builder does
not supply an export.51 delta. Subsequent v5 exports supply a step from the previous published
v5 snapshot; apply matching steps in order.
See the migration files and archive rules.

Unresolved records and strict use

This candidate retains 12,140 keys whose latest identity decision is unresolved.
The data does not yet prove whether each legacy row originally denoted a settlement or a
territory. Independently proved facts can remain, while unproved category, hierarchy or item
changes are withheld. An unresolved row never redirects automatically.

Start with the cumulative identity_changes.jsonl, including its baseline: true entries.
Keep the latest decision for each (table, id) in file order; apply later releases' decisions
and reviewed removals. Strict territorial users exclude retained keys whose latest outcome is
unresolved. Absence from a later file does not resolve a key. A settlement type filter alone
is not a substitute for this exclusion. Disclosure of an unresolved key does not approve
a pending name or territorial change; outstanding publication holds still need a decision.

Data changes to check before switching

Postcode coverage

Removed postcode ids since v4.0 include Malta 25,813, China 19,255, Myanmar 17,331,
Paraguay 8,644, Tunisia 4,860, Nigeria 3,728, Tanzania 3,684,
Argentina 10,628, South Africa 4,953, Ukraine 4,422, and Spain 8,124.
The full country/outcome breakdown is in appendix_postcode_removals_by_country.csv.

A replacement product must support the entity the id denoted: sometimes a code alone,
sometimes a code plus locality, district or delivery kind. Malta's locality prefixes and China's
general codes cannot silently replace finer delivery codes. Some rows retire even though their
code occurs in the replacement product. A removal for missing source support is not a finding
that mail cannot be delivered there. Supported values were re-derived; unsupported points,
localities and links may be null. Spanish municipality codes used as postal ids were replaced
with actual postal-code coverage rather than redirected by number.

After those removals, 4,137 postcodes were added for 24 countries left with little or no coverage, from
OpenStreetMap (ODbL, only codes with an explicit street address basis) and GeoNames (CC BY), each with a fresh id: for
example Iran 2,632, China 402, Vietnam 246, Greece 139, Nigeria 101 and Paraguay 100. Their state and city links are
empty until proved. See the additions.

United States counties and towns

US counties now match the US Census Bureau's 2024 Gazetteer: 3,144 counties, all its entries reconciled. Connecticut's
8 historical counties retire with no redirect, because the 9 planning regions that replaced them in 2022 are a
different geography; the regions are added as counties, and 179 of Connecticut's 182 cities link to one. 63 missing
county-equivalents are added, including Virginia's 38 independent cities, and Alaska's Valdez-Cordova splits into
Chugach and Copper River. Puerto Rico's municipios stay under the PR country. 610 New England towns that had no city
row are added with fresh ids, and 44 city populations that were wrong are corrected or cleared. See
the counties and
the towns.

Country names

Two display names follow Unicode CLDR 48.2.0's short forms, as the naming rule in
DISPUTED_AND_SPECIAL_TERRITORIES.md sets out:
Palestine's English name is now "Palestine" (was "Palestinian Territory Occupied"), and all its translations use the
short form (for example ru ΠŸΠ°Π»Π΅ΡΡ‚ΠΈΠ½Π°, ar ΩΩ„Ψ³Ψ·ΩŠΩ†, ko νŒ”λ ˆμŠ€νƒ€μΈ, nl Palestina); Taiwan's Japanese and Chinese translations
are now 台湾. Codes and ids are unchanged; the former values are the before values in changed_fields.jsonl.
See the name change and
its follow-up.

Territories, names and moves

The CN-TW and CN-HK unit rows in the city table retire, with mappings to the TW and HK state
tables. TW and HK remain separate country lookups; CN-TW and CN-HK remain catalogue entries.
These cross-table mappings are not automatic city redirects. Western Sahara's province rows
in the city table retire to their existing MA state records.

For the owner's check: Crimean names follow Ukraine's official romanisation, with
283 name changes in the earlier territory update,
including legal renames such as Krasnoperekopsk β†’ Yany Kapu and Kalinino β†’ Umiut.
Har Adar and Modiin Ilit move from IL to PS; their local names and Israeli clock remain.
East Jerusalem's clock changes from Asia/Gaza to Asia/Jerusalem.
appendix_renames_moves_for_review.csv lists endpoint name, country, state, county, parent and
point changes on retained keys, plus the earlier territory update separately, including its
later-retired rows. These comparison groups overlap and must not be summed. Identity decisions
are included where available; a changed label or point alone does not prove continuity.

Γ…land is restored under its original states 1509 key as FI-01, the same catalogue entity.
This is a reviewed same-entity restoration, not reuse for a new place.
See the restoration.

Settlement queries

Update to the documented settlement query:
exclude administrative-only and defunct types; additionally exclude municipality in MX, GR
and VN, and names beginning Gemeente in NL. Require non-null coordinates. Keep null types
only if your use case accepts unclassified records. The Vietnam rule distinguishes new
commune/ward territories from former cities and towns retained as urban places.

sql
SELECT * FROM cities
WHERE (type IS NULL OR type NOT IN (
  'county', 'regency', 'prefecture', 'parish', 'banner', 'province',
  'area', 'oblast', 'administrative zone', 'region', 'abandoned',
  'historical', 'destroyed', 'religious', 'historical_capital'
))
AND (country_code NOT IN ('MX', 'GR', 'VN') OR type IS NULL OR type <> 'municipality')
AND NOT (country_code = 'NL' AND name LIKE 'Gemeente %')
AND latitude IS NOT NULL AND longitude IS NOT NULL;

The earlier type-only review documented 247 membership changes: 216 leaving
and 31 entering, across AU 1, CA 1, CN 1,
GR 22, KR 29, MX 142 and ZA 51.
This historical list is preserved in appendix_settlement_query_changes.csv, with each row's
current presence, type and query membership. After the subsequent identity corrections, that
same cohort has 10 leaving and 0 entering relative to v4.0.
The historical total is not the final release's total query difference.

State reforms

  • South Korea: South Jeolla (states 3856) retires as territorial_successor; current targets: states 5854; Gwangju (states 3858) retires as territorial_successor; current targets: states 5854. The new state codes are project-assigned, not ISO issuances.
  • Estonia: JΓ΅hvi (states 5746) retires as territorial_successor; current targets: states 5855; Toila (states 5788) retires as territorial_successor; current targets: states 5855. The new state codes are project-assigned, not ISO issuances.
  • Angola: Cuando Cubango (states 226) retires as split_into; current targets: states 5856, states 5857. The new state codes are project-assigned, not ISO issuances.
  • Latvia: Varakļāni (states 4431) retires as territorial_successor; current targets: states 5858; Madona (states 4433) retires as territorial_successor; current targets: states 5858. The new state codes are project-assigned, not ISO issuances.

Sources and reuse

CSC's own ODbL licence is unchanged. The source products and required credits have changed.
Much postcode data is now re-derived from named GeoNames products under CC BY, alongside
national open products. Malta and China also use OpenStreetMap under ODbL; Taiwan uses
Chunghwa Post under Taiwan's Open Government Data License. Other replacements include
Kadaster's public-domain postcode data and Ordnance Survey Code-Point Open. US counties and
New England towns come from US Census Bureau files, which are public domain.

Keep the supplied SOURCES.txt and accompanying licence notices with redistributed data,
including the specified attribution, source editions, licence links and modification notices.
Do not assume CSC's licence removes a source's attribution requirements. Some former sources
are excluded; others support only the narrower facts identified in their notices.
See the source credits and conditions.

v4 support

The API keeps serving v4 data for six months after v5.0.0 is published, until 19 April 2027. v4
downloads and the migration files stay available. Switch your clients and stored ids within that window.


--- METRICS ---