City Autocomplete API
for Address Forms
Suggest cities, states and countries as the user types. Every suggestion arrives with its full hierarchy, matching ignores accents and case, and a whole address field is billed as a single session instead of once per keystroke.
A City Search API Built for Typeaheads
Search 150,000+ cities, 5,000+ states and 200+ countries from one endpoint.
Forgiving matching
avila finds Ávila, munchen finds München and york finds New York.
Hierarchy included
Each suggestion carries city, state and country, plus a ready-to-render description, so there is no second call to fill the form.
Session billing
Send a sessiontoken and the whole field costs 1 token, however many keystrokes it takes.
Browser-ready
/v1/* answers with open CORS, so you can call it straight from your frontend without a proxy.
The Address Form Autocomplete Endpoints
Four endpoints under /v1/places cover the country, state, city and postcode part of a form.
| Endpoint | What it does | Main parameters | Token cost |
|---|---|---|---|
| GET /v1/places/autocomplete | Ranked suggestions for what the user typed | q, country, types, limit, lang, sessiontoken | 1 per session (1 per request without a token) |
| GET /v1/places/details | Full record of the picked suggestion: hierarchy, postcode format, phone code, currencies, timezones | id, type, lang, sessiontoken | 0 when it closes an open session, otherwise 1 |
| GET | POST /v1/places/validate | Confirm the final country, state, city and postcode combination | country, state, city, zipcode | 1 per request |
| GET /v1/places/postal-format | Postcode format, regex and example per country | country (optional) | 1 per request |
q needs at least 2 characters, limit goes from 1 to 20 (default 5) and types accepts country, state and city. Errors use real HTTP status codes with a stable error.code.
Add City Autocomplete in a Few Lines
One request per keystroke, one token per address field.
Request (cURL)
curl "https://api.countrydataapi.com/v1/places/autocomplete?apikey=YOUR_API_KEY&q=mad&country=ES&types=city&limit=5"Details of the pick (cURL)
curl "https://api.countrydataapi.com/v1/places/details?apikey=YOUR_API_KEY&id=66c7a6c9e4bda21f4ab1a0f1&type=city&sessiontoken=SESSION_UUID"Response (abridged)
{
"success": true,
"query": "mad",
"suggestions": [
{
"id": "66c7a6c9e4bda21f4ab1a0f1",
"type": "city",
"name": "Madrid",
"description": "Madrid, Comunidad de Madrid, Spain",
"match": "prefix",
"components": {
"city": { "name": "Madrid" },
"state": { "name": "Comunidad de Madrid" },
"country": { "name": "Spain", "iso2": "ES" }
}
}
],
"count": 1,
"session": {
"token": "6f9e...",
"billed": true,
"ttl_seconds": 180
},
"tokens_used": 1
}Typeahead with fetch
const BASE = 'https://api.countrydataapi.com/v1/places';
const API_KEY = 'YOUR_API_KEY';
let session = crypto.randomUUID();
let timer;
// New session each time the field gains focus
input.addEventListener('focus', () => (session = crypto.randomUUID()));
input.addEventListener('input', () => {
clearTimeout(timer);
timer = setTimeout(async () => {
if (input.value.trim().length < 2) return;
const params = new URLSearchParams({
apikey: API_KEY,
q: input.value,
types: 'city',
limit: '5',
sessiontoken: session,
});
const res = await fetch(`${BASE}/autocomplete?${params}`);
const { suggestions } = await res.json();
render(suggestions); // show s.description
}, 150);
});
// When the user picks one: free, and it closes the session
async function pick(s) {
const params = new URLSearchParams({
apikey: API_KEY, id: s.id, type: s.type, sessiontoken: session,
});
const res = await fetch(`${BASE}/details?${params}`);
const { place } = await res.json();
fillForm(place.components, place.postal);
}Pay Per Session, Not Per Keystroke
A typeahead fires a request on every key, so charging per request would make one address field cost several tokens and tie your bill to how fast people type. With a session token the cost is flat:
- Generate a UUID when the city input gains focus.
- Send it as
sessiontokenon every/autocompletecall. Only the first one is charged. - Send it on the
/detailscall for the suggestion the user picked. That call is free and closes the session. - Generate a new token for the next address field.
A session lasts 3 minutes from its first request. After that, the next request opens and bills a new one. Without a sessiontoken, each request costs 1 token. The session.billed field in the response tells you whether a given call was charged.
A Lighter Alternative to Google Places for the City Field
Many address forms only need the administrative part: country, region, city and postcode. If that is your case, a focused city search API is simpler to integrate and easier to budget. If you need street addresses, businesses or map pins, Google Places covers those and this API does not.
Common use cases
Checkout address forms
Let the shopper type a few letters of their city, then fill the state and country from the selected suggestion and validate the postcode against the country's format.
Sign-up and profile location
Capture a clean, canonical "City, State, Country" instead of free text that you have to clean up later.
Shipping and tax calculators
Resolve the region from the city the user picked, and read the currency and phone prefix from the details response.
Listings and search filters
Let people filter jobs, events or properties by city, with suggestions restricted to one country via the country parameter.
Step-by-step guide: address autocomplete, end to end.
What It Covers, and What It Doesn't
Suggestions come from an administrative dataset of 200+ countries, 5,000+ states, 150,000+ cities and 500,000+ postal codes.
- No street addresses. There is no street-level data, so the API cannot autocomplete a street or house number. Keep a plain text input for that line.
- No points of interest. No businesses, opening hours, photos or reviews.
- No city coordinates.
locationis only filled for countries, so this is not a geocoding API. - Your key is visible in the browser. Calling from the frontend exposes the key in devtools; use a budget you are comfortable with or proxy through your backend.
Frequently Asked Questions
What is a city autocomplete API?
It returns city suggestions for the partial text a user has typed, so a form can offer a dropdown instead of accepting free text. CountryDataAPI also suggests states and countries and includes the full hierarchy in every suggestion.
Can it autocomplete full street addresses?
No. It covers country, state, city and postal code only. There is no street-level or point-of-interest data. If you need street addresses, use a street-level provider for that line and this API for the city, region and postcode fields.
How is autocomplete billed?
With a sessiontoken, all autocomplete requests in a 3-minute session cost 1 token, and the closing /details call is free. Without a token, each request costs 1 token.
Does the search handle accents and partial names?
Yes. Matching is case, accent and punctuation insensitive and matches any word of the name. Results are ranked by exact match, then prefix, then inner word, and the match field tells you which rule fired.
How much does it cost?
Paid plans start at €5/month with 200,000 monthly tokens, and every plan includes the places endpoints. See the pricing page for all plans.
Give your address form a better city field
City, state and country suggestions with session billing, from €5/month. Create an account, grab your key and ship the typeahead today.
Need postal code lookup or validation too? See the zip code API.