Desarrolladores
API de InkaMaps
Datos geográficos del Perú por HTTP: Places (lugares y servicios), Geocoding (de dirección a punto y al revés, con la cartografía de InkaMaps), Autocompletado de direcciones, el Mapa base para tu mapa y consultas espaciales a tus propias capas (Builder).
Inicio rápido
- Pide acceso a InkaMaps. Damos de alta a tu empresa, habilitamos las APIs que necesitas y vinculamos a tu equipo.
- Entra a la consola y crea una key de servidor en API keys (la puedes volver a ver cuando quieras con «Mostrar»). Empieza a funcionar en aproximadamente un minuto (antes responde 403).
- Haz tu primera consulta: los lugares a 2 km de una coordenada, del más cercano al más lejano.
curl "https://api.inkamaps.com/v1/places/search?lat=-12.065&lon=-75.21&radiusKm=2" \
-H "x-api-key: ik_sk_TU_KEY"Todas las respuestas son JSON con la misma forma: success, data (o error) y metadata con la fecha y un requestId para soporte.
Autenticación y API keys
Cada consulta lleva la key en el header x-api-key (también se acepta ?key= en la URL, como en Geodir; el header es lo recomendado: la URL queda en historiales). Hay dos tipos:
| Tipo | Prefijo | Úsala en | Restricción |
|---|---|---|---|
| Servidor | ik_sk_… | Tu backend (Node, PHP, Python…) | Ninguna, pero es secreta: guárdala en una variable de entorno |
| Navegador | ik_pk_… | Código que corre en el navegador | Solo responde a los dominios que registres (ej. https://*.tuempresa.pe) |
Nunca pongas una key de servidor en el código del navegador ni en una app móvil: cualquiera podría copiarla. Si necesitas consultar desde el navegador, usa una key de navegador con tus dominios, o llama a tu propio backend y que él consulte a InkaMaps.
Desde la consola puedes pausar una key (deja de responder y la reactivas cuando quieras) o revocarla (definitivo). Si una key se filtra: crea una nueva, cámbiala en tu sistema y revoca la anterior. Cada cuenta tiene hasta 5 keys en uso.
Places · Buscar
GET/v1/places/search
Busca lugares publicados. Combina texto, ciudad, tipo y uno de los dos filtros geográficos.
| Parámetro | Ejemplo | Descripción |
|---|---|---|
| lat, lon | -12.065, -75.21 | Punto de referencia. Los resultados vienen ordenados por distancia. |
| radiusKm | 2 | Radio alrededor del punto (por defecto 5). |
| bbox | -75.23,-12.08,-75.19,-12.05 | Zona visible del mapa: oeste,sur,este,norte. No se combina con lat/lon. |
| q | mirador | Texto libre (nombre, tipo, descripción). Tolera errores de tipeo. |
| city | huancayo | Ciudad (clave en minúsculas, sin tildes). |
| type | parque,mirador | Uno o más tipos de lugar, separados por coma. |
| size | 20 | Cantidad de resultados (máximo 100). |
Orden: por distancia si mandas lat/lon; por relevancia si mandas q; si no, destacados primero.
{
"success": true,
"data": {
"results": [
{
"id": "plc_7f3a9c1e2b",
"name": "Parque de los Mates Burilados",
"poiType": "parque",
"placeKind": "tourist",
"city": "huancayo",
"location": { "lat": -12.0651, "lon": -75.2049 },
"cover": "https://…/photos/original/plc_7f3a9c1e2b/med_1.webp",
"photoCount": 6,
"hasVideo": false,
"videoPoster": null,
"contact": { "phone": null, "whatsapp": null, "website": null },
"featured": true,
"distanceMeters": 412.7
}
],
"total": 1
},
"metadata": { "timestamp": "2026-10-01T15:00:00.000Z", "requestId": "…" }
}distanceMeters solo viene cuando buscas por lat/lon.
Places · Autocompletar
GET/v1/places/autocomplete
Sugerencias mientras el usuario escribe un nombre de lugar (mínimo 2 caracteres, hasta 8 resultados).
| Parámetro | Ejemplo | Descripción |
|---|---|---|
| q | mira | Texto escrito hasta ahora (obligatorio, 2 caracteres o más). |
| city | huancayo | Opcional: solo lugares de esa ciudad. |
{ "success": true, "data": { "results": [
{ "id": "plc_7f3a9c1e2b", "name": "Mirador Cerro de la Libertad", "poiType": "mirador", "city": "huancayo" }
] } }Places · Detalle
GET/v1/places/{id}
Ficha completa de un lugar publicado, por su id (plc_…) o su slug. Incluye fotos y video con sus URLs, horarios, contacto, consejos y la dirección desglosada.
{ "success": true, "data": { "place": {
"id": "plc_7f3a9c1e2b", "slug": "parque-de-los-mates-burilados-1201",
"name": "Parque de los Mates Burilados", "poiType": "parque", "placeKind": "tourist",
"description": "…", "geo": { "lat": -12.0651, "lng": -75.2049 },
"address": "Jr. Arroyos 250", "ubigeo": "120114", "cityCode": "huancayo",
"addressDetail": {
"viaType": "jiron", "viaName": "Arroyos", "number": "250", "block": null, "lot": null,
"sublocality": "Millotingo", "reference": "Frente al puente Carrión",
"adminLevel1": "Junín", "adminLevel1Code": "12",
"adminLevel2": "Huancayo", "adminLevel2Code": "1201",
"adminLevel3": "El Tambo", "adminLevel3Code": "120114",
"postalCode": null, "adminLevel3Source": "geocode"
},
"coverPhoto": "https://…", "photos": [ … ], "videos": [ … ],
"hours": { "lunes": { "closed": false, "open": "08:00", "close": "18:00" } },
"contact": { "phone": null, "whatsapp": null, "website": null, "instagram": null },
"tips": ["Ir al atardecer"], "publishedAt": "2026-10-01T15:00:00.000Z"
} } }addressDetail puede ser null en lugares cargados antes de que existiera el desglose. Los códigos son los UBIGEO del INEI: departamento (2 dígitos) ⊂ provincia (4) ⊂ distrito (6).
Places · Categorías de fotos
GET/v1/places/photo-categories
Catálogo de categorías de fotos por tipo de lugar (vista, acceso, interior…). Con ?poiType=museo devuelve solo las de ese tipo. Útil para armar galerías ordenadas.
Geocoding · Dirección → punto
GET/v1/geocode?address=…
Convierte una dirección del Perú en una coordenada. Entiende direcciones mal escritas, desordenadas o incompletas: tipos de vía abreviados ("jr", "av"), errores de tipeo ("ruis gayo" = Ruiz Gallo), N°, S/N, manzana y lote (Mz A Lt 5), cuadras (cdra 24), urbanizaciones y A.H., y el distrito al final o abreviado (VES, SJL).
| Parámetro | Ejemplo | Para qué |
|---|---|---|
address | JR PEDRO RUIZ GALLO 668 | La dirección como la escribió la persona (obligatorio). |
segments | locality_id:150105 | Cierra la búsqueda a un distrito (6 dígitos), provincia (4) o departamento (2). |
curl "https://api.inkamaps.com/v1/geocode?address=JR%20PEDRO%20RUIZ%20GALLO%20668&segments=locality_id:150105" \
-H "x-api-key: ik_sk_TU_KEY"Responde en el mismo formato que Geodir (si ya lo usas, cambias la dirección y la key): status y results[], el más seguro primero. Cada resultado trae address_segments (vía, número, manzana, lote, urbanización, distrito con su ubigeo…), geometry, place_id y standard_address, más dos campos nuevos: confidence (0–1) y match (qué partes de la dirección se encontraron).
{
"status": "OK",
"results": [{
"result_types": ["address"],
"standard_address": "Jirón Pedro Ruiz Gallo 668, Breña, Lima, Perú",
"geometry": { "coordinates": { "lat": -12.065826, "lon": -77.054652 }, "geocoding_type": "INTERPOLATED", "bbox": [...] },
"address_segments": [{ "name": "668", "name_abbr": "668", "types": ["route_number"] }, ...],
"place_id": "…",
"confidence": 0.85,
"match": { "matched": ["route_type", "route", "route_number", "admin_level_3"], "unmatched": [] }
}]
}| geocoding_type | Qué significa |
|---|---|
| DOOR | La puerta o el lote existen en la cartografía. |
| INTERPOLATED | Número calculado sobre la cuadra, del lado par o impar. |
| CENTER | Centro de la vía, la cuadra, la manzana o la urbanización (sin número). |
| APROXIMATE | Solo el distrito: no se encontró nada más preciso. |
Usa confidence para decidir: ≥ 0,8 úsalo directo; entre 0,5 y 0,8 muéstralo para que la persona confirme; menos de 0,5, pide más datos (el distrito, el número).
Geocoding · Punto → dirección
GET/v1/geocode?latlon=lat,lon
La dirección de un punto (el GPS del usuario, un pin en el mapa). El primer resultado es el más preciso y los siguientes son los otros niveles del mismo lugar; cada uno trae distance_m.
| Orden | Qué devuelve | Hasta |
|---|---|---|
| 1 | La puerta más cercana (DOOR) | 30 m |
| 2 | El lote, con su manzana, urbanización y la vía de al lado | 25 m (o el lote de esa manzana, CENTER) |
| 3 | El número calculado del lado del punto (INTERPOLATED) | 60 m de la vía |
| 4 | La vía más cercana | 100 m |
| 5 | La manzana y la urbanización que contienen al punto | — |
| 6 | El distrito (siempre que el punto esté en el Perú) | — |
curl "https://api.inkamaps.com/v1/geocode?latlon=-12.206878,-76.942540" -H "x-api-key: ik_sk_TU_KEY"
# → "Calle C, Mz. L Lt. 8, P.J. Sector 2 Grupo 13, Villa El Salvador, Lima, Perú" (a 0 m)Autocompletado y detalle
GET/v1/autocomplete?input=…
GET/v1/geocode/place?place_id=…
Para un buscador de direcciones: mientras la persona escribe, sugiere vías, urbanizaciones y distritos, y la dirección completa en cuanto escribe el número, la cuadra o la manzana y el lote. Al elegir una sugerencia, el detalle da su punto y sus segmentos. Las sugerencias son de la API Autocompletado y el detalle (/v1/geocode/place) es de Geocoding: habilita las dos en tu key.
| Parámetro | Ejemplo | Para qué |
|---|---|---|
input | jr pedro r | Lo que se lleva escrito (mín. 2 caracteres). También vale search=, como en Geodir. |
segments | locality_id:150105 | Solo dentro de ese distrito, provincia o departamento. |
location | -12.12,-77.03 | Lo cercano a ese punto primero (la ubicación del usuario, el centro de tu mapa). |
size | 5 | Cuántas sugerencias (1–10). |
{
"status": "OK",
"predictions": [{
"types": ["route"],
"main_text": "Jirón Pedro Ruiz Gallo",
"secondary_text": "Breña, Lima, Lima",
"description": "Jirón Pedro Ruiz Gallo, Breña, Lima, Perú",
"place_id": "…",
"matched_substrings": [{ "offset": 6, "length": 5 }]
}]
}matched_substrings marca en main_text lo que coincide (para ponerlo en negrita). El detalle responde con el resultado en el primer nivel, como Geodir: { "status": "OK", "result_types", "address_segments", "geometry", "place_id", "standard_address" }. Espera ~300 ms desde la última tecla antes de llamar.
Geocoding · Capas y domicilio (búsqueda estructurada)
Para formularios paso a paso, como «Buscar domicilio» de Geodir Maps: Distrito → Vía → Número, o Distrito → Urbanización → Manzana → Lote. Cada campo sugiere dentro de lo ya elegido (con su place_id) y, con todo elegido, pides el domicilio.
GET/v1/geocode/layers/{adminlevel3 | routes | sublocalities | blocks | lots}?input=…
| Capa | Sugiere | Parámetros |
|---|---|---|
| adminlevel3 | Distritos | input |
| routes | Vías | input, locality_id; con sublocality_id, primero las de ese núcleo |
| sublocalities | Urbanizaciones, AA.HH., P.J.… | input, locality_id; con route_id, primero por las que pasa esa vía |
| blocks | Manzanas del núcleo, en orden (C1, C2… C10) | sublocality_id (o locality_id + input) |
| lots | Lotes de la manzana, en orden | block_id (o sublocality_id + block) |
Responde { "status", "items": [...] }, cada ítem con el mismo molde que un resultado. Con un núcleo, vía o manzana elegidos, input puede ir vacío (la lista completa).
curl "https://api.inkamaps.com/v1/geocode/layers/routes?input=pedro&locality_id=150105" -H "x-api-key: ik_sk_TU_KEY"GET/v1/geocode/structured?locality_id=…&route_id=…&street_number=…&sublocality_id=…&block=…&lot=…
El domicilio armado con lo elegido: vía + número → la puerta (o el número calculado sobre su cuadra); núcleo + manzana + lote → el lote; núcleo + manzana → la manzana. La manzana y el lote van como letra/número (block=L, lot=8) o como block_id / lot_id. Lo elegido tiene que estar en el locality_id. Mismo formato que la georreferenciación.
curl "https://api.inkamaps.com/v1/geocode/structured?locality_id=150142&sublocality_id=<place_id>&block=L&lot=8" -H "x-api-key: ik_sk_TU_KEY"
# Como Geodir: lo mismo en segments, sin address
curl "https://api.inkamaps.com/v1/geocode?segments=locality_id:150105|route_id:<place_id>|street_number:668" -H "x-api-key: ik_sk_TU_KEY"Los place_id pueden traer +, / o =: codifícalos en la URL.
Mapa base
Mapa vectorial del Perú (límites, vías con nombre y cuadras, urbanizaciones, manzanas, lotes y numeración) para MapLibre GL JS, en varios estilos. Usa una key de navegador con la API Mapa base y tus dominios. Cuenta una carga cada vez que se abre el mapa (no cada tesela).
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@5/dist/maplibre-gl.css" />
<script src="https://unpkg.com/maplibre-gl@5/dist/maplibre-gl.js"></script>
<div id="mapa" style="height: 500px"></div>
<script>
new maplibregl.Map({
container: "mapa",
style: "https://mapas.inkamaps.com/v1/estilos/inkamaps.json?key=ik_pk_TU_KEY",
center: [-77.0365, -12.1219], // [longitud, latitud]
zoom: 15,
});
</script>Para cambiar de estilo cambia inkamaps por otro nombre: estandar, claro, calles, andino, pergamino, oscuro o medianoche. Los ves con su vista previa en la sección Mapa base de tu consola, o en https://mapas.inkamaps.com/v1/temas.json. Las teselas llevan un token que vence en 24 h: la key no viaja en cada tesela.
Builder · Consultas a tus capas
Las capas que tu equipo crea en Construye tu mapa (dibujadas, subidas como Shapefile, KML, GeoPackage, CSV… o resultado de un análisis) se consultan por API: ¿en qué zona de reparto cae esta dirección?, ¿qué tienda está más cerca?, ¿qué clientes hay a 500 m? Necesitas una key con la API Builder, y la capa tiene que ser de un usuario de tu empresa. El id de la capa está en su pestaña Consultar.
GET/v1/builder/capas/{id}/{contiene | cercanos | radio}?lat=…&lon=… (o address=…)
| Operación | Para | Parámetros |
|---|---|---|
| contiene | En qué polígono cae el punto (capas de polígonos) | lat, lon o address |
| cercanos | Los k elementos más cercanos, con su distancia en metros | k (1–50, por defecto 5), max_m (hasta 50.000; por defecto 2.000) |
| radio | Todo lo que está a r metros o menos | r (hasta 50.000) |
| intersecta (POST) | Lo que cruza una geometría (una ruta, un polígono) | { "geometry": GeoJSON } |
curl "https://api.inkamaps.com/v1/builder/capas/3fa9c2d1e0b4/contiene?address=Av.%20Larco%20345%20Miraflores" -H "x-api-key: ik_sk_TU_KEY"
{ "status": "OK",
"location": { "lat": -12.1219, "lon": -77.0297 },
"results": [ { "feature_id": "a1b2", "properties": { "zona": "Z4", "repartidor": "Lima Sur" }, "distance_m": 0 } ] }Cada resultado trae feature_id, properties (los campos del elemento), distance_m (en línea recta) y, en líneas y polígonos, punto: el punto del elemento más cercano al consultado. Con geometria=true también trae la geometría. Sin resultados: "status": "ZERO_RESULTS".
En lote: hasta 1.000 puntos en un POST a la misma ruta, una respuesta por punto en el mismo orden.
curl -X POST "https://api.inkamaps.com/v1/builder/capas/3fa9c2d1e0b4/contiene" -H "x-api-key: ik_sk_TU_KEY" -H "Content-Type: application/json" -d '{ "puntos": [ { "id": "pedido-1", "lat": -12.10, "lon": -77.04 }, { "id": "pedido-2", "address": "Jr. Ucayali 120, Lima" } ] }'GET/v1/builder/servicios/{id}?lat=…&lon=… (o address=…)
Un servicio guardado es una consulta con nombre (operación, parámetros, un filtro y los campos a devolver) que se arma desde el mapa y queda con esta URL fija. Acepta también lote por POST.
Errores
Los errores tienen la forma:
{ "success": false, "error": { "code": "FORBIDDEN", "message": "Dominio no permitido para esta key" } }| HTTP | code | Qué pasó |
|---|---|---|
| 400 | VALIDATION_ERROR | Un parámetro es inválido (el mensaje dice cuál). |
| 401 | UNAUTHORIZED | Falta el header x-api-key, o la key no existe. |
| 403 | FORBIDDEN | Key pausada o revocada, cuenta suspendida, API no habilitada en tu key o dominio no permitido. El mensaje dice el motivo. |
| 404 | NOT_FOUND | El lugar no existe o no está publicado. |
| 429 | RATE_LIMITED | Superaste las consultas por segundo. Reintenta en un momento. |
| 429 | QUOTA_EXCEEDED | Superaste la cuota diaria de tu key. Se renueva al día siguiente (UTC). |
| 500 | INTERNAL_ERROR | Error nuestro. Si se repite, escríbenos con el requestId. |
Geocoding y Autocompletado responden sus propios errores en formato Geodir: { "status": "INVALID_REQUEST", "error_message": "…" } (400), NOT_FOUND (404, un place_id que no existe) y ZERO_RESULTS (200, sin resultados). Los de la key (401, 403, 429) son los de la tabla.
Límites de uso
Cada key tiene un límite de consultas por segundo y por día, según lo acordado con InkaMaps. En la sección Uso de tu consola ves el consumo de cada API (Places, Geocoding, Autocompletado y las cargas del Mapa base) día por día, de los últimos 7, 30 o 90 días, y cuánto lleva cada key hoy frente a su límite. Si te quedas corto, escríbenos y lo ampliamos.
Consejos: guarda en caché los detalles de lugares (cambian poco), espera a que el usuario deje de escribir ~300 ms antes de llamar al autocompletado, y reintenta los 429 con espera creciente (1 s, 2 s, 4 s…).
Ejemplos por lenguaje
Node.js / Next.js (servidor)
// .env → INKAMAPS_API_KEY=ik_sk_… (nunca NEXT_PUBLIC_)
const res = await fetch(
"https://api.inkamaps.com/v1/places/search?lat=-12.065&lon=-75.21&radiusKm=2",
{ headers: { "x-api-key": process.env.INKAMAPS_API_KEY! } },
);
const body = await res.json();
if (!body.success) throw new Error(body.error.message);
const lugares = body.data.results;Python
import os, requests
r = requests.get(
"https://api.inkamaps.com/v1/places/search",
params={"q": "mirador", "city": "huancayo"},
headers={"x-api-key": os.environ["INKAMAPS_API_KEY"]},
timeout=10,
)
r.raise_for_status()
lugares = r.json()["data"]["results"]PHP
$ch = curl_init("https://api.inkamaps.com/v1/places/autocomplete?q=" . urlencode("mira"));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: " . getenv("INKAMAPS_API_KEY")]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);Navegador (key ik_pk_ con tu dominio registrado)
const res = await fetch("https://api.inkamaps.com/v1/places/search?bbox=-75.23,-12.08,-75.19,-12.05", {
headers: { "x-api-key": "ik_pk_…" }, // pública: solo responde desde tus dominios
});Probar con tu key
En la consola, Probar las APIs: eliges una de tus keys, escribes una dirección (o tocas el mapa) y ves la respuesta tal cual, cuánto tardó y el punto en el mapa base (en el estilo que elijas), con el curl listo para copiar. En Mapa base ves todos los estilos, los pruebas en vivo y copias el código para tu web.