RouteMateRouteMate
Guía para desarrolladores

Documentación API

Todo lo que necesitas para integrar tu plataforma de entregas con RouteMate.

Resumen

Primeros pasos

La API de integración de RouteMate te permite importar trabajos de entrega por programación, optimizar rutas automáticamente y consultar el estado de los trabajos desde tus sistemas existentes.

URL base

https://api.routemate.app/v1

Cómo funciona

  1. Crear una integración — En la app web de RouteMate, ve a Integraciones y haz clic en Crear integración. Recibirás un client_id y un client_secret.
  2. Obtener un token de acceso — Intercambia tus credenciales por un bearer token temporal con validez de 1 hora.
  3. Importar un trabajo — Envía tus paradas de entrega por POST. RouteMate geocodificará las direcciones, optimizará el orden de la ruta y asignará el trabajo a un conductor.
  4. Consultar estado — Revisa el progreso de tu trabajo en cualquier momento para ver qué paradas se han completado.

Requisitos

  • Una cuenta de RouteMate en el plan Team o Enterprise
  • Una organización creada en la app web de RouteMate
  • Una integración activa con credenciales de cliente
Autenticación

Flujo de credenciales de cliente

La API usa credenciales de cliente OAuth2. Tu secreto nunca se almacena: solo conservamos un hash SHA-256 en nuestros servidores.

Modelo de seguridad

  • Los secrets de cliente se hashean con SHA-256 y nunca se almacenan en texto plano
  • Los tokens de acceso son opacos (no JWT) y son válidos durante 1 hora
  • Los tokens son de un solo uso y están limitados a tu integración
  • Todas las solicitudes deben hacerse por HTTPS
  • Incluye el token en cada solicitud: Authorization: Bearer <token>

Importante: Tu client_secret solo se muestra una vez cuando creas la integración. Guárdalo de forma segura, por ejemplo en variables de entorno o un gestor de secretos. Si lo pierdes, tendrás que regenerarlo desde el panel de RouteMate.

Endpoint

Obtener token de acceso

POST/v1/integration-token
Intercambiar credenciales por un bearer token
Llama a este endpoint para recibir un token de acceso temporal. Inclúyelo en la cabecera Authorization de las solicitudes posteriores.

Cuerpo de la solicitud

FieldTypeRequiredDescription
client_idstringYesEl client ID de tu integración (empieza por rm_ci_)
client_secretstringYesEl client secret de tu integración (empieza por rm_cs_)

Ejemplo de solicitud

curl -X POST https://api.routemate.app/v1/integration-token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "rm_ci_abc123...",
    "client_secret": "rm_cs_xyz789..."
  }'

Respuesta correcta 200

{
  "access_token": "rm_at_e5988dd1b91a4ff3827c5d2ed416ccbe37ae227a",
  "token_type": "Bearer",
  "expires_in": 3600
}

Respuestas de error

400Falta client_id o client_secret

401Credenciales no válidas (secret incorrecto o client_id desconocido)

403La integración ha sido deshabilitada

Endpoint

Importar trabajo y paradas

POST/v1/integration-import
Crear un trabajo de entrega con paradas
Importa un trabajo de entrega con una o más paradas. RouteMate geocodificará direcciones sin coordenadas, optimizará el orden de entrega y asignará la ruta al conductor.

Cabeceras de la solicitud

FieldTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Content-TypestringYesapplication/json
Idempotency-KeystringNoClave única para evitar importaciones duplicadas (válida durante 24 horas)

Cuerpo de la solicitud — Campos del trabajo

FieldTypeRequiredDescription
external_job_idstringYesTu identificador único para este trabajo (debe ser único por integración)
titlestringYesTítulo del trabajo (por ejemplo, Morning Deliveries - Zone A)
driver_emailstringYesEmail del conductor asignado. Si tiene una cuenta de RouteMate, verá la ruta en su app. Si no, se crea una invitación.
scheduled_datestringNoFecha programada en formato ISO (YYYY-MM-DD)
timezonestringNoZona horaria IANA (por ejemplo, Australia/Brisbane o America/New_York)
metadataobjectNoDatos personalizados en formato clave-valor adjuntos al trabajo
stopsarrayYesArray de objetos de parada (ver Campos de parada más abajo)

Ejemplo de solicitud

curl -X POST https://api.routemate.app/v1/integration-import \
  -H "Authorization: Bearer rm_at_your_token_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-batch-2026-03-09-001" \
  -d '{
    "external_job_id": "BATCH-2026-03-09-A",
    "title": "Morning Deliveries - Zone A",
    "driver_email": "driver@example.com",
    "scheduled_date": "2026-03-09",
    "timezone": "Australia/Brisbane",
    "stops": [
      {
        "external_stop_id": "ORD-1001",
        "address": "1 George St, Brisbane QLD 4000, Australia",
        "label": "John Smith",
        "notes": "Leave at front door",
        "priority": 1,
        "parcel_count": 2
      },
      {
        "external_stop_id": "ORD-1002",
        "address": "100 Queen St, Brisbane QLD 4000, Australia",
        "label": "Jane Doe",
        "notes": "Ring doorbell",
        "priority": 2
      },
      {
        "external_stop_id": "ORD-1003",
        "address": "South Bank Parklands, Brisbane QLD 4101, Australia",
        "label": "Bob Wilson",
        "priority": 3,
        "parcel_count": 1
      }
    ]
  }'

Respuesta correcta 200

{
  "job_id": "e7ad097b-bc51-4d01-9b04-0e372d80613a",
  "external_job_id": "BATCH-2026-03-09-A",
  "route_id": "1c2a8c0b-1b69-4a04-85b1-608b2ebe3878",
  "driver_email": "driver@example.com",
  "driver_resolved": true,
  "driver_user_id": "573b6bee-aa3d-4cb0-af87-620bba0db049",
  "stops_imported": 3,
  "stops_geocoded": 3,
  "stops_geocode_failed": 0,
  "optimization": {
    "total_distance_km": 12.4,
    "total_duration_minutes": 25,
    "encoded_polyline": "fvmfDqmfe\\bPtA..."
  },
  "stops": [
    {
      "external_stop_id": "ORD-1001",
      "address": "1 George St, Brisbane QLD 4000, Australia",
      "latitude": -27.4710,
      "longitude": 153.0234,
      "label": "John Smith",
      "notes": "Leave at front door",
      "sort_order": 0,
      "priority": 1,
      "parcel_count": 2,
      "status": "pending"
    },
    {
      "external_stop_id": "ORD-1003",
      "address": "South Bank Parklands, Brisbane QLD 4101, Australia",
      "latitude": -27.4753,
      "longitude": 153.0208,
      "label": "Bob Wilson",
      "notes": null,
      "sort_order": 1,
      "priority": 3,
      "parcel_count": 1,
      "status": "pending"
    },
    {
      "external_stop_id": "ORD-1002",
      "address": "100 Queen St, Brisbane QLD 4000, Australia",
      "latitude": -27.4688,
      "longitude": 153.0281,
      "label": "Jane Doe",
      "notes": "Ring doorbell",
      "sort_order": 2,
      "priority": 2,
      "parcel_count": 1,
      "status": "pending"
    }
  ],
  "deep_link": "https://app.routemate.app/app/jobs/e7ad097b-...",
  "warnings": [
    { "code": "ADDRESS_GEOCODED", "message": "3 stop(s) were geocoded from address text" },
    { "code": "ROUTE_OPTIMIZED", "message": "Route optimized: 12.4 km, 25 min" }
  ]
}

Nota: Nota: el array stops se devuelve en orden de entrega optimizado según sort_order, no en el orden enviado.

Códigos de advertencia

FieldTypeRequiredDescription
ROUTE_OPTIMIZEDinfoNoLa ruta se optimizó correctamente con distancia y duración
ADDRESS_GEOCODEDinfoNoUna o más paradas se geocodificaron a partir del texto de la dirección
DRIVER_AUTO_ADDEDinfoNoEl conductor tenía una cuenta de RouteMate y se añadió automáticamente a tu organización
DRIVER_NOT_FOUNDwarningNoNo se encontró ninguna cuenta de RouteMate para ese email. Se creó una invitación.
GEOCODE_FAILEDwarningNoNo se pudo geocodificar la dirección de una parada. Proporciona latitude/longitude en su lugar.
Endpoint

Consultar estado del trabajo

GET/v1/integration-jobs
Obtener detalles del trabajo y estados de las paradas
Consulta el estado actual de un trabajo, incluyendo todas las paradas con su estado de entrega. Los resultados se limitan a tu integración.

Parámetros de consulta

FieldTypeRequiredDescription
external_job_idstringNoTu ID externo del trabajo (el que proporcionaste durante la importación)
job_idstringNoEl UUID interno del trabajo en RouteMate

Debes proporcionar al menos external_job_id o job_id.

Ejemplo de solicitud

curl "https://api.routemate.app/v1/integration-jobs?external_job_id=BATCH-2026-03-09-A" \
  -H "Authorization: Bearer rm_at_your_token_here"

Respuesta correcta 200

{
  "job_id": "e7ad097b-bc51-4d01-9b04-0e372d80613a",
  "external_job_id": "BATCH-2026-03-09-A",
  "title": "Morning Deliveries - Zone A",
  "status": "assigned",
  "driver_email": "driver@example.com",
  "driver_resolved": true,
  "driver_user_id": "573b6bee-...",
  "route_id": "1c2a8c0b-...",
  "scheduled_date": "2026-03-09",
  "timezone": "Australia/Brisbane",
  "metadata": {},
  "stop_count": 3,
  "status_counts": {
    "pending": 2,
    "completed": 1
  },
  "deep_link": "https://app.routemate.app/app/jobs/e7ad097b-...",
  "stops": [
    {
      "external_stop_id": "ORD-1001",
      "address": "1 George St, Brisbane QLD 4000",
      "latitude": -27.4710,
      "longitude": 153.0234,
      "label": "John Smith",
      "notes": "Leave at front door",
      "status": "completed",
      "priority": 1,
      "parcel_count": 2
    },
    ...
  ],
  "created_at": "2026-03-09T08:30:00.000Z",
  "updated_at": "2026-03-09T10:15:00.000Z"
}

Estados del trabajo

FieldTypeRequiredDescription
pendingstatusNoTrabajo creado, pero el conductor aún no ha sido asignado o resuelto
assignedstatusNoEl conductor ha sido asignado y puede ver la ruta en su app
in_progressstatusNoEl conductor ha comenzado la ruta
completedstatusNoTodas las paradas han sido entregadas
Referencia

Campos de parada

Lista completa de campos disponibles para cada parada en la solicitud de importación.

FieldTypeRequiredDescription
external_stop_idstringYesTu identificador único para esta parada (debe ser único dentro del trabajo)
addressstringYesDirección completa. Se geocodificará si no se proporcionan latitude/longitude.
latitudenumberNoLatitud en grados decimales. Omite geocodificación si se proporciona junto con longitude.
longitudenumberNoLongitud en grados decimales. Omite geocodificación si se proporciona junto con latitude.
labelstringNoEtiqueta visible (por ejemplo, nombre del cliente o número de pedido)
notesstringNoInstrucciones de entrega para el conductor
service_typestringNoTipo de servicio (por ejemplo, delivery, pickup o service_call)
duration_minutesnumberNoDuración estimada del servicio en esta parada, en minutos
time_window_startstringNoHora más temprana de entrega (datetime ISO 8601)
time_window_endstringNoHora límite de entrega (datetime ISO 8601)
prioritynumberNoNivel de prioridad (un número menor implica mayor prioridad). Por defecto: 0
parcel_countnumberNoNúmero de paquetes para esta parada. Por defecto: 1
metadataobjectNoDatos personalizados en formato clave-valor adjuntos a esta parada

Consejo: Consejo: proporcionar latitude y longitude directamente es más rápido y fiable que geocodificar.

Función

Optimización de rutas

Cada importación optimiza automáticamente la secuencia de entrega para minimizar distancia y tiempo.

Cómo funciona la optimización

  1. Todas las paradas sin coordenadas se geocodifican a partir del texto de la dirección
  2. La primera parada se trata como origen y la última como destino
  3. Todas las paradas intermedias se optimizan para obtener la ruta de conducción más corta usando Google Routes API
  4. El campo sort_order de cada parada se actualiza para reflejar la secuencia optimizada
  5. Se calculan la polilínea de la ruta, la distancia total y la duración estimada

Campos de respuesta

FieldTypeRequiredDescription
optimization.total_distance_kmnumberNoDistancia total de la ruta en kilómetros
optimization.total_duration_minutesnumberNoTiempo total estimado de conducción en minutos
optimization.encoded_polylinestringNoGoogle Encoded Polyline para renderizar la ruta en un mapa

Nota: La optimización requiere al menos 2 paradas con coordenadas válidas. Si la geocodificación falla en algunas paradas, la ruta se optimizará solo con las que sí tengan coordenadas válidas.

Fiabilidad

Idempotencia

Reintenta solicitudes fallidas sin crear trabajos duplicados.

Incluye una cabecera Idempotency-Key con un valor único en las solicitudes de importación. Si se repite la misma clave dentro de 24 horas, la API devolverá la respuesta almacenada en caché en lugar de crear un trabajo duplicado.

curl -X POST https://api.routemate.app/v1/integration-import \
  -H "Authorization: Bearer rm_at_your_token" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: batch-2026-03-09-zone-a" \
  -d '{ ... }'

# Safe to retry — same Idempotency-Key returns cached response
curl -X POST https://api.routemate.app/v1/integration-import \
  -H "Authorization: Bearer rm_at_your_token" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: batch-2026-03-09-zone-a" \
  -d '{ ... }'

Buena práctica: Incluye siempre un Idempotency-Key en producción. Usa una clave determinista para evitar duplicados en reintentos de red.

Referencia

Gestión de errores

Todos los errores devuelven un cuerpo JSON con un campo error.

{
  "error": "Rate limit exceeded",
  "retry_after_seconds": 45
}

// o para errores de validación:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "messages": [
      "external_job_id is required",
      "stops[0].address is required"
    ]
  }
}
EstadoSignificadoAcción
200ÉxitoLa solicitud se completó correctamente
400Solicitud incorrectaRevisa los mensajes de error y corrige el cuerpo de la solicitud
401No autorizadoTu token no es válido o ha expirado. Obtén uno nuevo.
403ProhibidoTu integración ha sido deshabilitada. Contacta con tu administrador.
404No encontradoEl trabajo o el endpoint no existe
405Método no permitidoUsa el método HTTP correcto (POST o GET)
429Demasiadas solicitudesEspera retry_after_seconds antes de reintentar
500Error del servidorReintenta con backoff exponencial. Contacta soporte si persiste.
Límites

Límites de tasa

Los límites se aplican por integración en una ventana móvil de 1 minuto.

PlanSolicitudes / minutoMáx. paradas / importación
Team60200
EnterpriseCustomCustom

Cuando se aplique límite de tasa, la API devolverá HTTP 429 con un campo retry_after_seconds.

Ejemplos

Ejemplos de código completos

Ejemplos listos para copiar y pegar para lenguajes comunes. Todos muestran el flujo completo: autenticar, importar y consultar.

#!/bin/bash
# RouteMate API Integration Example

API_BASE="https://api.routemate.app/v1"
CLIENT_ID="rm_ci_your_client_id"
CLIENT_SECRET="rm_cs_your_client_secret"

# Step 1: Get access token
TOKEN=$(curl -s -X POST "$API_BASE/integration-token" \
  -H "Content-Type: application/json" \
  -d "{
    \"client_id\": \"$CLIENT_ID\",
    \"client_secret\": \"$CLIENT_SECRET\"
  }" | jq -r '.access_token')

echo "Access Token: $TOKEN"

# Step 2: Import a job with stops
RESULT=$(curl -s -X POST "$API_BASE/integration-import" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-batch-001" \
  -d '{
    "external_job_id": "BATCH-001",
    "title": "Morning Deliveries",
    "driver_email": "driver@example.com",
    "scheduled_date": "2026-03-10",
    "timezone": "Australia/Brisbane",
    "stops": [
      {
        "external_stop_id": "STOP-1",
        "address": "1 George St, Brisbane QLD 4000",
        "label": "Customer A",
        "parcel_count": 2
      },
      {
        "external_stop_id": "STOP-2",
        "address": "100 Queen St, Brisbane QLD 4000",
        "label": "Customer B",
        "notes": "Leave at reception"
      }
    ]
  }')

echo "$RESULT" | jq .

# Step 3: Query job status
JOB_ID=$(echo "$RESULT" | jq -r '.job_id')
curl -s "$API_BASE/integration-jobs?job_id=$JOB_ID" \
  -H "Authorization: Bearer $TOKEN" | jq .
Próximamente

Webhooks

Recibe notificaciones en tiempo real cuando se completen entregas.

La compatibilidad con webhooks llegará pronto. Podrás registrar una URL y recibir notificaciones POST para eventos como:

  • job.completed — Todas las paradas del trabajo se han entregado
  • stop.completed — Se completó una sola parada (incluye prueba de entrega)
  • stop.failed — Falló un intento de entrega
  • driver.location — Actualizaciones GPS del conductor en tiempo real

¿Te interesa el acceso anticipado? Contáctanos.

¿Listo para integrar?

Crea tus credenciales de integración en el panel de RouteMate y empieza a importar trabajos en minutos.