curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Mumbay&type=city&country=IN' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Maharashtra&type=state&country=IN' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Pune&type=city&country=IN&state=MH&limit=5' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
const params = new URLSearchParams({ q: 'Mumbay', type: 'city', country: 'IN' });
const response = await fetch(
`https://api.countrystatecity.in/v1/search/autocomplete?${params}`,
{ headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' } }
);
const results = await response.json();
results.forEach((r) => console.log(`${r.label} (${r.match_score})`));
import requests
response = requests.get(
'https://api.countrystatecity.in/v1/search/autocomplete',
params={'q': 'Mumbay', 'type': 'city', 'country': 'IN'},
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
for result in response.json():
print(f"{result['label']} -> {result['match_score']}")
[
{
"id": 132332,
"name": "Mumbai",
"state_id": 4008,
"state_code": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.07283000",
"longitude": "72.88261000",
"timezone": "Asia/Kolkata",
"native": "मुंबई",
"type": "city",
"label": "Mumbai, Maharashtra, India",
"match_score": 0.75,
"matched_field": "name"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata",
"type": "state",
"label": "Maharashtra, India",
"match_score": 1,
"matched_field": "name"
}
]
{
"status": "error",
"message": "Invalid query parameters: q: Search query must be at least 2 characters"
}
{
"status": "error",
"message": "Invalid query parameters: state: country is required when filtering by state"
}
{
"status": "error",
"message": "Invalid query parameters: state: state is only a valid filter when type=city"
}
{
"status": "error",
"message": "This feature is not available on your current plan.",
"details": {
"feature": "autocomplete",
"currentTier": "starter",
"requiredTier": "supporter",
"upgradeUrl": "https://app.countrystatecity.in/pricing"
}
}
Autocomplete
Type-ahead search for cities, states, and countries with deterministic ranking and ready-to-display labels
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Mumbay&type=city&country=IN' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Maharashtra&type=state&country=IN' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Pune&type=city&country=IN&state=MH&limit=5' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
const params = new URLSearchParams({ q: 'Mumbay', type: 'city', country: 'IN' });
const response = await fetch(
`https://api.countrystatecity.in/v1/search/autocomplete?${params}`,
{ headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' } }
);
const results = await response.json();
results.forEach((r) => console.log(`${r.label} (${r.match_score})`));
import requests
response = requests.get(
'https://api.countrystatecity.in/v1/search/autocomplete',
params={'q': 'Mumbay', 'type': 'city', 'country': 'IN'},
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
for result in response.json():
print(f"{result['label']} -> {result['match_score']}")
[
{
"id": 132332,
"name": "Mumbai",
"state_id": 4008,
"state_code": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.07283000",
"longitude": "72.88261000",
"timezone": "Asia/Kolkata",
"native": "मुंबई",
"type": "city",
"label": "Mumbai, Maharashtra, India",
"match_score": 0.75,
"matched_field": "name"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata",
"type": "state",
"label": "Maharashtra, India",
"match_score": 1,
"matched_field": "name"
}
]
{
"status": "error",
"message": "Invalid query parameters: q: Search query must be at least 2 characters"
}
{
"status": "error",
"message": "Invalid query parameters: state: country is required when filtering by state"
}
{
"status": "error",
"message": "Invalid query parameters: state: state is only a valid filter when type=city"
}
{
"status": "error",
"message": "This feature is not available on your current plan.",
"details": {
"feature": "autocomplete",
"currentTier": "starter",
"requiredTier": "supporter",
"upgradeUrl": "https://app.countrystatecity.in/pricing"
}
}
label (e.g. "Mumbai, Maharashtra, India") so you don’t have to assemble one yourself.
403 on Community, Starter, and Legacy plans. Compare plans, or see Trying it without a paid plan below.Response
Returns an array. Each item carries the standard fields for the entity (city, state, or country) at your plan’s data-access level, plus:
country_code and state_code, regardless of your plan’s data-access level — even the basic-tier field set includes them here, since you can’t build a useful label or scope a follow-up request without them. (States already include country_code at every tier under the normal field rules, so no such exception is needed there.)Ranking
Results are ordered deterministically — the same query always returns the same order:| Priority | Rule |
|---|---|
| 1 | Exact match (case-insensitive) on name or native |
| 2 | Starts-with match on name or native |
| 3 | Closest remaining fuzzy match, by match_score |
| 4 | Larger population breaks ties within the same rank |
| 5 | Lower id breaks any remaining tie |
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Mumbay&type=city&country=IN' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Maharashtra&type=state&country=IN' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/search/autocomplete?q=Pune&type=city&country=IN&state=MH&limit=5' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
const params = new URLSearchParams({ q: 'Mumbay', type: 'city', country: 'IN' });
const response = await fetch(
`https://api.countrystatecity.in/v1/search/autocomplete?${params}`,
{ headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' } }
);
const results = await response.json();
results.forEach((r) => console.log(`${r.label} (${r.match_score})`));
import requests
response = requests.get(
'https://api.countrystatecity.in/v1/search/autocomplete',
params={'q': 'Mumbay', 'type': 'city', 'country': 'IN'},
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
for result in response.json():
print(f"{result['label']} -> {result['match_score']}")
[
{
"id": 132332,
"name": "Mumbai",
"state_id": 4008,
"state_code": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.07283000",
"longitude": "72.88261000",
"timezone": "Asia/Kolkata",
"native": "मुंबई",
"type": "city",
"label": "Mumbai, Maharashtra, India",
"match_score": 0.75,
"matched_field": "name"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata",
"type": "state",
"label": "Maharashtra, India",
"match_score": 1,
"matched_field": "name"
}
]
{
"status": "error",
"message": "Invalid query parameters: q: Search query must be at least 2 characters"
}
{
"status": "error",
"message": "Invalid query parameters: state: country is required when filtering by state"
}
{
"status": "error",
"message": "Invalid query parameters: state: state is only a valid filter when type=city"
}
{
"status": "error",
"message": "This feature is not available on your current plan.",
"details": {
"feature": "autocomplete",
"currentTier": "starter",
"requiredTier": "supporter",
"upgradeUrl": "https://app.countrystatecity.in/pricing"
}
}
Trying it without a paid plan
A separate Playground plan powers the interactive API documentation — a basic-tier field set on a shared rate limit sized for many concurrent visitors, not a per-visitor quota. It isn’t something you can sign up for directly; it is only for the docs playground. For your own integration, choose a Supporter plan or higher.Related Endpoints
- Fuzzy Search — pure similarity ranking, without the tiered exact/starts-with/fuzzy order or a computed
label - Get All Countries — exact/substring inline search via
?q= - Get Cities by Country — list cities, filterable by
?q=
Authorizations
API key for authentication. Get your free key at app.countrystatecity.in.
Query Parameters
Search query — 2 to 100 characters. Case-insensitive.
2 - 100"Mumbay"
Entity type to search
city, state, country "city"
ISO 3166-1 alpha-2 country code to narrow the search (e.g., IN). Invalid when type=country — supplying both returns a 400.
2^[A-Za-z]{2}$"IN"
State/province ISO code to narrow a city search further (e.g., MH). State codes are not globally unique, so this requires country to also be set and is valid only when type=city.
1 - 20"MH"
Maximum number of results to return (1–50)
1 <= x <= 5010
Adds localized_name and matched_locale, and starts label with the localized name. The English name and id stay unchanged. Supporter+ plans only.
2 - 7^[a-zA-Z]{2}(-[a-zA-Z]{2,4})?$"ja"
When true, includes the full translation JSON string. Supporter+ plans only.
true
Response
List of matching results ranked by relevance
Entity type of the matched result
country, state, city "city"
Ready-to-display label. When locale is supplied on a Supporter+ plan, the first place name is localized. Parent state and country names remain English.
"ムンバイ, Maharashtra, India"
Entity ID (city, state, or country)
57606
English name of the matched entity
"Mumbai"
Relevance score (0–1, rounded to 2 decimals). Higher is a closer match.
0.95
Which field the match was found against.
name, native, translation "translation"
JSON string of translations. Supporter+ plans only, and only when include_translations=true is passed.
Localized display name selected by locale. The English name remains unchanged. Supporter+ plans only.
"ムンバイ"
Translation or fallback used for localized_name: the exact locale, base language, native, or en. Supporter+ plans only.
"ja"
ISO 3166-1 alpha-2 code (type=country) or state ISO code (type=state). Not present on type=city results.
"IN"
ISO 3166-1 alpha-3 code. Only present for type=country; not present otherwise.
"IND"
Parent state ISO code. Always present for type=city; null otherwise.
"MH"
Parent country ISO2 code. Always present for type=city and type=state; null for type=country.
"IN"