curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states?q=maha' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_states_by_country(country_code):
response = requests.get(
f'https://api.countrystatecity.in/v1/countries/{country_code}/states',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
states = response.json()
print(f'Found {len(states)} states in {country_code}')
return states
else:
print('Country not found or no states available')
return []
states = get_states_by_country('IN')
const getStatesByCountry = async (countryCode) => {
const response = await fetch(`https://api.countrystatecity.in/v1/countries/${countryCode}/states`, {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
if (response.ok) {
const states = await response.json();
console.log(`Found ${states.length} states in ${countryCode}`);
return states;
} else {
console.error('Country not found or no states available');
}
};
getStatesByCountry('IN');
<?php
function getStatesByCountry($countryCode) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.countrystatecity.in/v1/countries/{$countryCode}/states",
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) {
$states = json_decode($response, true);
echo "Found " . count($states) . " states in {$countryCode}\n";
return $states;
} else {
echo "Country not found or no states available\n";
return [];
}
}
$states = getStatesByCountry('IN');
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func getStatesByCountry(countryCode string) []map[string]interface{} {
url := fmt.Sprintf("https://api.countrystatecity.in/v1/countries/%s/states", countryCode)
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 states []map[string]interface{}
json.Unmarshal(body, &states)
fmt.Printf("Found %d states in %s\n", len(states), countryCode)
return states
} else {
fmt.Printf("Country not found or no states available\n")
return nil
}
}
func main() {
states := getStatesByCountry("IN")
fmt.Println(states)
}
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 StatesByCountry {
public static void main(String[] args) throws Exception {
String countryCode = "IN";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/countries/" + countryCode + "/states"))
.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>> states = gson.fromJson(response.body(), listType);
System.out.println("Found " + states.size() + " states in " + countryCode);
} else {
System.out.println("Country not found or no states available");
}
}
}
require 'net/http'
require 'json'
def get_states_by_country(country_code)
uri = URI("https://api.countrystatecity.in/v1/countries/#{country_code}/states")
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'
states = JSON.parse(response.body)
puts "Found #{states.length} states in #{country_code}"
states
else
puts 'Country not found or no states available'
[]
end
end
states = get_states_by_country('IN')
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata",
"fips_code": "16",
"iso3166_2": "IN-MH",
"type": "state",
"level": 1,
"parent_id": null,
"native": "महाराष्ट्र",
"population": 112374333
}
]
{
"error": "No States/Regions found."
}
{
"error": "Unauthorized. You shouldn't be here."
}
States Endpoints
Get States by Country
Retrieve all states/provinces for a specific country
GET
/
v1
/
countries
/
{iso2}
/
states
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states?q=maha' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_states_by_country(country_code):
response = requests.get(
f'https://api.countrystatecity.in/v1/countries/{country_code}/states',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
states = response.json()
print(f'Found {len(states)} states in {country_code}')
return states
else:
print('Country not found or no states available')
return []
states = get_states_by_country('IN')
const getStatesByCountry = async (countryCode) => {
const response = await fetch(`https://api.countrystatecity.in/v1/countries/${countryCode}/states`, {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
if (response.ok) {
const states = await response.json();
console.log(`Found ${states.length} states in ${countryCode}`);
return states;
} else {
console.error('Country not found or no states available');
}
};
getStatesByCountry('IN');
<?php
function getStatesByCountry($countryCode) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.countrystatecity.in/v1/countries/{$countryCode}/states",
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) {
$states = json_decode($response, true);
echo "Found " . count($states) . " states in {$countryCode}\n";
return $states;
} else {
echo "Country not found or no states available\n";
return [];
}
}
$states = getStatesByCountry('IN');
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func getStatesByCountry(countryCode string) []map[string]interface{} {
url := fmt.Sprintf("https://api.countrystatecity.in/v1/countries/%s/states", countryCode)
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 states []map[string]interface{}
json.Unmarshal(body, &states)
fmt.Printf("Found %d states in %s\n", len(states), countryCode)
return states
} else {
fmt.Printf("Country not found or no states available\n")
return nil
}
}
func main() {
states := getStatesByCountry("IN")
fmt.Println(states)
}
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 StatesByCountry {
public static void main(String[] args) throws Exception {
String countryCode = "IN";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/countries/" + countryCode + "/states"))
.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>> states = gson.fromJson(response.body(), listType);
System.out.println("Found " + states.size() + " states in " + countryCode);
} else {
System.out.println("Country not found or no states available");
}
}
}
require 'net/http'
require 'json'
def get_states_by_country(country_code)
uri = URI("https://api.countrystatecity.in/v1/countries/#{country_code}/states")
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'
states = JSON.parse(response.body)
puts "Found #{states.length} states in #{country_code}"
states
else
puts 'Country not found or no states available'
[]
end
end
states = get_states_by_country('IN')
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata",
"fips_code": "16",
"iso3166_2": "IN-MH",
"type": "state",
"level": 1,
"parent_id": null,
"native": "महाराष्ट्र",
"population": 112374333
}
]
{
"error": "No States/Regions found."
}
{
"error": "Unauthorized. You shouldn't be here."
}
Retrieve all states, provinces, regions, and territories for a specific country using the country’s ISO2 code.
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” for India, “US” for United States)
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 state/province
string
Official name of the state/province
string
ISO2 code for the state/province
integer
Unique identifier of the parent country
string
ISO2 code of the parent country
string
Approximate latitude of the state/province
string
Approximate longitude of the state/province
string
IANA timezone identifier (e.g.,
"Asia/Kolkata")Additional fields like
fips_code, iso3166_2, type, level, parent_id, native, population, translations, and wikiDataId are returned on higher tiers. See Tier-Based Field Availability below.curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/countries/IN/states?q=maha' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
def get_states_by_country(country_code):
response = requests.get(
f'https://api.countrystatecity.in/v1/countries/{country_code}/states',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
if response.ok:
states = response.json()
print(f'Found {len(states)} states in {country_code}')
return states
else:
print('Country not found or no states available')
return []
states = get_states_by_country('IN')
const getStatesByCountry = async (countryCode) => {
const response = await fetch(`https://api.countrystatecity.in/v1/countries/${countryCode}/states`, {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
if (response.ok) {
const states = await response.json();
console.log(`Found ${states.length} states in ${countryCode}`);
return states;
} else {
console.error('Country not found or no states available');
}
};
getStatesByCountry('IN');
<?php
function getStatesByCountry($countryCode) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.countrystatecity.in/v1/countries/{$countryCode}/states",
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) {
$states = json_decode($response, true);
echo "Found " . count($states) . " states in {$countryCode}\n";
return $states;
} else {
echo "Country not found or no states available\n";
return [];
}
}
$states = getStatesByCountry('IN');
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func getStatesByCountry(countryCode string) []map[string]interface{} {
url := fmt.Sprintf("https://api.countrystatecity.in/v1/countries/%s/states", countryCode)
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 states []map[string]interface{}
json.Unmarshal(body, &states)
fmt.Printf("Found %d states in %s\n", len(states), countryCode)
return states
} else {
fmt.Printf("Country not found or no states available\n")
return nil
}
}
func main() {
states := getStatesByCountry("IN")
fmt.Println(states)
}
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 StatesByCountry {
public static void main(String[] args) throws Exception {
String countryCode = "IN";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/countries/" + countryCode + "/states"))
.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>> states = gson.fromJson(response.body(), listType);
System.out.println("Found " + states.size() + " states in " + countryCode);
} else {
System.out.println("Country not found or no states available");
}
}
}
require 'net/http'
require 'json'
def get_states_by_country(country_code)
uri = URI("https://api.countrystatecity.in/v1/countries/#{country_code}/states")
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'
states = JSON.parse(response.body)
puts "Found #{states.length} states in #{country_code}"
states
else
puts 'Country not found or no states available'
[]
end
end
states = get_states_by_country('IN')
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"iso2": "MH",
"country_id": 101,
"country_code": "IN",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata",
"fips_code": "16",
"iso3166_2": "IN-MH",
"type": "state",
"level": 1,
"parent_id": null,
"native": "महाराष्ट्र",
"population": 112374333
}
]
{
"error": "No States/Regions found."
}
{
"error": "Unauthorized. You shouldn't be here."
}
Common Use Cases
Cascading Address Forms
Cascading Address Forms
Create dependent dropdowns where states populate based on country selection.
const populateStatesDropdown = async (countryCode) => {
const states = await getStatesByCountry(countryCode);
const select = document.getElementById('state-select');
// Clear existing options
select.innerHTML = '<option value="">Select State...</option>';
states.forEach(state => {
const option = document.createElement('option');
option.value = state.iso2;
option.textContent = state.name;
select.appendChild(option);
});
};
// Listen for country changes
document.getElementById('country-select').addEventListener('change', (e) => {
populateStatesDropdown(e.target.value);
});
Regional Validation
Regional Validation
Validate state codes against specific countries.
const validateStateForCountry = async (countryCode, stateCode) => {
const states = await getStatesByCountry(countryCode);
return states.some(state => state.iso2 === stateCode);
};
Cache states by country as they rarely change. Use this endpoint instead of filtering all states for better performance.
Tier-Based Field Availability
| Tier | Plans | Fields |
|---|---|---|
| Basic | Community, Starter, Legacy | id, name, iso2, country_id, country_code, latitude, longitude, timezone |
| Coordinates | Supporter | All Basic + fips_code, iso3166_2, type, level, parent_id, native, population |
| Full | Professional, Business | All Coordinates + translations, wikiDataId |
Was this page helpful?
⌘I