NAV Navbar
logo SimpliRoute

Introducción

API Endpoint:

URL: https://api.simpliroute.com/v1/
URL: https://api.simpliroute.com/v1/
URL: https://api.simpliroute.com/v1/

El API de SimpliRoute es un conjunto de endpoints de tipo REST. Por lo mismo, nuestra API tiene un comportamiento predecible, orientado a recursos via URL, y usa códigos de respuesta HTTP para indicar las respuestas del sistema y errores. Utilizamos características propias de HTTP, como HTTP authentication y verbos HTTP que son entendidos de manera nativa por cualquier cliente HTTP moderno. Soportamos cross-origin resources, lo que permite interactura de manera segura con nuestra API desde tus aplicaciones web tanto como back-end como desde front-end. Igualmente, recomedamos que nunca expongas tu API Key en el código público de tu app en el lado del cliente. Todas las respuestas de nuestra API son de tipo JSON, incluyendo los errores que puedan existir.

El principal objetivo de esta documentación es permitir a desarrolladores utilizar nuestra API gracias a diferentes casos de uso y ejemplos de llamadas al API en nuestra documentación. Los 2 grandes casos de uso de nuestra API son:

  • Tú (o tu compañía) son usuarios de la plataforma web de SimpliRoute y desean enviar o recuperar datos de nuestro sistema. If ese es tu caso de uso, estarás muy interesado en los endpoint de visitas

  • Si eres un desarrollador y estas interesado en mejorar tu logística y agregar optimización de rutas, el mejor lugar para empezar a usar nuestra API es en la sección de API de Optimización donde encontrarás la información necesaria para partir con diversos casos de uso.

Si tienes comentarios, encuentras errores o información desactualizada, siéntete libre de escribirnos a [email protected].

Autentificación

Endpoint básico para ejemplificar como se hace la llamada usando el token de autentificación.

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://api.simpliroute.com/v1/accounts/me/",
  "method": "GET",
  "headers": {
    "content-type": "application/json",
    "authorization": "Token 12345678900987sr"
  }
}
$.ajax(settings).done(function (response) {
  console.log(response);
});
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://api.simpliroute.com/v1/accounts/me/")
  .get()
  .addHeader("content-type", "application/json")
  .addHeader("authorization", "Token 12345678900987sr")
  .build();

Response response = client.newCall(request).execute();
curl curl -X GET \
  https://api.simpliroute.com/v1/accounts/me/ \
  -H 'authorization: Token 12345678900987sr' \
  -H 'content-type: application/json' \

Asegúrate de reemplazar 12345678900987sr con el token de tu cuenta.

Para usar el API de SimpliRoute, debes utilizar un token válido en el encabezado (o header) "Authorization". Si no conoces tu Token, puedes verlo en la sección Perfil de tu cuenta a través del link: https://app2.simpliroute.com/#/uprofile/info.

Si no tienes una cuenta de SimpliRoute, puedes iniciar una demo gratis de 14 días en este link: https://app2.simpliroute.com/#/signup.

Visitas

Si quieres integrar tu sistema con SimpliRoute, el endpoint más relevante es el de Visitas. Un objeto visita es cualquier acción o locación que un conductor debe atender en terreno: una orden de servicio, una entrega de un producto, recoger un producto, etc. Si quieres optimizar esas órdenes y monitorearlas en SimpliRoute, primero debes crearlas en SimpliRoute como un objeto visita. En este objeto debes especificar un par de cosas sencillas:

  • Título
  • Dirección
  • Fecha Planificada

Esta es la información mínima que una visita debe contener para ser aceptada por nuestra API. Como todos los endpoints en el API de SimpliRoute, permite hacer llamadas GET, POST, PUT y DELETE a través de métodos http.

El Objeto Visita

Ejemplo del Objeto Visita

{
        "id": 123,
        "order": 1,
        "tracking_id": "SR12345678901234",
        "status": "pending",
        "title": "Kwik e mart",
        "address": "742 Evergreen Terrace, Springfield, USA",
        "latitude": 44.052698,
        "longitude": -123.020718,
        "load": 1.2,
        "load_2": 2.0,
        "load_3": 3.1,
        "window_start": "10:00",
        "window_end": "14:00",
        "window_start_2": "15:00",
        "window_end_2": "18:00",
        "duration": "10",
        "contact_name": "Apu Nahasapeemapetilon",
        "contact_phone": "+123413123212",
        "contact_email": "[email protected]",
        "reference": "invoice_id",
        "notes": "Leave at front door",
        "skills_required": [],
        "skills_optional": [],
        "planned_date": "2020-01-01",
        "estimated_time_arrival": null,
        "estimated_time_departure": null,
        "checkin_time": null,
        "checkout_time": null,
        "checkout_latitude": null,
        "checkout_longitude": null,
        "checkout_comment": "Delivery was completed!",
        "pictures": [],
        "priority_level": 1
    }
Atributos Tipo de Datos Descripción
id uuid Identificador único de la visita.
order Integer Una vez que una visita ya está ruteada, order indica su orden dentro de la ruta.
tracking_id String Código de seguimiento del pedido autogenerado.
status String Estado de la visita (pending, completed, failed)
title String Nombre para identificar el pedido. Usualmente el nombre de una empresa o el de una persona.
address String Dirección donde se debe entregar el pedido. Una buena práctica es seguir el formato Googlemaps (Calle N°, Distrito, Ciudad).
planned_date Date Fecha cuando el pedido/orden será entregado.
latitude Float Latitud donde se encuentra la visita.
longitude Float Longitud donde se encuentra la visita.
load Double Espacio o carga que ocupa el pedido en el vehículo. Puede ser en kilos, metros cúbicos o la unidad que use tu negocio.
load_2 Double Segunda unidad de carga complementaria a la primera.
load_3 Double Tercera unidad de carga complementaria a las dos anteriores.
window_start Time Hora inicial en la que ese cliente puede ser visitado.
window_end Time Hora final en la que ese cliente puede ser visitado.
window_start_2 Time En el caso en que el cliente pueda visitarse en 2 horarios distintos en el día. Hora inicial de la segunda ventana.
window_end_2 Time En el caso en que el cliente pueda visitarse en 2 horarios distintos en el día. Hora final de la segunda ventana.
duration Integer Tiempo estimado de estadía en la visita (en minutos).
contact_name String Nombre de quien recibirá el pedido.
contact_phone String Teléfono de quien recibirá el pedido.
contact_email String E-mail de quien recibirá el pedido.
notes String Notas adicionales de ayuda al conductor.
skills_required Integer array Arreglo de habilidades obligatorias que debe tener el vehículo para ir a esta visita.
skills_optional Integer array Arreglo de habilidades opcionales que debe tener el vehículo para ir a esta visita.
estimated_time_arrival Time Hora estimada por SimpliRoute de llegada a la visita.
estimated_time_departure Time Hora estimada por SimpliRoute de salida desde la visita.
checkin_time Timestamp Horario en que el conductor inició la entrega del pedido en la visita.
checkout_time Timestamp Horario en que el conductor terminó la entrega del pedido en la visita.
checkout_latitude Float Latitude en la que el conductor terminó la entrega del pedido.
checkout_longitude Float Longitud en la que el conductor terminó la entrega del pedido.
checkout_comment String Comentarios que el conductor ingresó al momento de hacer el pedido.
pictures URL array Arreglo de URLs con las fotos que el conductor haya tomado en la visita.
priority_level Integer Si esta visita es más importante que otras. Posibles valores de 1 a 5. 1: Primera visita del día, 2: Última visita del día. 3: Prioridad Alta, 4: Prioridad Media, 5: Prioridad Baja.

Crear una Visita

Definición de la URL


POST https://api.simpliroute.com/v1/routes/visits/

Llamada de Ejemplo

  curl -X POST \
    https://api.simpliroute.com/v1/routes/visits/ \
    -H 'authorization: Token 12345678900987sr' \
    -H 'content-type: application/json' \
    -d '{
    "title": "Kwik e mart",
    "address": "742 Evergreen Terrace, Springfield, USA",
    "latitude": 44.052698,
    "longitude": -123.020718,
    "contact_name": "Apu Nahasapeemapetilon",
    "contact_phone": "+123413123212",
    "contact_email": "[email protected]",
    "reference": "invoice_id",
    "notes": "Leave at front door",
    "planned_date": "2020-01-01"
  }'


OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n  \"title\": \"Kwik e mart\",\n  \"address\": \"742 Evergreen Terrace, Springfield, USA\",\n  \"latitude\": 44.052698,\n  \"longitude\": -123.020718,\n  \"contact_name\": \"Apu Nahasapeemapetilon\",\n  \"contact_phone\": \"+123413123212\",\n  \"contact_email\": \"[email protected]\",\n  \"reference\": \"invoice_id\",\n  \"notes\": \"Leave at front door\",\n  \"planned_date\": \"2020-01-01\"\n}");
Request request = new Request.Builder()
  .url("https://api.simpliroute.com/v1/routes/visits/")
  .post(body)
  .addHeader("content-type", "application/json")
  .addHeader("authorization", "Token 12345678900987sr")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://api.simpliroute.com/v1/routes/visits/",
  "method": "POST",
  "headers": {
    "content-type": "application/json",
    "authorization": "Token 12345678900987sr"
  },
  "processData": false,
  "data": "{\n  \"title\": \"Kwik e mart\",\n  \"address\": \"742 Evergreen Terrace, Springfield, USA\",\n  \"latitude\": 44.052698,\n  \"longitude\": -123.020718,\n  \"contact_name\": \"Apu Nahasapeemapetilon\",\n  \"contact_phone\": \"+123413123212\",\n  \"contact_email\": \"[email protected]\",\n  \"reference\": \"invoice_id\",\n  \"notes\": \"Leave at front door\",\n  \"planned_date\": \"2020-01-01\"\n}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

Para crear una visita, la información mínima es title, address y planned_date. Los demás parámetros de la visita son opcionales y los necesitarás dependiendo de tu implementación y las características de tu negocio.

Puedes crear visitas una por una o muchas en un arreglo. El ejemplo a la derecha muestra la creación una a una, pero si necesitas crearlas en bloques la llamada al servicio lucirá así:

Respuesta

La respuesta la creación de la visita retorna el objeto visita resultante si la creación fue exitosa. Esta llamada arrojará un error si alguno de los parámetros inyectados fueron inválidos.

Obtener una Visita con su ID

Definición de la URL


GET https://api.simpliroute.com/v1/routes/visits/{{visit_id}}

Llamada de Ejemplo Usando '12345' como visit_id de ejemplo

curl -X GET \
  https://api.simpliroute.com/v1/routes/visits/12345 \
  -H 'authorization: Token 12345678900987sr' \
  -H 'content-type: application/json' \
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://api.simpliroute.com/v1/routes/visits/12345")
  .get()
  .addHeader("content-type", "application/json")
  .addHeader("authorization", "Token 12345678900987sr")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://api.simpliroute.com/v1/routes/visits/12345",
  "method": "GET",
  "headers": {
    "content-type": "application/json",
    "authorization": "Token 12345678900987sr"
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

Respuesta de Ejemplo

{
    "id": 12345,
    "order": 1,
    "tracking_id": "SR12345678901123",
    "status": "completed",
    "title": "Duff Beer Company",
    "address": "Suecia 0155, Providencia, Santiago",
    "latitude": "-33.419460",
    "longitude": "-70.611091",
    "load": 1.0,
    "load_2": 2.0,
    "load_3": 3.1,
    "window_start": "09:00",
    "window_end": "11:00",
    "window_start_2": "14:00",
    "window_end_2": "22:00",
    "duration": "20",
    "contact_name": "Bart Simpsons",
    "contact_phone": "+1245721234567",
    "contact_email": "[email protected]",
    "reference": "Leave in the Treehouse",
    "notes": "nota\ncon\nenters\ntest",
    "skills_required": [],
    "skills_optional": [],
    "planned_date": "2017-10-10",
    "route": 12,
    "route_estimated_time_start": null,
    "estimated_time_arrival": null,
    "estimated_time_departure": null,
    "checkin_time": null,
    "checkout_time": null,
    "checkout_latitude": null,
    "checkout_longitude": null,
    "checkout_comment": "",
    "checkout_observation": null,
    "signature": null,
    "pictures": [],
    "created": "2017-10-10T18:35:24.797823Z",
    "modified": "2017-10-10T18:35:24.800917Z",
    "eta_predicted": "2017-10-10T00:00:00-03:00",
    "eta_current": "2017-10-10T00:00:00-03:00",
    "driver": null,
    "vehicle": null,
    "priority": false,
    "sms_enabled": false,
    "has_alert": false,
    "priority_level": null
}

Devuelve los detalles de una visita existente. Haz la llamada enviando el ID único de la visita y el API de SimpliRoute te devolverá la información de la visita.

Obtener las visitas de una fecha

Definición


GET https://api.simpliroute.com/v1/routes/visits/?planned_date={{planned_date}}

Llamada de Ejemplo

curl -X GET \
  'https://api.simpliroute.com/v1/routes/visits/?planned_date=2020-01-01' \
  -H 'authorization: Token 12345678900987sr' \
  -H 'content-type: application/json'

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://api.simpliroute.com/v1/routes/visits/?planned_date=2020-01-01")
  .get()
  .addHeader("content-type", "application/json")
  .addHeader("authorization", "Token 12345678900987sr")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://api.simpliroute.com/v1/routes/visits/?planned_date=2020-01-01",
  "method": "GET",
  "headers": {
    "content-type": "application/json",
    "authorization": "Token 12345678900987sr"
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

Llamada GET para obtener todas las visitas planificadas para una fecha específica. El formato esperado para la fecha es 'AAA-MM-DD' (Año-Mes-día, 2020-10-22). Esta llamada es útil cuando quieres monitorear el estado de tus visitas durante el día, ya que devuelve la lista completa de visitas del día y todo lo que ha ocurrido con ellas (incluyendo checkout e información ingresada por los conductores en la calle).

Respuesta

Lista todas las visitas de una fecha específica. Cada entrada en el arreglo es un objeto visita. Si no hay visitas planificadas para esa fecha, el arreglo resultante estará vacío. Esta llamada retornará un error si planned_date no tiene el formato correcto.

Actualizar una visita

Definición de la URL


PUT https://api.simpliroute.com/v1/routes/visits/{{visit_id}}

Llamada de Ejemplo

curl -X PUT \
  https://api.simpliroute.com/v1/routes/visits/1111/ \
  -H 'authorization: Token 12345678900987sr' \
  -H 'content-type: application/json' \
  -d '{
  "title": "Updated visit",
  "address": "new address",
  "load": 39,
  "duration": "00:00:10",
  "contact_name": "New visit contact",
  "contact_phone": "+12341345",
  "notes": "New information",
  "planned_date": "2020-06-30"
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n  \"title\": \"Updated visit\",\n \"address\": \"New address\",\n \"load\": 39,\n  \"duration\": \"00:00:10\",\n  \"contact_name\": \"New visit contact\",\n  \"contact_phone\": \"+12341345\",\n  \"notes\": \"New information\",\n  \"planned_date\": \"2020-06-30\"\n}");
Request request = new Request.Builder()
  .url("https://api.simpliroute.com/v1/routes/visits/1111/")
  .put(body)
  .addHeader("content-type", "application/json")
  .addHeader("authorization", "Token 12345678900987sr")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://api.simpliroute.com/v1/routes/visits/1111/",
  "method": "PUT",
  "headers": {
    "content-type": "application/json",
    "authorization": "Token 12345678900987sr"
  },
  "processData": false,
  "data": "{\n  \"title\": \"Updated visit\",\n  \"address\": \"New address\",\n \"load\": 39,\n  \"duration\": \"00:00:10\",\n  \"contact_name\": \"New visit contact\",\n  \"contact_phone\": \"+12341345\",\n  \"notes\": \"New information\",\n  \"planned_date\": \"2020-06-30\"\n}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

Actualiza la visita con los nuevos parámetros ingresados en la llamada. Cualquier parámetro no incluido en la llamada de actualización permanecerá con sus valores antiguos.

Respuesta

Retorna el objeto visita con sus parámetros actualizados si la llamada fue exitosa. Esta llamada puede retornar un error si los parámetros enviados en la actualización son inválidos.

Respuesta de Ejemplo

Optimización

Endpoint de Optimización


https://optimizator.simpliroute.com/vrp/optimize/sync/

Dada nuestra alta experiencia en optimización de rutas, garantizamos que esta es la mejor forma de crear las rutas de despacho para tu empresa. Creemos que los problemas complejos necesitan soluciones sencillas, por lo que disponibilizamos la API para acceder a nuestros algoritmos de optimización. Resuelve de la forma más rápida y fácil tus problemas de logística de última milla.

SimpliRoute toma en consideración estas restricciones al momento de optimizar:

  • Capacidades o cargas de tus vehículos.
  • Diferentes puntos de inicio y fin para cada uno de tus vehículos en el día.
  • Turnos de los choferes.
  • Ventanas horarias de tus clientes.
  • Y mucho más.

En las secciones siguientes profundizaremos sobre nuestra API, los objetos que contiene y veremos varios ejemplos prácticos para que comiences a desarrollar tu aplicación con nuestra API. Si tienes preguntas, puedes escribirnos un correo a [email protected]

La Instancia de Optimización

JSON de Entrada


{
    "vehicles": [
        {
            "ident": "Vehicle 1",
            "location_start": {
                "ident": "warehouse A",
                "lat": -33.4233926,
                "lon": -70.6104996
            },
            "location_end": {
                "ident": "warehouse C",
                "lat": -33.4233926,
                "lon": -70.6104996
            },
            "capacity": 3500,
            "capacity_2": 3500,
            "capacity_3": 3500,
            "shift_start": "9:00",
            "shift_end": "22:00",
            "skills":[]
        },
        {
            "ident": "Vehicle 2",
            "location_start": {
                "ident": "warehouse B",
                "lat": -33.4233926,
                "lon": -70.6104996
            },
            "location_end": {
                "ident": "warehouse C",
                "lat": -33.4233926,
                "lon": -70.6104996
            },
            "capacity": 3500,
            "capacity_2": 3500,
            "capacity_3": 3500,
            "shift_start": "9:00",
            "shift_end": "22:00",
            "skills":[]
        }
    ],
    "nodes": [
        {
            "ident": "El Salto 4875",
            "lat": -33.3887,
            "lon": -70.62304,
            "window_start": "09:00",
            "window_end": "17:00",
            "window_start_2": "19:00",
            "window_end_2": "22:00",
             "duration": 15
        },
        {
            "ident": "Avenida Del Valle 7",
            "lat": -33.39124,
            "lon": -70.61387,
            "load": 2530,
            "window_start": "9:00",
            "window_end": "11:00",
            "window_start_2": "19:00",
            "window_end_2": "22:00",
            "duration": 15
        },
        {
            "ident": "Larrain 5862",
            "lat": -33.45066,
            "lon": -70.54915,
            "load": 77,
            "window_start": "09:00",
            "window_end": "17:00",
            "window_start_2": "19:00",
            "window_end_2": "22:00",
            "priority_level": 1,

            "duration": 10
        }
    ],
      "balance": true,
      "all_vehicles": false,
      "join": true,
      "open_ended": false,
      "single_tour": true,
      "fmv":1.0

}

Nuestra API recibe un objeto JSON como entrada. El JSON de Optimización se divide en 3 partes:

  • Vehicles: Arreglo de vehículos con la información que necesita la API.
  • Nodes: Arreglo de visitas o deliveries con sus respectivas restricciones para ser ruteadas por la API.
  • Optimization options: Diferentes opciones de optimización para ajustar el ruteo a la operación de tu empresa.

En las próximas secciones discutiremos cada uno de estos objetos. Además, mostraremos un par de ejemplos sobre como hacer una llamada a nuestra API con diferentes casos de uso para que te sea más fácil empezar a programar con SimpliRoute.

Vehículos

Ejemplos del Objeto Vehículos:

{
    "ident": "Vehicle 1",
    "location_start": {
        "ident": "warehouse B",
        "lat": -33.4233926,
        "lon": -70.6104996
    },
    "location_end": {
        "ident": "warehouse C",
        "lat": -33.345523,
        "lon": -70.456992
    },
    "capacity": 3500,
    "capacity_2": 3500,
    "capacity_3": 3500,
    "shift_start": "09:00",
    "shift_end": "18:00",
    "skills": ["north-east", "electricity", "cold"],
    "refill": 30
}

El primer objeto que debes entender para usar nuestra API de optimización es el de Vehículos. En nuestra API, un vehículo es cualquier objeto o persona que se mueve por la ciudad visitando lugares. Si trabajas con una flota de vehículos, con técnicos en terreno o vendedores por ejemplo, para efectos de nuestra API todos ellos serán "vehículos". Un vehículo tiene los siguientes atributos:

Atributos Mandatoriedad Tipo Descripción
ident Mandatorio String Identificador único del vehículo.
location_start Mandatorio Object Ubicación donde el vehículo comenzará la ruta. Contiene un ID y una ubicación con latitud y longitud.
location_end Opcional Object Ubicación donde el vehículo terminará la ruta. Contiene un ID y una ubicación con latitud y longitud.
capacity Opcional Float Capacidad máxima de productos que el vehículo puede llevar. (Ej: Kilos)
capacity_2 Opcional Float Segunda capacidad máxima de productos, complementaria a la primera (Ej: Metros Cúbicos)
capacity_3 Opcional Float Tercera capacidad máxima de productos, complementaria a las anteriores (Ej: Número de cajas)
shift_start Opcional String String "HH:mm" (formato 24 horas). Cuando el vehículo comienza su ruta.
shift_end Opcional String String "HH:mm" (formato 24 horas). Hora máxima en que el vehículo debe terminar su ruta.
skills Opcional String array Habilidades que posee el vehículo. Deben haber visitas con habilidades también para que se use.
refill Opcional Integer Minutos que toma el vehículo en recargarse en bodega entre una ruta y otra (solo para casos en que el vehículo haga más de una ruta).

Deliveries

Ejemplo del Objeto Nodo o Delivery:

{
    "nodes": [
        {
            "ident": "Delivery 1",
            "lat": -33.3887,
            "lon": -70.62304
        },
        {
            "ident": "Delivery 2",
            "lat": -33.39124,
            "lon": -70.61387,
            "load": 253.1,
            "load_2": 2.0,
            "load_2": 3.2,
            "window_start": "09:00",
            "window_end": "11:00",
            "window_start_2": "13:00",
            "window_end_2": "15:00",
            "duration": 15,
            "skills_required": ["north-east"],
            "skills_optional": ["electricity"],
            "priority_level": 2

        }
    ]
}

Un delivery o nodo es algo que tu vehículo debe hacer en la calle: entregar un pedido, visitar a un cliente, realizar una atención en terreno, etc.

Atributos Mandatoriedad Tipo Descripción
ident Mandatorio String Identificador único del objeto delivery.
lat Mandatorio Object Latitud donde se encuentra el lugar del delivery.
lon Opcional Object Longitud donde se encuentra el lugar del delivery.
load Opcional Float Carga a entregar en el delivery. Debe estar en las mismas unidades que el parámetro load de los vehículos.
load_2 Opcional Float Unidad de carga secundaria del delivery. Debe estar en las mismas unidades que el parámetro load 2 de los vehículos.
load_3 Opcional Float Tercera unidad de carga del delivery. Debe estar en las mismas unidades que el parámetro load 3 de los vehículos.
window_start Opcional String String "HH:mm" (formato 24 horas). Hora mínima en que este delivery puede ser realizado.
window_end Opcional String String "HH:mm" (formato 24 horas). Hora máxima en que este delivery puede ser realizado.
window_start_2 Opcional String String "HH:mm" (formato 24 horas). Segunda hora mínima en que este delivery puede ser realizado. (Ej: Puedo visitar este lugar entre 10:00 y 12:00, y entre 15:00 y 19:00)
window_end_2 Opcional String String "HH:mm" (formato 24 horas). Segunda hora máxima en que este delivery puede ser realizado.
duration Opcional Integer Tiempo en minutos que el vehículo estará realizando la entrega.
skills_required Opcional String array Habilidades que este delivery necesita para ser cumplido. Solo los vehículos que tengan todas estas habilidades podrán atender el delivery.
skills_optional Opcional String array Habilidades que este delivery necesita para ser cumplido. Solo los vehículos que tengan al menos una de estas habilidades podrán atender el delivery.
priority_level Opcional Integer Permite definir que este delivery es más importante que otros. Los posibles valores son 1: Primero del día, 2: Último de su ruta, 3: Prioridad Alta, 4: Prioridad Media, 5: Prioridad Baja.

Opciones de Optimización

SimpliRoute permite configurar los parámetros de la optimización en la mejor forma que se adapte a tu operación. Las opciones disponibles son:

Atributos Mandatorio Tipo Descripción
balance Opcional Boolean Default: False. Si es true, el algoritmo intentará balancear las rutas de todos los vehículos, en tiempo y número de deliveries por ruta.
fmv Opcional Integer Default: 2.0, Factor de tráfico. Puede ser 1.0 = Poco Tráfico, 1.5 = Tráfico Medio, 2.0 = Tráfico Alto o 3.0 = Tráfico Intensivo.
all_vehicles Opcional Boolean Default: False. Si es true, el algoritmo asignará rutas a todos los vehículos de la llamada. Si es falso, el algoritmo decidirá cuántos y cuáles vehículos deben usarse.
open_ended Opcional Boolean Default: False. Si es true, las rutas se crearán asumiendo que los vehículos no deben retornar a sus bodegas al final del día.
single_tour Opcional Boolean Default: False. Si es true, los vehículos tendrán máximo 1 ruta cada uno.

Ejemplo - Optimización Básica

JSON de Entrada

{
    "vehicles": [
        {
            "ident": "Vehicle 1",
            "location_start": {
                "ident": "depot_1_start",
                "lat": -33.4233926,
                "lon": -70.6104996
            }
        }
    ],
    "nodes": [
        {
            "ident": "1",
            "lat": -33.436135,
            "lon": -70.6509688
        },
        {
            "ident": "2",
            "lat": -33.4334123,
            "lon": -70.653234
        },
        {
            "ident": "3",
            "lat": -33.333413,
            "lon": -70.5534688
        }
    ]
}

JSON de Respuesta

{
    "vehicles": [{
        "ident": "Vehicle 1",
        "tours": [{
            "nodes": [{
                "arrival": "00:00",
                "ident": "depot_1_start",
                "lon": -70.6104996,
                "departure": "00:00",
                "lat": -33.4233926,
                "order": 0
            }, {
                "load": 0,
                "arrival": "00:17",
                "ident": "3",
                "lon": -70.5534688,
                "departure": "00:17",
                "lat": -33.333413,
                "order": 1
            }, {
                "load": 0,
                "arrival": "00:39",
                "ident": "2",
                "lon": -70.653234,
                "departure": "00:39",
                "lat": -33.4334123,
                "order": 2
            }, {
                "load": 0,
                "arrival": "00:40",
                "ident": "1",
                "lon": -70.6509688,
                "departure": "00:40",
                "lat": -33.436135,
                "order": 3
            }, {
                "arrival": "01:42",
                "ident": "depot_1_start",
                "lon": -70.6104996,
                "departure": "01:42",
                "lat": -33.4233926,
                "order": 11
            }]
        }]
    }],
    "num_vehicles_used": 1
}

El ejemplo más básico de optimización de rutas usando nuestra API es cuando hay solo una bodega, de la cual todos tus vehículos comienzan y terminan su día.

Además, en cada delivery no hay restricciones ni de carga ni de ventanas horarias. Esto ocurre generalmente en casos como:

  • Reparto de cartas y documentos
  • Reparto de comida en que la carga del vehículo no es relevante

Puedes ver un ejemplo de JSON de entrada y salida a la derecha.

En este ejemplo hay 2 entidades relevantes: Vehículos y Nodos. El primero de ellos debe contener:

"Ident" es obligatorio y es el id del vehículo. El objeto "location_start" es el lugar donde tu vehículo comenzará su ruta. Como en este ejemplo no definimos un "location_end", la API asume que el vehículo terminará su ruta en "location_start".

En el caso de los nodos, debes definir:

Usaremos "ident" como el ID del delivery, y "lat" y "lon" para especificar la latitud y longitud del delivery. Dado que en este ejemplo no hay ventanas horarias ni carga, no hay necesidad de especificar nada más en cada delivery.

Ventanas Horarias de los Vehículos

Si no se definen turnos o ventanas horarias para los vehículos, nuestro algoritmo asumirá que la hora de inicio del vehículo será a las "00:00" y la hora de fin a las "23:59" del mismo día. Si deseas especificar otro horario, debes añadir valores a "shift_start" y "shift_end". Un ejemplo de esto es:

Tiempos de Servicio

Si no se especifica un tiempo de servicio en un delivery, nuestro algoritmo asumirá que el tiempo de estadía en ese lugar es 0 (cero) minutos. Si deseas añadir un valor, debes especificarlo en el objeto node como muestra el ejemplo:

"Duration" debe ser un integer en minutos. Representa cuanto tiempo estará el vehículo en ese lugar.

Ejemplo - Múltiples bodegas

Similar al caso anterior, puedes definir para cada vehículo ubicaciones diferentes de inicio y fin del día. De esta forma, puedes simular operaciones más complejas en las que un vehículo inicia el día en una ciudad y termina en otra por ejemplo. Un JSON de ejemplo se encuentra en la barra de la derecha.

JSON de Entrada:

{
    "vehicles": [{
        "ident": "Vehicle 1 different start and end",
        "shift_start": "09:00",
        "shift_end": "19:00",
        "location_start": {
            "ident": "depot_1_start",
            "lat": -33.4233926,
            "lon": -70.6104996
        },
        "location_end": {
            "ident": "depot_2_end",
            "lat": -33.436662,
            "lon": -70.577584
        }
    }],
    "nodes": [{
        "ident": "1",
        "lat": -33.436135,
        "lon": -70.6509688
    }, {
        "ident": "2",
        "lat": -33.4334135,
        "lon": -70.6534688,
        "duration": 5
    }, {
        "ident": "3",
        "lat": -33.333413,
        "lon": -70.5534688,
        "duration": 5
    }]
}

JSON de Salida:

{
    {
    "vehicles": [{
        "ident": "Vehicle 1 different start and end",
        "tours": [{
            "nodes": [{
                "arrival": "09:00",
                "ident": "depot_1_start",
                "lon": -70.6104996,
                "departure": "09:00",
                "lat": -33.4233926,
                "order": 0
            }, {
                "load": 0,
                "arrival": "09:17",
                "ident": "2",
                "lon": -70.6534688,
                "departure": "09:22",
                "lat": -33.4334135,
                "order": 1
            }, {
                "load": 0,
                "arrival": "10:05",
                "ident": "1",
                "lon": -70.6509688,
                "departure": "10:35",
                "lat": -33.436135,
                "order": 2
            }, {
                "load": 0,
                "arrival": "10:49",
                "ident": "3",
                "lon": -70.5534688,
                "departure": "11:19",
                "lat": -33.333413,
                "order": 3
            },{
                "arrival": "11:56",
                "ident": "depot_2_end",
                "lon": -70.577584,
                "departure": "11:56",
                "lat": -33.436662,
                "order": 4
            }]
        }]
    }],
    "num_vehicles_used": 1
}

Optimización con Cargas y Descargas

Ejemplo del Objeto Nodes con Loads y Pickloads

{
    "nodes": [
        {
            "ident": "Delivery Normal",
            "lat": -33.3887,
            "lon": -70.62304,
            "load": 10.1,
            "load_2": 2.0,
            "load_3": 3.2
        },
        {
            "ident": "Pick normal",
            "lat": -33.39124,
            "lon": -70.61387,
            "pickload": 5.1,
            "pickload_2": 1.0,
            "pickload_3": 1.2
        },
        {
            "ident": "Pick y Delivery",
            "lat": -33.4887,
            "lon": -70.92304
            "load": 7.2,
            "load_2": 1.0,
            "load_2": 2.2,
            "pickload": 4.1,
            "pickload_2": 3.0,
            "pickload_3": 3.2
        }
    ]
}

Como una extensión natural de nuestro algoritmo actual se ha desarrollado la opción de considerar que los clientes que son visitados en una ruta pueden tener productos que deban ser recolectados y llevados a la bodega. Dado esto al visitar un cliente es posible entregar productos, recoger productos o ambas acciones.

Este tipo de ruteo es conocido como Optimización de Rutas con Cargas y Descargas. Si en cada punto se entregan o recogen productos, la capacidad del vehículo debe ser chequeada en todo momento, a diferencia de en el ruteo tradicional donde la carga del vehículo no debe ser excedida en el total de la ruta.

Para hacer una optimización con Cargas y Descargas, se debe llamar al mismo endpoint de optimización tradicional, pero añadiendo algunos de los parámetros opcionales por visita de Pickload, modificando el objeto Nodes dentro del JSON de optimización.

A continuación se explican los nuevos campos asociados a un cliente y cómo se relacionan con los ya existentes:

Atributos Mandatoriedad Tipo Descripción
load Opcional Float Carga que debe ser entregada en este cliente. Debe estar en la misma unidad que la capacidad del Vehículo
load_2 Opcional Float Carga secundaria que debe ser entregada en este cliente. Debe estar en la misma unidad que la capacidad secundaria del Vehículo
load_3 Opcional Float Tercera Carga que debe ser entregada en este cliente. Debe estar en la misma unidad que la tercera capacidad del Vehículo
pickload Opcional Float Carga que debe ser recogida en el cliente y llevada a bodega. Debe estar en la misma unidad que la capacidad del Vehículo y que load.
pickload_2 Opcional Float Carga secundaria que debe ser recogida en el cliente y llevada a bodega. Debe estar en la misma unidad que la capacidad secundaria del Vehículo y que load_2
pickload_3 Opcional Float Tercera Carga que debe ser recogida en el cliente y llevada a bodega. Debe estar en la misma unidad que la capacidad del Vehículo y que load_3

Actualización de Horas de Salida y Llegada (ETC)

Endpoint de Actualización de ETC


https://optimizator.simpliroute.com/etc/sync

JSON de Entrada

{
  "vehicle": {
    "vehicle_id": "Vehicle 1",
    "lat": -33.45754,
    "lon": -70.92697,
    "departure_time": "09:00"
  },
  "tours": [{
    "nodes": [{
        "id": "id1",
        "lat": -33.45754,
        "lon": -70.62697,
        "service_time": 30.0,
        "order": 0
      },
      {
        "id": "id2",
        "lat": -33.45744,
        "lon": -70.77532,
        "service_time": 90.0,
        "order": 1
      },
      {
        "id": "id3",
        "lat": -33.45742,
        "lon": -70.60364,
        "service_time": 90.0,
        "order": 2
      }
    ]
  }],
  "fmv":2.0
}

Una vez que tus vehículos están en ruta, muchas cosas pueden ocurrir:

  • Congestión Vehícular
  • Tiempos de servicio más largos de lo esperado
  • Calles cortadas. Manifestaciones. Situaciones inesperadas relacionadas con las calles.
  • Nuevas prioridades a lo largo del día.

Naturalmente, los ETA (tiempo estimado de llegada a un punto) calculados inicialmente no serán válidos después de unas horas. Para estos casos, tenemos un endpoint dedicado a resolver este problema. Algunas consideraciones respecto a este endpoint:

  • Debes proveer la hora actual al momento de recalcular un ETA ("departure_time")
  • Debes recalcular los tiempos de un vehículo a la vez por llamada
  • El recálculo es solo de tiempos. La llamada a este servicio no alterará el orden de los puntos que pertenecen a la ruta ni hará una optimización nueva (VRP o TSP)
  • El nuevo ETA será en base a estimaciones de tráfico.

La información que el endpoint necesita para el vehículo es la siguiente:

Atributos Mandatoriedad Tipo Descripción
Vehicle_id Mandatorio String Identificador único del vehículo
lat Mandatorio Double Latitud en que se encuentra el vehículo en ese momento
lon Mandatorio Double Longitud en que se encuentra el vehículo en ese momento
departure_time Mandatorio Time Hora actual para usar como inicio del recálculo de ETA. En formato "HH:mm"

La información respecto a los nodos en el endpoint es la siguiente:

Atributos Mandatoriedad Tipo Descripción
id Mandatorio String Identificador único de la visita
lat Mandatorio Double Latitud de la visita
lon Mandatorio Double Longitud de la visita
service_time Mandatorio Double Tiempo de servicio en la visita (minutos)
order Mandatorio Integer Orden de la visita dentro de la ruta

Puedes ver un ejemplo de la respuesta de este endpoint en el lado derecho de la documentación.

JSON de Respuesta:

{
    "vehicle": {
        "vehicle_id": "Vehicle 1",
        "lat": -33.45754,
        "lon": -70.92697,
        "departure_time": "09:00"
    },
    "tours": [
        {
            "nodes": [
                {
                    "id": "id1",
                    "lat": -33.45754,
                    "lon": -70.62697,
                    "service_time": 30,
                    "order": 0,
                    "arrival": "09:48",
                    "departure": "10:18"
                },
                {
                    "id": "id2",
                    "lat": -33.45744,
                    "lon": -70.77532,
                    "service_time": 90,
                    "order": 1,
                    "arrival": "10:50",
                    "departure": "12:20"
                },
                {
                    "id": "id3",
                    "lat": -33.45742,
                    "lon": -70.60364,
                    "service_time": 90,
                    "order": 2,
                    "arrival": "13:00",
                    "departure": "14:30"
                }
            ]
        }
    ]
}

Errores

El API de SimpliRoute usa los siguientes códigos de error:

Código de Error Descripción
400 Bad Request -- Tu llamada fue inválida. Revisa el formato y el tipo de los datos que enviaste.
401 Unauthorized -- No estás usando el token correcto para hacer la llamada.
404 Not Found -- La llamada que hiciste no arrojó resultados.
405 Method Not Allowed -- Intentaste acceder al endpoint con un método inválido.
406 Not Acceptable -- Hiciste una llamada con un formato que no es JSON.
500 Internal Server Error -- Hubo un problema con nuestro servidor. Inténtalo más tarde o comunícate con nosotros.
503 Service Unavailable -- Estamos temporalmente fuera por mantenimiento. Por favor inténtalo más tarde.