curl -X GET 'https://api.countrystatecity.in/v1/meta/data-version' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_data_version():
"""Fetch the geographic data release currently live behind the API."""
response = requests.get(
'https://api.countrystatecity.in/v1/meta/data-version',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
return response.json()
else:
print('Data version temporarily unavailable')
return None
version = get_data_version()
const getDataVersion = async () => {
const response = await fetch('https://api.countrystatecity.in/v1/meta/data-version', {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
if (response.ok) {
return await response.json();
} else {
console.error('Data version temporarily unavailable');
return null;
}
};
getDataVersion();
{
"dataVersion": "v3.2-export.7-2026.07.30",
"sourceRelease": "v3.2-export.7",
"updatedAt": "2026-07-30T09:01:18.000Z",
"recordCounts": {
"regions": 6,
"subregions": 22,
"countries": 250,
"states": 5308,
"cities": 152970
}
}
{
"status": "error",
"message": "Data version information is temporarily unavailable."
}
Meta Endpoints
Get Data Version
Check which geographic data release your API responses are currently served from
GET
/
v1
/
meta
/
data-version
curl -X GET 'https://api.countrystatecity.in/v1/meta/data-version' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_data_version():
"""Fetch the geographic data release currently live behind the API."""
response = requests.get(
'https://api.countrystatecity.in/v1/meta/data-version',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
return response.json()
else:
print('Data version temporarily unavailable')
return None
version = get_data_version()
const getDataVersion = async () => {
const response = await fetch('https://api.countrystatecity.in/v1/meta/data-version', {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
if (response.ok) {
return await response.json();
} else {
console.error('Data version temporarily unavailable');
return null;
}
};
getDataVersion();
{
"dataVersion": "v3.2-export.7-2026.07.30",
"sourceRelease": "v3.2-export.7",
"updatedAt": "2026-07-30T09:01:18.000Z",
"recordCounts": {
"regions": 6,
"subregions": 22,
"countries": 250,
"states": 5308,
"cities": 152970
}
}
{
"status": "error",
"message": "Data version information is temporarily unavailable."
}
Returns the version of the underlying geographic dataset currently live behind the API β which upstream release it was exported from, when that release was imported, and a record-count snapshot taken at import time.
The packageβs
Availability: All plans (Community and above) β no tier restriction. The request still counts toward your daily/monthly usage quota like any other endpoint.
Authentication
string
required
Your API key for authentication
Response
string
The full version string, in
<source-release>-<YYYY.MM.DD> format (e.g. v3.2-export.7-2026.07.30). The date part is the day the release was imported into the API, not the day the release was published β so the same data can carry a different date string in the npm package. See npm package parity below. This is the same value sent on the X-CSC-Data-Version header of every /v1/* response β see Response headers on every request below.string
The upstream release tag from the countries-states-cities-database this data was exported from. Compare this field β not
dataVersion β when you want to check whether two copies of the data are on the same release.string
ISO 8601 UTC timestamp of when this release was imported, with milliseconds β for example
2026-07-30T09:01:18.000Z.object
A snapshot of row counts taken at import time β not computed live on each request. The counts change with every release, so treat the numbers in the example below as illustrative.
curl -X GET 'https://api.countrystatecity.in/v1/meta/data-version' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_data_version():
"""Fetch the geographic data release currently live behind the API."""
response = requests.get(
'https://api.countrystatecity.in/v1/meta/data-version',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
return response.json()
else:
print('Data version temporarily unavailable')
return None
version = get_data_version()
const getDataVersion = async () => {
const response = await fetch('https://api.countrystatecity.in/v1/meta/data-version', {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
if (response.ok) {
return await response.json();
} else {
console.error('Data version temporarily unavailable');
return null;
}
};
getDataVersion();
{
"dataVersion": "v3.2-export.7-2026.07.30",
"sourceRelease": "v3.2-export.7",
"updatedAt": "2026-07-30T09:01:18.000Z",
"recordCounts": {
"regions": 6,
"subregions": 22,
"countries": 250,
"states": 5308,
"cities": 152970
}
}
{
"status": "error",
"message": "Data version information is temporarily unavailable."
}
Response headers on every request
Two of the fields above are also stamped as headers on every/v1/* response, not just this endpoint β so you can track the live data version without an extra request:
| Header | Meaning |
|---|---|
X-CSC-Data-Version | Same value as dataVersion above |
X-CSC-Data-Updated-At | Same value as updatedAt above |
X-Request-ID | Server-generated UUID, unique per request β include it when contacting support about a specific request |
This metadata is cached, so it can trail a fresh import. This route reads through a 5-minute-TTL cache backed by Redis, so right after an import it can report the previous release for up to about 5 minutes while the new data is already being served. The headers are stamped from an in-memory copy that refreshes every 30 seconds on top of that same cache, so they can trail the imported data by about 5.5 minutes β a deliberate tradeoff so stamping them never adds latency or a new failure mode to every request. Both catch up on their own; no action is needed on your side.
X-Request-ID is always present. The two X-CSC-Data-* headers are omitted until the in-memory copy has warmed after a server restart. All three appear on error responses too, because theyβre set before routing rather than per endpoint β see Errors & Rate Limits.npm package parity
The@countrystatecity/countries and @countrystatecity/countries-browser npm packages ship a getDataVersion() loader with the same dataVersion/sourceRelease/updatedAt fields, read from a small bundled version.json instead of a network call. See npm Packages for usage.
Compare
sourceRelease, not dataVersion. Both sides build dataVersion from the same release tag, but they append different dates: the npm package uses the date the release was published, while the API uses the date that release was imported. An import lands after the release is published, so the two strings usually differ by a day or more even when both sides hold exactly the same data. sourceRelease is the same string on both sides, which makes it the reliable parity key.For example, the same v3.2-export.7 release can read as v3.2-export.7-2026.07.29 in the package and v3.2-export.7-2026.07.30 from the API.recordCounts is also narrower than the APIβs: countries/states/cities only, no regions/subregions.
Related
Errors & Rate Limits
The
status/message envelope used by the 503 response above, plus usage limits by tier.npm Packages
Get the same version info without a network call via
getDataVersion().Was this page helpful?
βI