Several cities can share the same name. A search for Jingzhou, for example, can return locations in Hubei, Anhui, Guangdong, and Hebei. GeoCity supports two ways to handle this:
- Search for
Jingzhouto return all matching locations and let the user choose. - Search for
Jingzhou, HubeiorHubei Jingzhouto return only the match in Hubei.
In both cases, the province is returned as state in the response. Render location options as name, state, country.
What state means
state is the common response field for the first-level administrative area:
| Country | Meaning of state | Example |
|---|---|---|
| China | Province | Hubei |
| India | State | Maharashtra |
| Other countries | State, province, region, or equivalent first-level area | Depends on the country |
For Indian localities, the response may also include district. For Chinese cities, district is commonly null while the province is available in state.
1. Search with an optional state or province
Call GET /api/v2/geo/search. You can put the city first with a comma, or put a recognized state or province first:
curl --get "https://api.freeastroapi.com/api/v2/geo/search" \
-H "x-api-key: $FREE_ASTRO_API_KEY" \
--data-urlencode "q=Jingzhou, Hubei" \
--data-urlencode "limit=10"The supported forms are:
| Query | Behavior |
|---|---|
Jingzhou | Returns matching locations in every province |
Jingzhou, Hubei | Returns only Jingzhou in Hubei |
Hubei Jingzhou | Province-first form; also returns only Jingzhou in Hubei |
Jingzhou, Hubei Province | Accepts the administrative suffix and returns the Hubei match |
Jingzhou City, Hubei Province | Accepts both the city and province suffixes |
Jingzhou, Hubei, CN | Also limits the search to China |
Province-first input works with recognized administrative areas, not only Hubei. For example, Sichuan Chengdu, Guangdong Shenzhen, and Zhejiang Hangzhou use the same logic. The optional English administrative suffixes are also accepted, as in Jingzhou City, Hubei Province and Hubei Province Jingzhou City. GeoCity first tries the complete text as an existing city or locality name; only when that has no result does it remove the optional suffix or reinterpret the leading words as a state or province. This preserves existing multiword searches. You can also keep using the optional two-letter country query parameter, for example country=CN.
The API key must stay on your server. Do not expose it in browser JavaScript or a public environment variable.
2. Read the province from state
The Hubei result contains:
{
"name": "Jingzhou",
"country": "CN",
"state": "Hubei",
"district": null,
"lat": 30.35028,
"lng": 112.19028,
"timezone": "Asia/Shanghai",
"population": 1052282
}Keep the field name exactly as state. Do not look for a separate province field.
3. Build the visible location label
Create the primary label from name, state, and country:
function formatLocation(result) {
return [result.name, result.state, result.country]
.filter(Boolean)
.join(", ");
}For an unqualified Jingzhou search, the user will see:
Jingzhou, Hubei, CN
Jingzhou, Anhui, CN
Jingzhou, Guangdong, CN
Jingzhou, Hebei, CN.filter(Boolean) omits a missing value and prevents extra commas.
4. Render an autocomplete result list
This React example matches the location pattern shown in the GeoCity documentation:
function GeoResults({ results, onSelect }) {
return (
<div className="geo-results">
{results.map((result) => (
<button
key={`${result.lat}-${result.lng}`}
type="button"
onClick={() => onSelect(result)}
className="geo-result"
>
<strong>
{[result.name, result.state, result.country]
.filter(Boolean)
.join(", ")}
</strong>
<span>
{result.lat}, {result.lng} · {result.timezone}
</span>
</button>
))}
</div>
);
}Use coordinates in the React key because cities can share the same name, state, or even country.
5. Show Indian districts when available
Indian results can include both state and district:
{
"name": "Vangaon",
"country": "IN",
"state": "Maharashtra",
"district": "Palghar",
"lat": 19.8814722,
"lng": 72.7624167,
"timezone": "Asia/Kolkata"
}If district-level distinction matters, use a more detailed formatter:
function formatDetailedLocation(result) {
return [
result.name,
result.district,
result.state,
result.country
]
.filter(Boolean)
.join(", ");
}This returns Vangaon, Palghar, Maharashtra, IN.
Existing Indian city and locality behavior is unchanged. Queries such as Mumbai, Vangaon, or Mulund, with or without country=IN, keep the same matching and ordering. A qualified state, such as Mumbai, Maharashtra or Maharashtra Mumbai, narrows those results by state only after GeoCity has checked the complete input as a place name.
6. Save the selected result, not only its name
After the user selects Jingzhou, Hubei, CN, keep the complete result object. Use its lat, lng, and timezone in later astrology requests. Coordinates remove city-name ambiguity, and the timezone provides the location context required by date-sensitive calculations.
If the user already knows the province, send Jingzhou, Hubei or Hubei Jingzhou in q. If not, search for Jingzhou, display the returned state for every option, and let the user choose.
Recommended user flow
- The user enters
Jingzhou, HubeiorHubei Jingzhou. - Your server calls
GET /api/v2/geo/search. - GeoCity recognizes the province qualifier and filters the matches.
- Your UI reads
statefrom the result. - The option is displayed as
name, state, country. - The user selects
Jingzhou, Hubei, CN. - Your application saves and uses the selected
lat,lng, andtimezone.
Try the live GeoCity V2 search below, or open the complete City Search documentation for request parameters and examples.