curl -X GET 'https://api.countrystatecity.in/v1/states' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/states?q=texas' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/states?include_translations=true' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
response = requests.get(
'https://api.countrystatecity.in/v1/states',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
states = response.json()
print(f'Found {len(states)} states')
const response = await fetch('https://api.countrystatecity.in/v1/states', {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
const states = await response.json();
console.log(`Found ${states.length} states`);
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.countrystatecity.in/v1/states',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'X-CSCAPI-KEY: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
$states = json_decode($response, true);
echo "Found " . count($states) . " states\n";
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.countrystatecity.in/v1/states"
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()
body, _ := ioutil.ReadAll(res.Body)
var states []map[string]interface{}
json.Unmarshal(body, &states)
fmt.Printf("Found %d states\n", len(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 AllStates {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/states"))
.header("X-CSCAPI-KEY", "YOUR_API_KEY")
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
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");
}
}
require 'net/http'
require 'json'
uri = URI("https://api.countrystatecity.in/v1/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)
states = JSON.parse(response.body)
puts "Found #{states.length} states"
[
{
"id": 4008,
"name": "Maharashtra",
"country_id": 101,
"country_code": "IN",
"iso2": "MH",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"country_id": 101,
"country_code": "IN",
"iso2": "MH",
"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,
"translations": "{\"kr\":\"마하라슈트라\",\"de\":\"Maharashtra\",\"fr\":\"Maharashtra\",\"cn\":\"马哈拉施特拉邦\"}",
"wikiDataId": "Q1191"
}
]
{
"error": "Unauthorized. You shouldn't be here."
}
Get All States
Retrieve a complete list of all states, provinces, and regions worldwide
curl -X GET 'https://api.countrystatecity.in/v1/states' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/states?q=texas' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/states?include_translations=true' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
response = requests.get(
'https://api.countrystatecity.in/v1/states',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
states = response.json()
print(f'Found {len(states)} states')
const response = await fetch('https://api.countrystatecity.in/v1/states', {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
const states = await response.json();
console.log(`Found ${states.length} states`);
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.countrystatecity.in/v1/states',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'X-CSCAPI-KEY: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
$states = json_decode($response, true);
echo "Found " . count($states) . " states\n";
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.countrystatecity.in/v1/states"
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()
body, _ := ioutil.ReadAll(res.Body)
var states []map[string]interface{}
json.Unmarshal(body, &states)
fmt.Printf("Found %d states\n", len(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 AllStates {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/states"))
.header("X-CSCAPI-KEY", "YOUR_API_KEY")
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
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");
}
}
require 'net/http'
require 'json'
uri = URI("https://api.countrystatecity.in/v1/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)
states = JSON.parse(response.body)
puts "Found #{states.length} states"
[
{
"id": 4008,
"name": "Maharashtra",
"country_id": 101,
"country_code": "IN",
"iso2": "MH",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"country_id": 101,
"country_code": "IN",
"iso2": "MH",
"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,
"translations": "{\"kr\":\"마하라슈트라\",\"de\":\"Maharashtra\",\"fr\":\"Maharashtra\",\"cn\":\"马哈拉施特拉邦\"}",
"wikiDataId": "Q1191"
}
]
{
"error": "Unauthorized. You shouldn't be here."
}
/states without filtering by country (bulkStates) is gated to Starter+. Community users must call /countries/{iso2}/states instead. The fields returned also vary by tier — see Tier-Based Field Availability below.?fields= to limit columns returned, or ?sort= to order the list. Both are available on Starter+ plans. See the Field Filtering & Sorting guide for syntax and per-entity sortable fields.fips_code, iso3166_2, 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/states' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/states?q=texas' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
curl -X GET 'https://api.countrystatecity.in/v1/states?include_translations=true' \
-H 'X-CSCAPI-KEY: YOUR_API_KEY'
import requests
response = requests.get(
'https://api.countrystatecity.in/v1/states',
headers={'X-CSCAPI-KEY': 'YOUR_API_KEY'}
)
states = response.json()
print(f'Found {len(states)} states')
const response = await fetch('https://api.countrystatecity.in/v1/states', {
headers: { 'X-CSCAPI-KEY': 'YOUR_API_KEY' }
});
const states = await response.json();
console.log(`Found ${states.length} states`);
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.countrystatecity.in/v1/states',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'X-CSCAPI-KEY: YOUR_API_KEY'
),
));
$response = curl_exec($curl);
curl_close($curl);
$states = json_decode($response, true);
echo "Found " . count($states) . " states\n";
?>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.countrystatecity.in/v1/states"
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()
body, _ := ioutil.ReadAll(res.Body)
var states []map[string]interface{}
json.Unmarshal(body, &states)
fmt.Printf("Found %d states\n", len(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 AllStates {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.countrystatecity.in/v1/states"))
.header("X-CSCAPI-KEY", "YOUR_API_KEY")
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
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");
}
}
require 'net/http'
require 'json'
uri = URI("https://api.countrystatecity.in/v1/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)
states = JSON.parse(response.body)
puts "Found #{states.length} states"
[
{
"id": 4008,
"name": "Maharashtra",
"country_id": 101,
"country_code": "IN",
"iso2": "MH",
"latitude": "19.75147980",
"longitude": "75.71388840",
"timezone": "Asia/Kolkata"
}
]
[
{
"id": 4008,
"name": "Maharashtra",
"country_id": 101,
"country_code": "IN",
"iso2": "MH",
"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,
"translations": "{\"kr\":\"마하라슈트라\",\"de\":\"Maharashtra\",\"fr\":\"Maharashtra\",\"cn\":\"马哈拉施特拉邦\"}",
"wikiDataId": "Q1191"
}
]
{
"error": "Unauthorized. You shouldn't be here."
}
Common Use Cases
Global State Analysis
Global State Analysis
const analyzeStateTypes = (states) => {
const typeCount = states.reduce((acc, state) => {
acc[state.type] = (acc[state.type] || 0) + 1;
return acc;
}, {});
console.log('State types distribution:', typeCount);
return typeCount;
};
Geographic Mapping
Geographic Mapping
const getStatesBounds = (states) => {
const lats = states.map(s => parseFloat(s.latitude));
const lngs = states.map(s => parseFloat(s.longitude));
return {
north: Math.max(...lats),
south: Math.min(...lats),
east: Math.max(...lngs),
west: Math.min(...lngs)
};
};
Tier-Based Field Availability
This endpoint requires Starter+ (Legacy plans also include it), so Community accounts never reach field access at all — they get a403 first.
| Tier | Plans | Fields |
|---|---|---|
| Basic | Starter, Legacy | id, name, iso2, country_id, country_code, latitude, longitude, timezone |
| Full | Supporter, Professional, Business | All Basic + fips_code, iso3166_2, type, level, parent_id, native, population, translations, wikiDataId, localized_name, matched_locale |
translations is part of Full access but is not returned by default: add include_translations=true, or name it in ?fields=. localized_name and matched_locale are computed from the translations rather than stored, and appear only when you pass locale. See Localized Place Names.
See Pricing for plan details.Authorizations
API key for authentication. Get your free key at app.countrystatecity.in.
Query Parameters
Search filter. Case-insensitive match on name and native fields. Min 2 characters. Requires Starter+ plan.
2 - 100"maha"
Comma-separated list of fields to include in the response. id is always included. Requires Starter+ plan.
"name,iso2,country_code"
Comma-separated sort tokens: field or field:asc|desc. Requires Starter+ plan.
"name:asc"
BCP 47 locale code (e.g. pt-BR) to request a localized name. Adds localized_name (resolved via exact locale → base language → native name → English name fallback) and matched_locale (which tier matched) to each result; name is unaffected. Supporter+ plans only — silently omitted (not an error) on lower tiers. A malformed value is rejected with a 400 on every tier.
2 - 7^[a-zA-Z]{2}(-[a-zA-Z]{2,4})?$"pt-BR"
When true, includes the full translations field (JSON string keyed by language code). Supporter+ plans only — silently omitted (not an error) on lower tiers. Note that an explicit fields=translations also returns the field and takes precedence over this flag.
true
Response
List of all states globally
Unique identifier
4008
State name in English
"Maharashtra"
Parent country ID
Parent country ISO2 code
"IN"
State/province ISO code
"MH"
Latitude coordinate
"19.75147980"
Longitude coordinate
"75.71388840"
IANA timezone identifier
"Asia/Kolkata"
FIPS code. Coordinates tier and above.
ISO 3166-2 subdivision code. Coordinates tier and above.
Administrative type (e.g., state, province, territory). Coordinates tier and above.
"state"
Administrative level. Coordinates tier and above.
Parent subdivision ID (for nested administrative structures). Coordinates tier and above.
Name in native language. Coordinates tier and above.
Population count. Coordinates tier and above.
JSON string keyed by language code. Supporter+ plans only. Returned when include_translations=true or when fields=translations explicitly requests it.
Wikidata item identifier. Full access level only.
"Q1191"
Name resolved via the locale query param's fallback chain (exact locale → base language → native name → English name). Only present when locale was supplied. Supporter+ plans only — silently omitted on lower tiers.
"Maharashtra"
Which fallback tier satisfied the locale request: the exact locale (e.g. pt-BR), its base language (e.g. pt), native, or en (English fallback). Only present when locale was supplied. Supporter+ plans only — silently omitted on lower tiers.
"en"