Autocompletado de Lugares
Busca países, estados y ciudades mientras el usuario teclea
El endpoint /v1/places/autocomplete es el motor del campo de dirección de un checkout, un formulario de registro o una calculadora de envíos. Le envías lo que el usuario lleva escrito y te devuelve sugerencias ordenadas por relevancia, cada una con su jerarquía completa ya resuelta para que puedas pintar Madrid, Comunidad de Madrid, España sin una segunda llamada.
Cubre los niveles país, estado y ciudad. No cubre direcciones a nivel de calle ni puntos de interés como negocios, horarios o reseñas.
Endpoint
GET https://api.countrydataapi.com/v1/places/autocomplete
Parámetros de Consulta
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
apikey |
string | Sí | Tu clave de autenticación API |
q |
string | Sí | Lo que el usuario ha escrito. Mínimo 2 caracteres |
country |
string | No | Restringe los resultados a un país: id interno, ISO-2, ISO-3 o nombre |
types |
string | No | Niveles a buscar separados por comas: country, state, city. Por defecto los tres |
limit |
number | No | Número de sugerencias, 1-20. Por defecto 5 |
lang |
string | No | Idioma de los nombres devueltos. Por defecto en |
sessiontoken |
string | No | Agrupa todas las pulsaciones de un campo en una única sesión facturable |
Cómo funciona la coincidencia
La consulta se normaliza antes de buscar, para que el usuario no tenga que pelearse con el teclado:
- Insensible a mayúsculas y acentos —
avilaencuentraÁvila,munchenencuentraMünchen. - Insensible a la puntuación —
hospitaletencuentraL'Hospitalet de Llobregat. - Coincide cualquier palabra —
yorkencuentraNew York, no solo los nombres que empiezan por York.
Los resultados se ordenan por calidad de la coincidencia (nombre exacto, luego inicio del nombre, luego inicio de una palabra interior), después de nivel administrativo más amplio a más concreto, y por último por longitud del nombre. El campo match de cada sugerencia te dice qué regla se aplicó, lo que resulta útil para resaltar el texto.
Ejemplo de Solicitud
curl "https://api.countrydataapi.com/v1/places/autocomplete?apikey=tu-clave-api&q=mad&country=ES&limit=5&lang=es"
JavaScript
const API_KEY = 'tu-clave-api';
async function search(query, sessionToken) {
const params = new URLSearchParams({
apikey: API_KEY,
q: query,
limit: '5',
lang: 'es',
sessiontoken: sessionToken,
});
const response = await fetch(
`https://api.countrydataapi.com/v1/places/autocomplete?${params}`
);
return response.json();
}
Python
import requests
response = requests.get(
'https://api.countrydataapi.com/v1/places/autocomplete',
params={
'apikey': 'tu-clave-api',
'q': 'mad',
'country': 'ES',
'limit': 5,
'lang': 'es',
},
)
data = response.json()
SDK de TypeScript
import { CountryDataApi, Places } from '@countrydataapi/sdk';
const api = new CountryDataApi({ apiKey: 'tu-clave-api' });
const session = Places.createSession();
const { suggestions } = await api.places.autocomplete({
q: 'mad',
country: 'ES',
lang: 'es',
sessiontoken: session,
});
Formato de Respuesta
{
"success": true,
"query": "mad",
"suggestions": [
{
"id": "66c7a6c9e4bda21f4ab1a0f1",
"type": "city",
"name": "Madrid",
"description": "Madrid, Comunidad de Madrid, España",
"match": "prefix",
"components": {
"city": { "id": "66c7a6c9e4bda21f4ab1a0f1", "name": "Madrid" },
"state": { "id": "66c7a6c9e4bda21f4ab10a22", "name": "Comunidad de Madrid" },
"country": {
"id": "66c7a6c9e4bda21f4ab10ef2",
"name": "España",
"iso2": "ES",
"iso3": "ESP",
"phone_code": "+34",
"flag": "🇪🇸"
}
}
}
],
"count": 1,
"session": { "token": "6f9e...", "billed": true, "ttl_seconds": 180 },
"tokens_used": 1,
"remaining_tokens": 4871
}
Campos de la Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
suggestions[].id |
string | Pásalo a /v1/places/details |
suggestions[].type |
string | country, state o city |
suggestions[].name |
string | Nombre en el idioma solicitado |
suggestions[].description |
string | Listo para pintar: "Madrid, Comunidad de Madrid, España" |
suggestions[].match |
string | exact, prefix o word |
suggestions[].components |
object | Jerarquía resuelta: city, state, country |
session |
object | Presente solo si enviaste un sessiontoken. billed indica si esta llamada se ha cobrado |
Consumo de Tokens: se paga por sesión, no por tecla
Un autocompletado lanza una petición con cada tecla. Cobrar por petición haría que un solo campo de dirección costase 8-10 tokens y convertiría tu factura en una función de lo rápido que teclean tus usuarios.
Envía un sessiontoken —cualquier UUID, generado al enfocar el campo— y la sesión completa cuesta 1 token, sin importar cuántas peticiones hicieran falta:
- Genera un token cuando el input de dirección recibe el foco.
- Envíalo en cada llamada a
/autocomplete. Solo se cobra la primera. - Envíalo en la llamada a
/detailsde la sugerencia que elija el usuario. Esa llamada es gratuita y cierra la sesión. - Genera un token nuevo para el siguiente campo de dirección.
Las sesiones caducan a los 3 minutos. Sin sessiontoken, cada petición cuesta 1 token.
// Una sesión por campo de dirección
let session = crypto.randomUUID();
input.addEventListener('focus', () => { session = crypto.randomUUID(); });
// ...cada tecla reutiliza `session`, así que todo el campo cuesta 1 token
Respuesta de Error
{
"success": false,
"error": {
"code": "INVALID_PARAMETER",
"message": "Parameter \"q\" is required and must be at least 2 characters long.",
"status": 400
},
"message": "Parameter \"q\" is required and must be at least 2 characters long."
}
A diferencia de los endpoints más antiguos, /v1/places/* devuelve un código HTTP real (400, 401, 402, 404) junto a un error.code estable. Consulta la documentación de códigos de error.
Llamadas desde el navegador
/v1/* envía Access-Control-Allow-Origin: *, así que puedes llamar al autocompletado directamente desde tu frontend sin un proxy. Ten en cuenta que entonces la clave API es visible para cualquiera que abra las herramientas de desarrollo: usa una clave con un presupuesto que te resulte cómodo exponer, o pasa por tu propio backend si eso te importa.
Consejos prácticos
- Aplica debounce de unos 150 ms. Menos peticiones, misma sensación.
- Exige 2-3 caracteres antes de lanzar la búsqueda. Las consultas más cortas no son útiles.
- Pasa
countrycuando ya lo conozcas. Menos sugerencias y mejores. - Pasa
types=citysi el campo es específicamente una ciudad. - No caches nada por usuario — pero eres libre de guardar y cachear los datos devueltos todo el tiempo que quieras. No hay ninguna restricción sobre su conservación.
Endpoints Relacionados
- GET /v1/places/details - Ficha completa de una sugerencia
- GET /v1/places/validate - Validar una dirección completa
- GET /v1/places/postal-format - Formato de código postal por país