This endpoint allows you to find the state that contains a specific city. It is useful for reverse lookups when you know the city name but need to determine its parent state. Note that many cities around the world share the same name, so the API may return multiple results from different countries.
All API requests require authentication using an API key. Include your API key as a query parameter in each request:
?apikey=YOUR_API_KEY
You can obtain an API key by registering at CountryDataAPI.
https://api.countrydataapi.com/v1/states/city
Returns the state that contains that city.
Country: USA, State: Colorado, City: Denver
Country: Spain, State: Comunidad Valenciana, City: Valencia
Keep in mind that there are many cities with the same name
According to the requested fields, there will be 3 types of requests:
BASIC: Returns the fields id, state_name, lang Each state will cost 1 token
NORMAL: Returns the field state_cities [All IDs and names of cities in the state] Each city will cost 1 token
ADVANCED: Returns the field state_zip_codes [All postal codes of the city] Each postal code costs 1 token
| Parameter | Type | Description |
|---|---|---|
| apikey | required, token | Account authentication key |
| city | required, string | Name of the city found in the state |
| limitToken | optional, number | 1000 (default). Maximum number of tokens you want to spend on this request |
| fields | optional, string | id,lang,state_name (default). Expected fields in the response |
| lang | optional, lang | en (default). Expected language of the response |
[
{
"id": "8dd25479-067a-43b0-ac4a-8e7faf2bcafb",
"state_name": "Takhar",
"lang": "en",
"state_cities": [
{
"id": "8dd25476-067a-43b0-ac4b-8e7faf2bcbfb",
"city_name": "City"
}
],
"state_zip_codes": [
"00000",
"00001"
]
}
]
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/states/city';
async function getStateByCity(cityName) {
try {
const params = new URLSearchParams({
apikey: API_KEY,
city: cityName,
lang: 'en',
fields: 'id,state_name,lang'
});
const response = await fetch(`${BASE_URL}?${params}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const states = await response.json();
console.log(`States containing city "${cityName}":`, states);
return states;
} catch (error) {
console.error('Error fetching state by city:', error);
throw error;
}
}
// Usage - Note: Multiple states may be returned if city name exists in different regions
getStateByCity('Denver');
getStateByCity('Valencia');
getStateByCity('Springfield'); // Common city name - will return multiple results
import axios from 'axios';
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/states/city';
async function getStateByCity(cityName) {
try {
const response = await axios.get(BASE_URL, {
params: {
apikey: API_KEY,
city: cityName,
lang: 'en',
fields: 'id,state_name,lang'
}
});
console.log(`States containing city "${cityName}":`, response.data);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('API Error:', error.response?.data || error.message);
}
throw error;
}
}
// Usage
getStateByCity('Miami');
import { useState, useEffect } from 'react';
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/states/city';
function StateByCity({ cityName }) {
const [states, setStates] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const fetchStateByCity = async () => {
if (!cityName) {
setStates([]);
return;
}
try {
setLoading(true);
setError(null);
const params = new URLSearchParams({
apikey: API_KEY,
city: cityName,
lang: 'en',
fields: 'id,state_name,lang'
});
const response = await fetch(`${BASE_URL}?${params}`);
if (!response.ok) {
throw new Error('Failed to fetch state');
}
const data = await response.json();
setStates(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchStateByCity();
}, [cityName]);
if (loading) return <div>Searching for states...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
<h2>States containing "{cityName}"</h2>
{states.length === 0 ? (
<p>No states found for this city</p>
) : (
<>
<p>Found {states.length} state(s)</p>
<ul>
{states.map((state) => (
<li key={state.id}>
{state.state_name}
</li>
))}
</ul>
</>
)}
</div>
);
}
// City search component with input
function CityStateSearch() {
const [cityInput, setCityInput] = useState('');
const [searchCity, setSearchCity] = useState('');
const handleSearch = (e) => {
e.preventDefault();
setSearchCity(cityInput);
};
return (
<div>
<form onSubmit={handleSearch}>
<input
type="text"
value={cityInput}
onChange={(e) => setCityInput(e.target.value)}
placeholder="Enter city name..."
/>
<button type="submit">Search</button>
</form>
{searchCity && <StateByCity cityName={searchCity} />}
</div>
);
}
export default CityStateSearch;
<template>
<div>
<div v-if="loading">Searching for states...</div>
<div v-else-if="error">Error: {{ error }}</div>
<div v-else>
<h2>States containing "{{ city }}"</h2>
<p v-if="states.length === 0">No states found for this city</p>
<div v-else>
<p>Found {{ states.length }} state(s)</p>
<ul>
<li v-for="state in states" :key="state.id">
{{ state.state_name }}
</li>
</ul>
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
const props = defineProps({
city: {
type: String,
required: true
}
});
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.countrydataapi.com/v1/states/city';
const states = ref([]);
const loading = ref(false);
const error = ref(null);
const fetchStateByCity = async () => {
if (!props.city) {
states.value = [];
return;
}
try {
loading.value = true;
error.value = null;
const params = new URLSearchParams({
apikey: API_KEY,
city: props.city,
lang: 'en',
fields: 'id,state_name,lang'
});
const response = await fetch(`${BASE_URL}?${params}`);
if (!response.ok) {
throw new Error('Failed to fetch state');
}
states.value = await response.json();
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
};
watch(() => props.city, fetchStateByCity);
onMounted(fetchStateByCity);
</script>
import { Component, Input, OnInit, OnChanges } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
interface State {
id: string;
state_name: string;
lang: string;
state_cities?: Array<{ id: string; city_name: string }>;
state_zip_codes?: string[];
}
@Component({
selector: 'app-state-by-city',
standalone: true,
imports: [CommonModule, FormsModule],
template: `
<div>
<div *ngIf="loading">Searching for states...</div>
<div *ngIf="error">Error: {{ error }}</div>
<div *ngIf="!loading && !error">
<h2>States containing "{{ city }}"</h2>
<p *ngIf="states.length === 0">No states found for this city</p>
<div *ngIf="states.length > 0">
<p>Found {{ states.length }} state(s)</p>
<ul>
<li *ngFor="let state of states">{{ state.state_name }}</li>
</ul>
</div>
</div>
</div>
`
})
export class StateByCityComponent implements OnInit, OnChanges {
@Input() city!: string;
private readonly API_KEY = 'YOUR_API_KEY';
private readonly BASE_URL = 'https://api.countrydataapi.com/v1/states/city';
states: State[] = [];
loading = false;
error: string | null = null;
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.fetchStateByCity();
}
ngOnChanges(): void {
this.fetchStateByCity();
}
private fetchStateByCity(): void {
if (!this.city) {
this.states = [];
return;
}
this.loading = true;
this.error = null;
const params = new HttpParams()
.set('apikey', this.API_KEY)
.set('city', this.city)
.set('lang', 'en')
.set('fields', 'id,state_name,lang');
this.http.get<State[]>(this.BASE_URL, { params }).subscribe({
next: (data) => {
this.states = data;
this.loading = false;
},
error: (err) => {
this.error = err.message;
this.loading = false;
}
});
}
}
// Search component with input
@Component({
selector: 'app-city-state-search',
standalone: true,
imports: [CommonModule, FormsModule, StateByCityComponent],
template: `
<div>
<form (ngSubmit)="search()">
<input
type="text"
[(ngModel)]="cityInput"
name="city"
placeholder="Enter city name..."
/>
<button type="submit">Search</button>
</form>
<app-state-by-city
*ngIf="searchCity"
[city]="searchCity"
></app-state-by-city>
</div>
`
})
export class CityStateSearchComponent {
cityInput = '';
searchCity = '';
search(): void {
this.searchCity = this.cityInput;
}
}
<?php
$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://api.countrydataapi.com/v1/states/city';
function getStateByCity($cityName, $apiKey) {
$baseUrl = 'https://api.countrydataapi.com/v1/states/city';
$params = http_build_query([
'apikey' => $apiKey,
'city' => $cityName,
'lang' => 'en',
'fields' => 'id,state_name,lang'
]);
$url = $baseUrl . '?' . $params;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("HTTP Error: $httpCode");
}
return json_decode($response, true);
}
// Usage
try {
$cityName = 'Denver';
$states = getStateByCity($cityName, $apiKey);
echo "States containing '$cityName':\n";
echo "Found " . count($states) . " state(s)\n\n";
foreach ($states as $state) {
echo "- " . $state['state_name'] . " (ID: " . $state['id'] . ")\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
// Handle multiple cities with the same name
function findStatesForCity($cityName, $apiKey) {
$states = getStateByCity($cityName, $apiKey);
if (empty($states)) {
return "No states found for city: $cityName";
}
if (count($states) === 1) {
return "City '$cityName' is located in: " . $states[0]['state_name'];
}
$stateNames = array_map(function($s) {
return $s['state_name'];
}, $states);
return "City '$cityName' exists in multiple states: " . implode(', ', $stateNames);
}
echo findStatesForCity('Springfield', $apiKey); // Will show multiple states
?>
import requests
API_KEY = 'YOUR_API_KEY'
BASE_URL = 'https://api.countrydataapi.com/v1/states/city'
def get_state_by_city(city_name):
"""Find the state(s) containing a specific city."""
params = {
'apikey': API_KEY,
'city': city_name,
'lang': 'en',
'fields': 'id,state_name,lang'
}
try:
response = requests.get(BASE_URL, params=params)
response.raise_for_status()
states = response.json()
return states
except requests.exceptions.RequestException as e:
print(f'Error fetching state by city: {e}')
raise
# Usage
if __name__ == '__main__':
city = 'Denver'
states = get_state_by_city(city)
print(f"States containing '{city}':")
print(f"Found {len(states)} state(s)\n")
for state in states:
print(f" - {state['state_name']} (ID: {state['id']})")
# Example with a common city name
print("\n--- Searching for 'Springfield' (common name) ---")
springfield_states = get_state_by_city('Springfield')
print(f"Found {len(springfield_states)} states with city named 'Springfield'")
# Async version with aiohttp
import aiohttp
import asyncio
async def get_state_by_city_async(city_name):
"""Find state by city asynchronously."""
params = {
'apikey': API_KEY,
'city': city_name,
'lang': 'en',
'fields': 'id,state_name,lang'
}
async with aiohttp.ClientSession() as session:
async with session.get(BASE_URL, params=params) as response:
if response.status == 200:
return await response.json()
else:
raise Exception(f'HTTP Error: {response.status}')
# Search for multiple cities concurrently
async def search_multiple_cities(cities):
"""Search states for multiple cities concurrently."""
tasks = [get_state_by_city_async(city) for city in cities]
results = await asyncio.gather(*tasks, return_exceptions=True)
return dict(zip(cities, results))
# Usage
# cities = ['Denver', 'Miami', 'Seattle', 'Austin']
# results = asyncio.run(search_multiple_cities(cities))
# for city, states in results.items():
# print(f"{city}: {[s['state_name'] for s in states]}")
# Search state by city name
curl -X GET "https://api.countrydataapi.com/v1/states/city?apikey=YOUR_API_KEY&city=Denver&lang=en&fields=id,state_name,lang"
# Search for Valencia (exists in multiple countries)
curl -X GET "https://api.countrydataapi.com/v1/states/city?apikey=YOUR_API_KEY&city=Valencia&lang=en"
# With pretty-printed JSON output
curl -X GET "https://api.countrydataapi.com/v1/states/city?apikey=YOUR_API_KEY&city=Miami&lang=en" | json_pp
# Search for a common city name (returns multiple results)
curl -X GET "https://api.countrydataapi.com/v1/states/city?apikey=YOUR_API_KEY&city=Springfield&lang=en"
# Get detailed state info including cities
curl -X GET "https://api.countrydataapi.com/v1/states/city?apikey=YOUR_API_KEY&city=Boston&fields=id,state_name,state_cities"
# Save response to file
curl -X GET "https://api.countrydataapi.com/v1/states/city?apikey=YOUR_API_KEY&city=Seattle&lang=en" -o seattle_state.json
The API may return the following error responses:
| Status Code | Description |
|---|---|
| 400 | Bad Request - Invalid parameters or missing city |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - Insufficient permissions or token balance |
| 404 | Not Found - City not found |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
{
"statusCode": 404,
"message": "City not found",
"error": "Not Found"
}