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": "supporter",
"requiredTier": "professional",
"upgradeUrl": "https://app.countrystatecity.in/pricing"
}
}
Search Endpoints
Autocomplete
Type-ahead search for cities, states, and countries with deterministic ranking and ready-to-display labels
GET
/
v1
/
search
/
autocomplete
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": "supporter",
"requiredTier": "professional",
"upgradeUrl": "https://app.countrystatecity.in/pricing"
}
}
Search cities, states, and countries for a type-ahead / autocomplete UI. Unlike Fuzzy Search — which ranks purely by trigram similarity — autocomplete uses a stricter, deterministic order built for a dropdown: exact matches first, then starts-with matches, then the closest remaining fuzzy matches, with population and then record ID breaking any ties. The same query always returns the same order. Each result also carries a ready-to-display
label (e.g. "Mumbai, Maharashtra, India") so you don’t have to assemble one yourself.
Availability: Professional and Business plans. Returns
403 on Community, Starter, Supporter, and Legacy plans. Compare plans, or see Trying it without a paid plan below.Matching checks the English name, native name, and stored translations. Translation matching starts at 3 characters. Responses are cached separately by query, filters, plan, locale, and translation output.
Authentication
string
required
Your API key for authentication
Query Parameters
string
required
The search text. 2–100 characters, matched case-insensitively against the English and native names.
string
default:"city"
What to search. One of
city, state, or country.string
Restrict results to a single country by ISO 3166-1 alpha-2 code, e.g.
IN, US. Case-insensitive (auto-uppercased). Not valid with type=country — sending it returns 400.string
Restrict city results to one state. This works only with
type=city and requires country. Other combinations return 400 because state codes aren’t unique across countries.integer
default:"10"
Maximum number of results to return. 1–50.
string
Add
localized_name and matched_locale, and use the localized name in label. Example: ja or pt-BR. Professional and Business plans only. See Localized Place Names.boolean
default:"false"
Include the full raw
translations JSON string. Professional and Business plans only.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:
string
Which entity this result is:
country, state, or city.string
A ready-to-display string: just the name for a country,
"State, Country" for a state, "City, State, Country" for a city. Missing parts (e.g. a city with no state on record) are omitted rather than left blank.number
Trigram similarity of the best-matching name (English or native), from
0 to 1, rounded to 2 decimals.string
Which name field matched:
name, native, or translation.string
The display name for
locale, when requested and available on your plan.string
The locale used for
localized_name, including fallback values such as native or en.City results always include
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": "supporter",
"requiredTier": "professional",
"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 Professional or Business plan.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=
Was this page helpful?
⌘I