Total Human DesignDashboard|
Documentation

City Search

GET/api/locationsPro

Search cities by name. Returns matching cities with timezone, coordinates, and population — use this to build city autocomplete in your own frontend or chatbot.

No calculation units consumed

This endpoint only searches the city database — it does not run Swiss Ephemeris or consume a calculation unit from your quota.

Why use this?

All chart endpoints require a valid birthLocation. If you're building your own UI, you need a way to let users pick a real city. This endpoint gives you that — it's the same offline city database the THD frontend uses, with 167,000+ cities across 246 countries.

Typical flow:

  1. User types into a city input field
  2. You call /api/locations?query=<input> on each keystroke (debounced)
  3. Display the returned list as a dropdown
  4. On selection, pass the chosen value as birthLocation in your chart request

Request

Method: GET

ParamTypeRequiredDefaultDescription
querystringYesPartial city name, min 3 characters
limitnumberNo8Max results returned (max 20)
thd-api

Response

Returns a JSON array sorted by population descending (most prominent city wins ties).

Response200

[
{
  "name": "Manila",
  "province": "National Capital Region",
  "country": "Philippines",
  "timezone": "Asia/Manila",
  "coordinates": { "lat": 14.6042, "lng": 120.9822 },
  "population": 1600000,
  "value": "Manila, National Capital Region, Philippines"
},
{
  "name": "Manila",
  "province": "Arkansas",
  "country": "United States",
  "timezone": "America/Chicago",
  "coordinates": { "lat": 35.8801, "lng": -90.167 },
  "population": 3736,
  "value": "Manila, Arkansas, United States"
}
]
FieldDescription
nameCity name
provinceState or province (null if not applicable)
countryFull country name
timezoneIANA timezone identifier
coordinates{ lat, lng } — pass these as latitude/longitude in chart requests to bypass city lookup
populationPopulation used for ranking (higher = ranked first)
valueDisplay string for your UI — safe to use as birthLocation in chart calls

Error — query too short:

{ "success": false, "error": "query param is required and must be at least 3 characters." }

Dataset

  • Source: GeoNames cities1000 (CC-BY 4.0)
  • Coverage: 167,617 cities, population ≥ 1,000, 246 countries
  • US cities: 17,321 — covers towns down to ~1,000 population
  • Search: prefix-first then contains, diacritics-insensitive ("Zurich" matches "Zürich")
  • Tiebreaker: population descending — "London" returns UK (8.9M) before Canada (422K)
  • Comma hint: "London, Canada" filters by province/country

Population floor

Towns with fewer than 1,000 residents are not in the dataset. For very remote birthplaces, collect coordinates directly from the user and pass latitude + longitude to the chart endpoint — this bypasses the city lookup entirely.

Integration example

// Debounced autocomplete let debounce; cityInput.addEventListener('input', (e) => { clearTimeout(debounce); if (e.target.value.length < 3) return; debounce = setTimeout(async () => { const res = await fetch( `/api/locations?query=${encodeURIComponent(e.target.value)}&limit=8`, { headers: { Authorization: `Bearer ${apiKey}` } } ); const cities = await res.json(); // Render dropdown dropdown.innerHTML = cities.map(city => `<option value="${city.value}" data-lat="${city.coordinates.lat}" data-lng="${city.coordinates.lng}"> ${city.value} </option>` ).join(''); }, 250); });