Skip to main content
La API de última milla permite que un integrador (una plataforma logística, un agregador de flotas o una marca con bodegas propias) pida la flota de Justo para llevar paquetes desde sus puntos de retiro hasta la dirección de sus clientes. El flujo tiene tres pasos: registras tus locales de retiro, cotizas cada envío y creas la entrega desde la cotización. Justo ubica la dirección, te asegura una hora de retiro y envía a un repartidor que pueda transportar el paquete. Las entregas se facturan a tu cuenta de integrador, no a las marcas o clientes que atiendes. Las cotizaciones y los envíos están bajo https://api.service.getjusto.com/v3/admin/last-mile; los locales se administran con los endpoints de Locales (/v3/ecommerce/stores). Todos se autentican con el token de tu aplicación en el header Authorization: Bearer <token> (ver Autenticación). La autorización debe tener el permiso admin sobre tu cuenta de integrador.

Conceptos

Local

Los paquetes salen desde los locales de tu cuenta, los mismos locales que usa el resto de Justo. Un local de retiro puede ser una bodega, una tienda o un centro de distribución. Lo creas con Crear un local de retiro: queda habilitado solo para pedir despachos, con una dirección, un teléfono de contacto y la opción acceptsCar. Activa acceptsCar si despachas paquetes que no caben en una moto: permite que Justo envíe un repartidor en auto a ese local. Puedes identificar un local con el ID que le asigna Justo (storeId) o con tu propio identificador (externalId). Ambos sirven en cualquier parámetro storeId de la API.

Cotización

Una cotización calcula el precio y la hora de retiro de un paquete desde uno de tus locales hasta una dirección, y queda guardada con un id. Mientras no venza (expiresAt, 20 minutos por defecto), Justo garantiza el precio y la hora de retiro cotizados: al crear la entrega no se recalcula nada. Si envías varios locales candidatos en storeIds (por ejemplo, los que tienen stock del producto), Justo cotiza desde el más cercano al destino que esté abierto para el retiro. Sin storeId ni storeIds considera todos los locales de tu cuenta que piden despachos. La distancia se mide por calle y no puede superar los 20 km.

Horario de atención de los locales

Justo solo promete retiros cuando el local está abierto. Un local creado con Crear un local de retiro parte abierto siempre; configura su horario semanal, sus días cerrados y sus horarios especiales con Actualizar el horario del local. Si ningún local candidato está abierto para el retiro, la cotización responde storeClosed y el mensaje dice cuándo abre el más cercano: vuelve a cotizar con un pickupAt desde esa hora.

Hora de retiro

Cada cotización trae un pickupAt: la hora de retiro que Justo te asegura. Si al cotizar envías pickupAt, indicas desde cuándo el paquete está listo y el retiro queda desde esa hora; si no lo envías, desde ahora.
Si cotizas sin pickupAt y aceptas varios minutos después, la hora de retiro se corre en la misma medida. La hora definitiva viene en quote.pickupAt de la respuesta al crear la entrega.

Vehículo

Con el peso y las medidas del paquete, Justo envía un repartidor en un vehículo que pueda transportarlo. Si el paquete no cabe en una moto, se despacha en auto: el local debe tener acceptsCar: true (si no, la cotización responde vehicleNotAvailable) y el precio incluye un recargo fijo por auto, que ya viene en la cotización. Un paquete que no cabe en un auto no se puede despachar por esta API (packageTooLarge).

Paquetes de alto valor

Declara siempre el valor real del contenido en package.valueAmount, en la moneda del país del local. Justo usa ese valor para cuidar los envíos de mayor valor.

Flujo de un envío

1

Crea tus locales de retiro

Registra cada punto de retiro una sola vez con Crear un local de retiro. Usa tu propio externalId para no tener que guardar el ID de Justo. Si tu cuenta ya tiene locales con dirección y despachos habilitados, puedes cotizar desde ellos sin crear nada.
2

Cotiza el envío

Cotiza el paquete hasta la dirección del cliente. Guarda el id de la cotización.
3

Crea la entrega desde la cotización

Cuando tu cliente confirma la compra, crea la entrega con el quoteId antes de expiresAt. Justo usa el precio y la hora de retiro cotizados.
La respuesta trae la cotización aceptada en quote (con status: "accepted" y el deliveryId) y la entrega creada en delivery.
4

Entrega el código de entrega a tu cliente

La entrega trae requiresDeliveryVerificationCode: el código que tu cliente debe decirle al repartidor al recibir el paquete. Sin ese código el repartidor no puede cerrar la entrega. Muéstraselo a tu cliente en el seguimiento o envíaselo en un mensaje.

Probar sin repartidores reales

Desde una cuenta de pruebas puedes crear envíos que atiende una flota simulada: recibes los mismos webhooks que con un envío real, sin cobro ni repartidores de verdad. Ver Probar la integración.

Código de entrega

Toda entrega de última milla tiene un código de entrega (requiresDeliveryVerificationCode). Al llegar al destino, el repartidor se lo pide a quien recibe y solo puede cerrar la entrega con el código correcto. Así el paquete se entrega a la persona que tiene el código. El código viene en la respuesta de Crear un envío, en Obtener una entrega y en el webhook deliveries.delivery.updated. No lo compartas con el repartidor ni con el local.

Reintentos e idempotencia

Crear la entrega es idempotente por cotización: si la respuesta no te llegó (timeout, error de red), reintenta con el mismo quoteId y los mismos datos, y recibirás la misma entrega, sin duplicarla. Si reintentas con otro externalId u otro valor de simulation mientras la cotización se está aceptando, responde 409 con bookingMismatch. Si dos solicitudes con el mismo quoteId llegan a la vez, una crea la entrega y la otra responde 409 con quoteBeingAccepted; reintenta en unos segundos o consulta la cotización con Obtener una cotización. Si una creación quedó sin respuesta (timeout o error 500), la cotización puede quedar en proceso hasta 5 minutos: después de eso, reintentar con el mismo quoteId devuelve la entrega si alcanzó a crearse, o la crea si no. Si la cotización venció, la creación responde 409 con quoteExpired. Pide una cotización nueva: el precio o la hora de retiro pueden haber cambiado. Si envías externalId, Justo también lo usa para evitar duplicados. No reutilices el mismo externalId para envíos distintos.

Errores

Los errores responden con success: false y un objeto error con un código estable (error.error) y un mensaje en español (error.message). Los errores de validación y de negocio responden 400; los conflictos de la cotización, 409.
Si tu cuenta usa saldo prepago y no alcanza para la entrega, o la cuenta tiene pagos pendientes, la creación de la entrega falla con un mensaje que explica cómo resolverlo.

Seguimiento de la entrega

La entrega creada es una entrega sin pedido de Justo Delivery, así que se sigue con los mismos endpoints. Usa el delivery._id que recibiste al crearla:
  • Obtener una entrega (GET /admin/deliveries/{deliveryId}): estado, repartidor, última ubicación, link de seguimiento (trackingURL) y fotos de retiro y entrega.
  • Cancelar una entrega (POST /admin/deliveries/{deliveryId}/cancel).
  • Webhook Entrega sin pedido actualizada (deliveries.delivery.updated): Justo te avisa cada vez que la entrega cambia de estado o de repartidor. Las entregas creadas desde una cotización traen lastMileQuoteId, para que las cruces con tus cotizaciones.

Formatos de dirección

Las direcciones (toAddress al cotizar y address del local) siempre llevan countryCode (ISO 3166-1 alfa-2: CL, CO, MX, PE…) y se pueden enviar de tres formas:
  • En una línea (line): calle, número, unidad y comuna en un solo texto. Es la forma más simple si tu sistema guarda la dirección como texto libre.
  • Por campos: streetAddress (calle y número) es obligatorio si no envías line. Agrega locality y region para evitar ambigüedades entre comunas o ciudades con calles del mismo nombre.
  • Con coordenadas (location): si ya las tienes (por ejemplo, de un pin en el mapa), Justo las usa tal cual, sin geocodificar. Es la opción más precisa.
Sin coordenadas, Justo ubica la dirección. La cotización devuelve las coordenadas que usó en toAddress.location. Si la dirección no se puede ubicar con certeza, la cotización responde addressNotFound. El departamento u oficina (extendedAddress) no cambia el precio. Si no lo tenías al cotizar, puedes enviarlo al crear la entrega.

Configuración de tu cuenta

Justo configura para tu cuenta:
  • Vigencia de las cotizaciones: cuánto dura una cotización antes de vencer (20 minutos por defecto).
  • Precio: la tarifa acordada con tu cuenta, por ejemplo por tramos de distancia.
  • Saldo prepago: si tus entregas se descuentan de un saldo prepago que debe alcanzar al crear cada entrega.
Para cambiar alguno de estos valores, contacta a tu ejecutivo de Justo.