curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states/MH/cities' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states/MH/cities?q=pune' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_cities_by_state(country_code, state_code):
response = requests.get(
f'https://api.countrystatecity.in/v1/countries/{country_code}/states/{state_code}/cities',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
cities = response.json()
print(f'Found {len(cities)} cities in {state_code}, {country_code}')
return cities
else:
print('State not found or no cities available')
return []
cities = get_cities_by_state('IN', 'MH')
const getCitiesByState = async (countryCode, stateCode) => {
const response = await fetch(
`https://api.countrystatecity.in/v1/countries/${countryCode}/states/${stateCode}/cities`,
{
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
}
);
if (response.ok) {
const cities = await response.json();
console.log(`Found ${cities.length} cities in ${stateCode}, ${countryCode}`);
return cities;
} else {
console.error('State not found or no cities available');
return [];
}
};
getCitiesByState('IN', 'MH');
<?php
function getCitiesByState($countryCode, $stateCode) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.countrystatecity.in/v1/countries/{$countryCode}/states/{$stateCode}/cities",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'X-CSCAPI-KEY: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode == 200) {
$cities = json_decode($response, true);
echo "Found " . count($cities) . " cities in {$stateCode}, {$countryCode}\n";
return $cities;
} else {
echo "State not found or no cities available\n";
return [];
}
}
$cities = getCitiesByState('IN', 'MH');
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func getCitiesByState(countryCode, stateCode string) []map[string]interface{} {
url := fmt.Sprintf("https://api.countrystatecity.in/v1/countries/%s/states/%s/cities",
countryCode, stateCode)
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-CSCAPI-KEY", "YOUR_API_KEY")
res, _ := client.Do(req)
defer res.Body.Close()
if res.StatusCode == 200 {
body, _ := ioutil.ReadAll(res.Body)
var cities []map[string]interface{}
json.Unmarshal(body, &cities)
fmt.Printf("Found %d cities in %s, %s\n", len(cities), stateCode, countryCode)
return cities
} else {
fmt.Printf("State not found or no cities available\n")
return nil
}
}
func main() {
cities := getCitiesByState("IN", "MH")
fmt.Println(cities)
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class CitiesByState {
public static void main(String[] args) throws Exception {
String countryCode = "IN";
String stateCode = "MH";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/countries/" + countryCode +
"/states/" + stateCode + "/cities"))
.header("X-CSCAPI-KEY", "YOUR_API_KEY")
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
Gson gson = new Gson();
Type listType = new TypeToken<List<Map<String, Object>>>(){}.getType();
List<Map<String, Object>> cities = gson.fromJson(response.body(), listType);
System.out.println("Found " + cities.size() + " cities in " + stateCode + ", " + countryCode);
} else {
System.out.println("State not found or no cities available");
}
}
}
require 'net/http'
require 'json'
def get_cities_by_state(country_code, state_code)
uri = URI("https://api.countrystatecity.in/v1/countries/#{country_code}/states/#{state_code}/cities")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['X-CSCAPI-KEY'] = 'YOUR_API_KEY'
response = http.request(request)
if response.code == '200'
cities = JSON.parse(response.body)
puts "Found #{cities.length} cities in #{state_code}, #{country_code}"
cities
else
puts 'State not found or no cities available'
[]
end
end
cities = get_cities_by_state('IN', 'MH')
[
{ "id": 133024, "name": "Mumbai" },
{ "id": 132332, "name": "Pune" },
{ "id": 133351, "name": "Nashik" }
]
[
{
"id": 133024,
"name": "Mumbai",
"state_id": 4008,
"state_code": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.07283000",
"longitude": "72.88261000",
"timezone": "Asia/Kolkata",
"population": 12442373,
"type": null,
"level": null,
"parent_id": null,
"native": "मुंबई"
}
]
[
{
"id": 133024,
"name": "Mumbai",
"...": "...all coordinates fields above...",
"translations": "{\"de\":\"Mumbai\",\"fr\":\"Bombay\",\"ja\":\"ムンバイ\",\"cn\":\"孟买\"}",
"wikiDataId": "Q1156"
}
]
{
"error": "No Cities found."
}
{
"error": "Unauthorized. You shouldn't be here."
}
Cities Endpoints
Get Cities by State
Retrieve all cities within a specific state/province of a country
GET
/
v1
/
countries
/
{country_iso2}
/
states
/
{state_iso2}
/
cities
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states/MH/cities' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states/MH/cities?q=pune' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_cities_by_state(country_code, state_code):
response = requests.get(
f'https://api.countrystatecity.in/v1/countries/{country_code}/states/{state_code}/cities',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
cities = response.json()
print(f'Found {len(cities)} cities in {state_code}, {country_code}')
return cities
else:
print('State not found or no cities available')
return []
cities = get_cities_by_state('IN', 'MH')
const getCitiesByState = async (countryCode, stateCode) => {
const response = await fetch(
`https://api.countrystatecity.in/v1/countries/${countryCode}/states/${stateCode}/cities`,
{
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
}
);
if (response.ok) {
const cities = await response.json();
console.log(`Found ${cities.length} cities in ${stateCode}, ${countryCode}`);
return cities;
} else {
console.error('State not found or no cities available');
return [];
}
};
getCitiesByState('IN', 'MH');
<?php
function getCitiesByState($countryCode, $stateCode) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.countrystatecity.in/v1/countries/{$countryCode}/states/{$stateCode}/cities",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'X-CSCAPI-KEY: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode == 200) {
$cities = json_decode($response, true);
echo "Found " . count($cities) . " cities in {$stateCode}, {$countryCode}\n";
return $cities;
} else {
echo "State not found or no cities available\n";
return [];
}
}
$cities = getCitiesByState('IN', 'MH');
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func getCitiesByState(countryCode, stateCode string) []map[string]interface{} {
url := fmt.Sprintf("https://api.countrystatecity.in/v1/countries/%s/states/%s/cities",
countryCode, stateCode)
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-CSCAPI-KEY", "YOUR_API_KEY")
res, _ := client.Do(req)
defer res.Body.Close()
if res.StatusCode == 200 {
body, _ := ioutil.ReadAll(res.Body)
var cities []map[string]interface{}
json.Unmarshal(body, &cities)
fmt.Printf("Found %d cities in %s, %s\n", len(cities), stateCode, countryCode)
return cities
} else {
fmt.Printf("State not found or no cities available\n")
return nil
}
}
func main() {
cities := getCitiesByState("IN", "MH")
fmt.Println(cities)
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class CitiesByState {
public static void main(String[] args) throws Exception {
String countryCode = "IN";
String stateCode = "MH";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/countries/" + countryCode +
"/states/" + stateCode + "/cities"))
.header("X-CSCAPI-KEY", "YOUR_API_KEY")
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
Gson gson = new Gson();
Type listType = new TypeToken<List<Map<String, Object>>>(){}.getType();
List<Map<String, Object>> cities = gson.fromJson(response.body(), listType);
System.out.println("Found " + cities.size() + " cities in " + stateCode + ", " + countryCode);
} else {
System.out.println("State not found or no cities available");
}
}
}
require 'net/http'
require 'json'
def get_cities_by_state(country_code, state_code)
uri = URI("https://api.countrystatecity.in/v1/countries/#{country_code}/states/#{state_code}/cities")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['X-CSCAPI-KEY'] = 'YOUR_API_KEY'
response = http.request(request)
if response.code == '200'
cities = JSON.parse(response.body)
puts "Found #{cities.length} cities in #{state_code}, #{country_code}"
cities
else
puts 'State not found or no cities available'
[]
end
end
cities = get_cities_by_state('IN', 'MH')
[
{ "id": 133024, "name": "Mumbai" },
{ "id": 132332, "name": "Pune" },
{ "id": 133351, "name": "Nashik" }
]
[
{
"id": 133024,
"name": "Mumbai",
"state_id": 4008,
"state_code": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.07283000",
"longitude": "72.88261000",
"timezone": "Asia/Kolkata",
"population": 12442373,
"type": null,
"level": null,
"parent_id": null,
"native": "मुंबई"
}
]
[
{
"id": 133024,
"name": "Mumbai",
"...": "...all coordinates fields above...",
"translations": "{\"de\":\"Mumbai\",\"fr\":\"Bombay\",\"ja\":\"ムンバイ\",\"cn\":\"孟买\"}",
"wikiDataId": "Q1156"
}
]
{
"error": "No Cities found."
}
{
"error": "Unauthorized. You shouldn't be here."
}
Retrieve all cities within a specific state or province using both the country’s ISO2 code and the state’s ISO2 code. This provides the most targeted city data.
See Pricing for plan details.
Availability: All plans (Community and above). The fields returned vary by tier — see Tier-Based Field Availability below.
Path Parameters
string
required
ISO2 code of the country (e.g., “IN”, “US”)
string
required
ISO2 code of the state/province (e.g., “MH” for Maharashtra, “CA” for California)
Trim and order results: Add
?fields= to limit columns returned, or ?sort= to order the list. Both are available on Supporter+ plans. See the Field Filtering & Sorting guide for syntax and per-entity sortable fields.Authentication
string
required
Your API key for authentication
Query Parameters
string
Search filter on name. Case-insensitive match on
name and native fields. Minimum 2 characters. Requires Supporter+ plan. Without this parameter, all results are returned (no plan restriction for search).Response
integer
Unique identifier for the city
string
Official name of the city
City responses on the Basic tier only return
id and name. Upgrading to Supporter+ unlocks state_id, state_code, country_id, country_code, latitude, longitude, timezone, population, type, level, parent_id, and native. Professional+ adds translations and wikiDataId. See Tier-Based Field Availability below.curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states/MH/cities' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states/MH/cities?q=pune' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_cities_by_state(country_code, state_code):
response = requests.get(
f'https://api.countrystatecity.in/v1/countries/{country_code}/states/{state_code}/cities',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
cities = response.json()
print(f'Found {len(cities)} cities in {state_code}, {country_code}')
return cities
else:
print('State not found or no cities available')
return []
cities = get_cities_by_state('IN', 'MH')
const getCitiesByState = async (countryCode, stateCode) => {
const response = await fetch(
`https://api.countrystatecity.in/v1/countries/${countryCode}/states/${stateCode}/cities`,
{
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
}
);
if (response.ok) {
const cities = await response.json();
console.log(`Found ${cities.length} cities in ${stateCode}, ${countryCode}`);
return cities;
} else {
console.error('State not found or no cities available');
return [];
}
};
getCitiesByState('IN', 'MH');
<?php
function getCitiesByState($countryCode, $stateCode) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.countrystatecity.in/v1/countries/{$countryCode}/states/{$stateCode}/cities",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'X-CSCAPI-KEY: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode == 200) {
$cities = json_decode($response, true);
echo "Found " . count($cities) . " cities in {$stateCode}, {$countryCode}\n";
return $cities;
} else {
echo "State not found or no cities available\n";
return [];
}
}
$cities = getCitiesByState('IN', 'MH');
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func getCitiesByState(countryCode, stateCode string) []map[string]interface{} {
url := fmt.Sprintf("https://api.countrystatecity.in/v1/countries/%s/states/%s/cities",
countryCode, stateCode)
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-CSCAPI-KEY", "YOUR_API_KEY")
res, _ := client.Do(req)
defer res.Body.Close()
if res.StatusCode == 200 {
body, _ := ioutil.ReadAll(res.Body)
var cities []map[string]interface{}
json.Unmarshal(body, &cities)
fmt.Printf("Found %d cities in %s, %s\n", len(cities), stateCode, countryCode)
return cities
} else {
fmt.Printf("State not found or no cities available\n")
return nil
}
}
func main() {
cities := getCitiesByState("IN", "MH")
fmt.Println(cities)
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class CitiesByState {
public static void main(String[] args) throws Exception {
String countryCode = "IN";
String stateCode = "MH";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/countries/" + countryCode +
"/states/" + stateCode + "/cities"))
.header("X-CSCAPI-KEY", "YOUR_API_KEY")
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
Gson gson = new Gson();
Type listType = new TypeToken<List<Map<String, Object>>>(){}.getType();
List<Map<String, Object>> cities = gson.fromJson(response.body(), listType);
System.out.println("Found " + cities.size() + " cities in " + stateCode + ", " + countryCode);
} else {
System.out.println("State not found or no cities available");
}
}
}
require 'net/http'
require 'json'
def get_cities_by_state(country_code, state_code)
uri = URI("https://api.countrystatecity.in/v1/countries/#{country_code}/states/#{state_code}/cities")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['X-CSCAPI-KEY'] = 'YOUR_API_KEY'
response = http.request(request)
if response.code == '200'
cities = JSON.parse(response.body)
puts "Found #{cities.length} cities in #{state_code}, #{country_code}"
cities
else
puts 'State not found or no cities available'
[]
end
end
cities = get_cities_by_state('IN', 'MH')
[
{ "id": 133024, "name": "Mumbai" },
{ "id": 132332, "name": "Pune" },
{ "id": 133351, "name": "Nashik" }
]
[
{
"id": 133024,
"name": "Mumbai",
"state_id": 4008,
"state_code": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.07283000",
"longitude": "72.88261000",
"timezone": "Asia/Kolkata",
"population": 12442373,
"type": null,
"level": null,
"parent_id": null,
"native": "मुंबई"
}
]
[
{
"id": 133024,
"name": "Mumbai",
"...": "...all coordinates fields above...",
"translations": "{\"de\":\"Mumbai\",\"fr\":\"Bombay\",\"ja\":\"ムンバイ\",\"cn\":\"孟买\"}",
"wikiDataId": "Q1156"
}
]
{
"error": "No Cities found."
}
{
"error": "Unauthorized. You shouldn't be here."
}
Common Use Cases
Cascading Location Selector
Cascading Location Selector
Build three-level dropdowns for Country → State → City selection.
class LocationSelector {
constructor() {
this.setupEventListeners();
}
setupEventListeners() {
const countrySelect = document.getElementById('country');
const stateSelect = document.getElementById('state');
const citySelect = document.getElementById('city');
countrySelect.addEventListener('change', async (e) => {
const countryCode = e.target.value;
if (countryCode) {
await this.populateStates(countryCode);
this.clearCities();
}
});
stateSelect.addEventListener('change', async (e) => {
const stateCode = e.target.value;
const countryCode = countrySelect.value;
if (stateCode && countryCode) {
await this.populateCities(countryCode, stateCode);
}
});
}
async populateCities(countryCode, stateCode) {
const cities = await getCitiesByState(countryCode, stateCode);
const citySelect = document.getElementById('city');
citySelect.innerHTML = '<option value="">Select City...</option>';
cities.forEach(city => {
const option = document.createElement('option');
option.value = city.id;
option.textContent = city.name;
citySelect.appendChild(option);
});
}
}
Regional Service Areas
Regional Service Areas
Define service coverage areas by state and city combinations.
const createServiceArea = async (serviceAreas) => {
const coverage = {};
for (const area of serviceAreas) {
const { countryCode, stateCode, serviceName, deliveryTime } = area;
const cities = await getCitiesByState(countryCode, stateCode);
coverage[`${countryCode}-${stateCode}`] = {
serviceName,
deliveryTime,
cities: cities.length,
cityIds: cities.map(city => city.id)
};
}
return coverage;
};
// Usage
const areas = [
{ countryCode: 'IN', stateCode: 'MH', serviceName: 'Express', deliveryTime: '1-2 days' },
{ countryCode: 'US', stateCode: 'CA', serviceName: 'Standard', deliveryTime: '2-3 days' }
];
const serviceMap = await createServiceArea(areas);
This is the most efficient endpoint for building cascading location selectors as it provides the smallest, most relevant dataset.
This endpoint provides the optimal balance between data size and specificity, making it ideal for form controls and location-based filtering.
Tier-Based Field Availability
| Tier | Plans | Fields |
|---|---|---|
| Basic | Community, Starter, Legacy | id, name |
| Coordinates | Supporter | All Basic + state_id, state_code, country_id, country_code, latitude, longitude, timezone, population, type, level, parent_id, native |
| Full | Professional, Business | All Coordinates + translations, wikiDataId |
Was this page helpful?
⌘I