🚌

API de direcciones y coordenadas

Buslandia · para cuentas de tipo desarrollador

Dos cosas hace esta API:

  1. Le mandás una dirección y un municipio, y te devuelve las coordenadas.
  2. Le mandás unas coordenadas, y te devuelve la dirección, el municipio, el departamento y el país.

Todo va por https://net.newhorizontstart.com y responde en JSON.

1. Conseguir el token

Las dos consultas piden un token. Se pide una vez con tu usuario y tu contraseña de Buslandia, dura 24 horas y sirve para todas las consultas de ese rato.

POST/api/geo/login
# Pedir el token
curl -X POST https://net.newhorizontstart.com/api/geo/login \
  -H "Content-Type: application/json" \
  -d '{"usuario":"tu_usuario","clave":"tu_contraseña"}'

# Respuesta
{
  "token": "blt_9f2c…",
  "tipo_token": "Bearer",
  "vence_en_seg": 86400,
  "usuario": { "id": "12", "nombre_usuario": "tu_usuario", "tipo": "desarrollador" }
}

En usuario podés mandar tu nombre de usuario o tu correo, los dos sirven.

Solo las cuentas de tipo desarrollador reciben token. Si tu cuenta es de usuario o de conductor, la respuesta es 403 con {"error":"Usuario no autorizado"}. Podés cambiar el tipo creando una cuenta nueva y eligiendo Desarrollador.

El token se manda en todas las demás consultas en la cabecera:

Authorization: Bearer blt_9f2c…

2. Dirección → coordenadas

GET/api/geo/coordenadas
POST/api/geo/coordenadas

Los datos podés mandarlos como parámetros en la dirección web (GET) o en el cuerpo (POST). Es igual, elegí lo que te sirva.

CampoQué es
direccionobligatorio La vía. Ejemplo: Carrera 49 #42-15
municipioobligatorio Ejemplo: Itagüí
departamentoopcional Ayuda cuando hay municipios con el mismo nombre en dos departamentos
paisopcional Por omisión Colombia
limiteopcional Cuántas alternativas devolver además de la mejor. Por omisión 3
# Ejemplo
curl -X POST https://net.newhorizontstart.com/api/geo/coordenadas \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer blt_9f2c…" \
  -d '{"direccion":"Carrera 43A","municipio":"Medellín"}'

# Respuesta
{
  "encontrado": true,
  "lat": 6.20861,
  "lon": -75.57093,
  "direccion": "Carrera 43A",
  "municipio": "Medellín",
  "departamento": "Antioquia",
  "pais": "Colombia",
  "codigo_pais": "CO",
  "barrio": "El Poblado",
  "codigo_postal": null,
  "exactitud": "calle",
  "completo": "Carrera 43A, El Poblado, Medellín, Antioquia, Colombia",
  "otras": [ /* otros resultados, mismo formato */ ]
}

Si no la encuentra

Responde 200 igual, con encontrado: false y un aviso de qué probar. No es un error: que una dirección no esté en el mapa es un resultado válido, no una falla.

{
  "encontrado": false,
  "consulta": { "direccion": "…", "municipio": "…" },
  "aviso": "No encontré esa dirección. Probá sin el número, o escribiendo…"
}

3. Coordenadas → dirección

GET/api/geo/direccion
POST/api/geo/direccion
CampoQué es
latobligatorioLatitud, entre -90 y 90
lonobligatorioLongitud, entre -180 y 180
# Ejemplo
curl "https://net.newhorizontstart.com/api/geo/direccion?lat=6.16901&lon=-75.61604" \
  -H "Authorization: Bearer blt_9f2c…"

# Respuesta
{
  "encontrado": true,
  "consulta": { "lat": 6.16901, "lon": -75.61604 },
  "lat": 6.16915,
  "lon": -75.61598,
  "direccion": "Calle 39 #52-10",
  "barrio": "Santa María",
  "municipio": "Itagüí",
  "departamento": "Antioquia",
  "pais": "Colombia",
  "codigo_pais": "CO",
  "exactitud": "casa",
  "completo": "Calle 39 #52-10, Santa María, Itagüí, Antioquia, Colombia"
}

consulta repite lo que preguntaste, y lat y lon son las del portal más cercano que encontró. Suelen ser parecidas pero no idénticas.

El campo exactitud

Este campo importa más de lo que parece, y conviene mirarlo siempre. Dice qué tan fino es el resultado, y la diferencia entre un valor y otro puede ser de kilómetros:

ValorQué significa
casaEl número exacto. Es lo más preciso.
calleLa vía sí, el número no. Puede caer en cualquier punto de esa cuadra.
barrioSolo el barrio.
municipioEl centro del municipio. Puede estar a varios kilómetros.
aproximadaNi eso.

Mirando solo las coordenadas es imposible distinguir casa de municipio: las dos son dos números. Por eso el campo está.

Errores

CódigoQué pasó
400Faltan datos o son inválidos. El mensaje dice cuál.
401Usuario o contraseña mal, o token faltante, vencido o inválido.
403Usuario no autorizado: la cuenta no es de tipo desarrollador.
429Te pasaste del tope de consultas por minuto.

Todos responden un JSON con un campo error en español.

Límites, y por qué existen

60 consultas por minuto por cuenta.

No es un capricho. Por debajo esto consulta Nominatim, el buscador de direcciones de OpenStreetMap, que es gratuito y permite una consulta por segundo. Si alguien se pasa, bloquean la IP del servidor entero — y con eso se caería también el buscador de direcciones de la app de Buslandia, que usa el mismo servicio.

Las respuestas se guardan una semana, así que repetir la misma consulta no gasta cuota y contesta al instante. Si vas a consultar las mismas direcciones seguido, no te preocupes por eso.

Si necesitás un volumen grande y sostenido, esto no te va a alcanzar: ahí toca montar un Nominatim propio o pagar un servicio de geocodificación. Te lo decimos de frente para que no te enteres cuando ya sea un problema.

Cerrar la sesión antes de tiempo

POST/api/geo/logout

Anula el token sin esperar las 24 horas. Útil si se te filtró.

curl -X POST https://net.newhorizontstart.com/api/geo/logout \
  -H "Authorization: Bearer blt_9f2c…"

Un ejemplo completo en JavaScript

const BASE = 'https://net.newhorizontstart.com';

// 1. El token, una vez cada 24 horas
const { token } = await (await fetch(BASE + '/api/geo/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ usuario: 'tu_usuario', clave: 'tu_contraseña' }),
})).json();

const auth = { Authorization: `Bearer ${token}` };

// 2. Dirección -> coordenadas
const punto = await (await fetch(BASE + '/api/geo/coordenadas', {
  method: 'POST',
  headers: { ...auth, 'Content-Type': 'application/json' },
  body: JSON.stringify({ direccion: 'Carrera 43A', municipio: 'Medellín' }),
})).json();

if (punto.encontrado) console.log(punto.lat, punto.lon, punto.exactitud);

// 3. Coordenadas -> dirección
const lugar = await (await fetch(
  `${BASE}/api/geo/direccion?lat=6.16901&lon=-75.61604`, { headers: auth })).json();

console.log(lugar.direccion, lugar.municipio, lugar.departamento, lugar.pais);

De dónde salen los datos

De OpenStreetMap, hecho por voluntarios de todo el mundo. Los datos son © colaboradores de OpenStreetMap y están bajo licencia ODbL. En Colombia la cobertura es muy buena en las ciudades y más floja en zonas rurales: ahí es normal que exactitud baje a municipio.

← Volver a Buslandia