Saltar al contenido principal

Geocoding

Resuelve direcciones a coordenadas (forward), coordenadas a direcciones (reverse), sugiere nombres de calle (autocomplete) y consultá tu saldo restante (quota).

Dos formas de geocodificar

Esta API resuelve direcciones con dos motores complementarios, y vos elegís cuál usar:

  • Nominatim (texto libre / reverse)forward con texto libre q y reverse (coordenada → dirección) trabajan sobre datos de OpenStreetMap. Ideal para cobertura mundial y entrada de texto libre.
  • Interno, con nuestros propios mapas (modos estructurados)internal resuelve solo contra la base de calles propia de LogicSat, con modos estructurados explícitos: calle + esquina, calle + número y ruta + km. Ideal cuando ya tenés la dirección separada en campos y querés la coincidencia más precisa en los países cubiertos (Uruguay, Argentina y más).

forward con campos estructurados (street / number / corner) también prueba el motor interno primero como parte de su cadena de proveedores. Usá el endpoint dedicado internal cuando quieras forzar un modo estructurado específico contra nuestros mapas y saltear por completo los proveedores externos.

Servicio de pago — es el único endpoint que se cobra por uso

El servicio de geocoding tiene costo adicional por uso. Cada búsqueda exitosa de forward o reverse descuenta un crédito de tu cupo de geocodificación contratado con LogicSat. No está incluido en el uso libre del resto de la API.

  • Descuenta crédito: las búsquedas forward y reverse que devuelven al menos un resultado (1 crédito por resultado que resuelve).
  • Gratis: autocomplete, la consulta de saldo quota, las búsquedas que no devuelven resultados y las búsquedas repetidas servidas desde la caché corta.
  • Consultá tu saldo cuando quieras con GET /apidev/v1/geocoding/quota — nunca descuenta un crédito.
  • El cupo se contrata con LogicSat. Cuando se agota, las búsquedas que cobran devuelven HTTP 402 hasta que el saldo se renueva o se amplía.
Requisitos previos

Todos los endpoints requieren un token JWT válido, una clave de API y el encabezado tenant. Consultá Autenticación. Cada endpoint de geocoding requiere el permiso APICLI_GEOCODE.

Cómo funciona el cobro

Cada respuesta que cobra incluye un bloque quota dentro de meta para que siempre sepas cómo quedó tu saldo después de la llamada:

CampoTipoDescripción
contractednumberCréditos totales del período activo.
usednumberCréditos ya consumidos en el período activo.
remainingnumberCréditos restantes (contractedused).
period_startstring | nullInicio de la ventana de facturación activa. null significa sin inicio fijo.
period_endstring | nullFin de la ventana de facturación activa. null significa sin vencimiento.
chargednumberCréditos que descontó esta llamada (0 en aciertos de caché y resultados vacíos).
Planificá con quota

Antes de correr un lote grande, llamá a GET /apidev/v1/geocoding/quota para ver tu saldo remaining. Si un lote se queda sin saldo a mitad de camino, resuelve tantos ítems como el saldo permita y devuelve un error por ítem para el resto — ver Forward Geocoding (lote).


Forward Geocoding

Convierte una dirección en una coordenada. Enviá una dirección estructurada (país / departamento / calle / número / esquina, o ruta + km) o texto libre. Devuelve candidatos rankeados con precisión, confianza y componentes de dirección normalizados.

POST/apidev/v1/geocoding/forward
PermisoAPICLI_GEOCODE
Límite de solicitudes30 solicitudes/min (ventana deslizante)
Costo1 crédito por resultado (gratis en acierto de caché / sin resultados)

Cuerpo de la solicitud

Enviá un objeto de consulta único, o un lote con { "items": [ ... ] } (1–25 consultas). Ver Modo lote.

CampoTipoRequeridoDescripción
modestringNoauto (por defecto), street_number, intersection, route_km o freetext. auto infiere la estrategia según los campos que envíes.
countrystringCondicionalPaís (ID o nombre). Acota la búsqueda. Requerido salvo en freetext y route_km.
departmentstringCondicionalDepartamento / provincia (ID o nombre). Desambigua calles homónimas. Requerido salvo en freetext.
citystringNoCiudad / localidad (ID o nombre). Sesga la búsqueda.
streetstringCondicionalNombre de calle. Acepta una línea completa como "Av. Brasil 2950 esq. Ellauri"; el motor la separa.
numberstringNoNúmero de puerta. Activa el modo street_number.
cornerstringNoEsquina. Activa el modo intersection.
routestringCondicionalNúmero de ruta. Combinado con km, activa el modo route_km.
kmnumberCondicionalKilómetro / mojón.
qstringCondicionalTexto libre. Activa el modo freetext.
providersstring[]NoSubconjunto de internal, nominatim, google, mapbox, bing. Se intersecta con los proveedores habilitados para tu compañía; se conserva el orden.
limitnumberNoMáximo de candidatos a devolver. Mín 1, Máx 25, por defecto 10.
langstringNoIdioma de los resultados (es, en, …).
bias_bboxnumber[4]NoCaja [minLng, minLat, maxLng, maxLat] para sesgar la búsqueda hacia un área.

Campos de la respuesta

data.results es un arreglo de candidatos. Cada candidato tiene:

CampoTipoDescripción
latstringLatitud (decimal como string).
lngstringLongitud (decimal como string).
precisionstringCalidad del resultado: explicit, rooftop, range, intersection, route-km, street, approx o centroid.
confidencenumber | nullConfianza del proveedor, de 0 a 1.
sourcestringProveedor que lo resolvió: internal, nominatim, google, mapbox o bing.
addressobjectComponentes normalizados: street, number, corner, neighborhood, city, department, country, postcode.
formattedstringDirección legible en una sola línea.
bboxnumber[4]Caja contenedora [minLng, minLat, maxLng, maxLat]. Presente cuando está disponible.
normalizedobjectPresente solo cuando se corrigió la calle: { street, resolved_from } (la calle usada vs. el texto que enviaste).

El bloque meta incluye providers_tried (string[]), resolved_by (string | null), cached (boolean) y el bloque quota descrito en Cómo funciona el cobro.

Ejemplo de código

curl -s -X POST "https://$TENANT/apidev/v1/geocoding/forward" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"country": "Uruguay",
"department": "Montevideo",
"street": "Av. Brasil",
"number": "2950"
}'

Respuesta de ejemplo

{
"success": true,
"data": {
"results": [
{
"lat": "-34.90568300",
"lng": "-56.18820200",
"precision": "range",
"confidence": 0.82,
"source": "internal",
"address": {
"street": "Avenida Brasil",
"number": "2950",
"corner": "Ellauri",
"neighborhood": "Pocitos",
"city": "Montevideo",
"department": "Montevideo",
"country": "Uruguay",
"postcode": "11300"
},
"formatted": "Avenida Brasil 2950 esq. Ellauri, Pocitos, Montevideo",
"bbox": [-56.190, -34.907, -56.186, -34.904],
"normalized": {
"street": "Avenida Brasil",
"resolved_from": "Av. Brasil"
}
}
]
},
"meta": {
"providers_tried": ["internal"],
"resolved_by": "internal",
"cached": false,
"quota": {
"contracted": 5000,
"used": 1242,
"remaining": 3758,
"period_start": "2026-01-01T00:00:00",
"period_end": "2026-12-31T23:59:59",
"active": true,
"charged": 1
}
}
}
Sin resultados nunca cuesta un crédito

Una búsqueda válida que no encuentra nada devuelve 200 con "results": [] y "charged": 0. Solo se cobra cuando una búsqueda realmente resuelve una ubicación.

Modo lote

Enviá hasta 25 consultas a la vez con { "items": [ ... ] }. La forma de la respuesta cambia: data.items es un arreglo de { index, success, results?, error? }, y meta.quota.charged reporta el total de créditos consumidos en el lote.

Si el saldo se agota a mitad de camino, los ítems resueltos hasta ese punto se cobran y se devuelven; cada ítem restante vuelve con success: false y un error GEOCODING_QUOTA_EXCEEDED. La solicitud igual devuelve 200.

{
"success": true,
"data": {
"items": [
{
"index": 0,
"success": true,
"results": [
{
"lat": "-34.90568300",
"lng": "-56.18820200",
"precision": "range",
"confidence": 0.82,
"source": "internal",
"address": { "street": "Avenida Brasil", "number": "2950", "city": "Montevideo", "department": "Montevideo", "country": "Uruguay" },
"formatted": "Avenida Brasil 2950, Montevideo"
}
]
},
{
"index": 1,
"success": false,
"error": {
"code": "GEOCODING_QUOTA_EXCEEDED",
"message": "Geocoding quota exceeded"
}
}
]
},
"meta": {
"cached": false,
"quota": {
"contracted": 5000,
"used": 5000,
"remaining": 0,
"period_start": "2026-01-01T00:00:00",
"period_end": "2026-12-31T23:59:59",
"active": true,
"charged": 1
}
}
}

Reverse Geocoding

Convierte una coordenada en una dirección. Mismo cobro que forward — 1 crédito por resultado, gratis en acierto de caché o resultado vacío.

POST/apidev/v1/geocoding/reverse
PermisoAPICLI_GEOCODE
Límite de solicitudes30 solicitudes/min (ventana deslizante)
Costo1 crédito por resultado (gratis en acierto de caché / sin resultados)

Cuerpo de la solicitud

Enviá un objeto de consulta único, o un lote con { "items": [ ... ] } (1–25 consultas, con las mismas reglas de cobro parcial que forward).

CampoTipoRequeridoDescripción
latstringLatitud (decimal como string).
lngstringLongitud (decimal como string).
langstringNoIdioma de los resultados (es, en, …).
zoomnumberNoNivel de detalle. Mín 3, Máx 18.

Campos de la respuesta

La misma forma de candidato que Forward Geocoding. meta.providers_tried es ["nominatim"], y meta.quota lleva el saldo después del cobro.

Ejemplo de código

curl -s -X POST "https://$TENANT/apidev/v1/geocoding/reverse" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"lat": "-34.90568300",
"lng": "-56.18820200"
}'

Respuesta de ejemplo

{
"success": true,
"data": {
"results": [
{
"lat": "-34.90568300",
"lng": "-56.18820200",
"precision": "rooftop",
"confidence": 0.45,
"source": "nominatim",
"address": {
"street": "Avenida Brasil",
"number": "2950",
"neighborhood": "Pocitos",
"city": "Montevideo",
"department": "Montevideo",
"country": "Uruguay",
"postcode": "11300"
},
"formatted": "Avenida Brasil 2950, Pocitos, Montevideo, Uruguay",
"bbox": [-56.189, -34.906, -56.187, -34.905]
}
]
},
"meta": {
"providers_tried": ["nominatim"],
"resolved_by": "nominatim",
"cached": false,
"quota": {
"contracted": 5000,
"used": 1243,
"remaining": 3757,
"period_start": "2026-01-01T00:00:00",
"period_end": "2026-12-31T23:59:59",
"active": true,
"charged": 1
}
}
}

Geocoding interno (nuestros mapas)

Resuelve una dirección solo contra la base de calles propia de LogicSat — sin Nominatim, sin proveedores externos. Vos elegís un mode estructurado explícito, así no hay ambigüedad: cada modo mapea directo a una búsqueda contra nuestros mapas.

Usalo cuando ya tenés la dirección separada en campos y querés la coincidencia más precisa en los países cubiertos, o cuando querés evitar específicamente los proveedores externos.

modeResuelveCampos requeridosCobertura
street_cornerCalle y su esquina (intersección)country, street, cornerUruguay, Argentina, Ecuador, Chile, Paraguay, Colombia
street_numberCalle y número de puertacountry, street, numberUruguay y Argentina (los países con rangos de numeración)
routeRuta y mojón / kilómetroroute, kmUruguay
POST/apidev/v1/geocoding/internal
PermisoAPICLI_GEOCODE
Límite de solicitudes30 solicitudes/min (ventana deslizante)
Costo1 crédito por resultado (gratis en acierto de caché / sin resultados)
Mismo cobro que forward / reverse

El geocoding interno se cobra igual que forward y reverse: 1 crédito por resultado que resuelve, gratis en aciertos de caché y resultados vacíos. Solo autocomplete y quota son siempre gratis.

Cuerpo de la solicitud

CampoTipoRequeridoDescripción
modestringstreet_corner, street_number o route. Selecciona la búsqueda estructurada.
countrystringCondicionalPaís (ID o nombre). Requerido para street_corner y street_number. Ignorado en route (solo Uruguay).
departmentstringNoDepartamento / provincia (ID o nombre). Desambigua calles homónimas.
streetstringCondicionalNombre de calle. Requerido para street_corner y street_number.
cornerstringCondicionalEsquina. Requerido para street_corner.
numberstringCondicionalNúmero de puerta. Requerido para street_number.
routestringCondicionalNúmero de ruta. Requerido para route.
kmstringCondicionalKilómetro / mojón. Requerido para route.

Campos de la respuesta

La misma forma de candidato que Forward Geocoding. Cada resultado tiene source: "internal" y meta.providers_tried es ["internal"]. precision es intersection para street_corner, range para street_number (el motor devuelve el centroide del tramo del rango, no la puerta interpolada) y route-km para route. meta.quota lleva el saldo después del cobro.

Ejemplo de código

curl -s -X POST "https://$TENANT/apidev/v1/geocoding/internal" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"mode": "street_corner",
"country": "Uruguay",
"department": "Montevideo",
"street": "Av. Brasil",
"corner": "Ellauri"
}'

Respuesta de ejemplo

{
"success": true,
"data": {
"results": [
{
"lat": "-34.90568300",
"lng": "-56.18820200",
"precision": "intersection",
"confidence": null,
"source": "internal",
"address": {
"street": "Avenida Brasil",
"corner": "Ellauri",
"neighborhood": "Pocitos",
"city": "Montevideo",
"department": "Montevideo",
"country": "Uruguay"
},
"formatted": "Avenida Brasil esq. Ellauri"
}
]
},
"meta": {
"providers_tried": ["internal"],
"resolved_by": "internal",
"cached": false,
"quota": {
"contracted": 5000,
"used": 1244,
"remaining": 3756,
"period_start": "2026-01-01T00:00:00",
"period_end": "2026-12-31T23:59:59",
"active": true,
"charged": 1
}
}
}

Autocomplete

Sugerencias de typeahead para un nombre de calle. Gratis — no devuelve coordenadas y nunca consume un crédito.

POST/apidev/v1/geocoding/autocomplete
PermisoAPICLI_GEOCODE
Límite de solicitudes30 solicitudes/min (ventana deslizante)
CostoGratis

Cuerpo de la solicitud

CampoTipoRequeridoDescripción
countrystringPaís (ID o nombre).
departmentstringNoDepartamento / provincia (ID o nombre). Acota las sugerencias.
streetstringFragmento de calle a buscar. Mínimo 2 caracteres.
limitnumberNoMáximo de sugerencias. Mín 1, Máx 20, por defecto 10.

Campos de la respuesta

data.suggestions es un arreglo de { street, neighborhood?, city?, department? }. meta.cached indica si el resultado vino de la caché corta.

Ejemplo de código

curl -s -X POST "https://$TENANT/apidev/v1/geocoding/autocomplete" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"country": "Uruguay",
"department": "Montevideo",
"street": "bras"
}'

Respuesta de ejemplo

{
"success": true,
"data": {
"suggestions": [
{
"street": "Avenida Brasil",
"neighborhood": "Pocitos",
"department": "Montevideo"
},
{
"street": "Brasilia",
"neighborhood": "Carrasco",
"department": "Montevideo"
}
]
},
"meta": {
"cached": false
}
}

Quota

Consultá el saldo de geocoding de tu compañía — contratado, usado, restante y el período activo. Gratis, y nunca toca tu cupo.

GET/apidev/v1/geocoding/quota
PermisoAPICLI_GEOCODE
Límite de solicitudes30 solicitudes/min (ventana deslizante)
CostoGratis

Campos de la respuesta

CampoTipoDescripción
contractednumberCréditos totales del período activo.
usednumberCréditos consumidos en el período activo.
remainingnumberCréditos restantes.
period_startstring | nullInicio de la ventana de facturación activa.
period_endstring | nullFin de la ventana de facturación activa.
activebooleantrue cuando hay una ventana contratada vigente. false (con remaining: 0) cuando el geocoding no está contratado o la ventana venció.

Ejemplo de código

curl -s "https://$TENANT/apidev/v1/geocoding/quota" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"

Respuesta de ejemplo

{
"success": true,
"data": {
"contracted": 5000,
"used": 1243,
"remaining": 3757,
"period_start": "2026-01-01T00:00:00",
"period_end": "2026-12-31T23:59:59",
"active": true
},
"meta": {}
}
Marcas de tiempo

Las fechas del período se devuelven sin zona horaria (p. ej., "2026-01-01T00:00:00"). El valor representa la zona horaria configurada de la compañía. No agregues Z ni apliques conversión a UTC; mostralo tal cual.


Errores

Todos los endpoints de esta página pueden devolver estos errores. Consultá Manejo de errores para la referencia completa.

CódigoHTTPAplica aDescripción
VALIDATION_ERROR400TodosCampos del cuerpo inválidos (campo desconocido, tipo incorrecto, campo requerido ausente, lote de más de 25 ítems). Detalle en details[].
UNAUTHORIZED401Todostenant / Authorization / X-API-Key ausente, inválido o expirado.
FORBIDDEN403TodosLa clave de API no tiene el permiso APICLI_GEOCODE.
GEOCODING_NOT_CONTRACTED402Forward, Reverse, InternoEl geocoding no está contratado para tu compañía, o la ventana de facturación venció. Contratá el servicio de geocodificación con LogicSat o renová la ventana.
GEOCODING_QUOTA_EXCEEDED402Forward, Reverse, InternoSe agotó el saldo de geocodificación del período. Esperá la renovación o ampliá tu cupo contratado con LogicSat.
RATE_LIMITED429TodosSe superaron 30 solicitudes/min. Es un límite por tiempo, distinto del cupo por uso.
INTERNAL_ERROR500TodosError inesperado del servidor. Reintentá; si persiste, contactá a soporte.
Pago requerido (402)

Los dos códigos 402 llevan el saldo actual directamente en error.details para que tu integración sepa exactamente por qué se rechazó la llamada. El cupo se contrata con LogicSat — recargalo o renová la ventana para seguir usando geocoding.

{
"success": false,
"error": {
"code": "GEOCODING_QUOTA_EXCEEDED",
"message": "Geocoding quota exceeded",
"details": {
"contracted": 5000,
"used": 5000,
"remaining": 0,
"period_start": "2026-01-01T00:00:00",
"period_end": "2026-12-31T23:59:59",
"active": true
}
}
}