RouteMateRouteMate
Guia de developer

Documentação API

Tudo o que precisa para integrar a sua plataforma de entregas com o RouteMate.

Visão geral

Primeiros passos

A Integration API do RouteMate permite importar jobs de entrega de forma programática, otimizar rotas automaticamente e consultar o estado dos jobs a partir dos seus sistemas atuais.

URL base

https://api.routemate.app/v1

Como funciona

  1. Criar uma integração — Na aplicação web do RouteMate, vá a Integrações e clique em Criar integração. Receberá um client_id e um client_secret.
  2. Obter um token de acesso — Troque as suas credenciais por um bearer token temporário válido durante 1 hora.
  3. Importar um job — Envie as suas paragens de entrega por POST. O RouteMate geocodifica os endereços, otimiza a ordem da rota e atribui o job a um motorista.
  4. Consultar o estado — Verifique o progresso do job a qualquer momento para ver quais paragens já foram concluídas.

Requisitos

  • Uma conta RouteMate no plano Team ou Enterprise
  • Uma organização criada na aplicação web do RouteMate
  • Uma integração ativa com credenciais de cliente
Autenticação

Fluxo de client credentials

A API utiliza credenciais de cliente OAuth2. O seu secret nunca é armazenado: apenas um hash SHA-256 fica guardado nos nossos servidores.

Modelo de segurança

  • Os client secrets são hashados com SHA-256 e nunca armazenados em texto simples
  • Os tokens de acesso são opacos (não são JWT) e válidos por 1 hora
  • Os tokens são de utilização única e limitados à sua integração
  • Todos os pedidos devem ser feitos por HTTPS
  • Inclua o token em todos os pedidos: Authorization: Bearer <token>

Importante: O seu client_secret é mostrado apenas uma vez quando cria a integração. Guarde-o de forma segura, por exemplo em variáveis de ambiente ou num gestor de segredos. Se o perder, terá de o regenerar no dashboard do RouteMate.

Endpoint

Obter token de acesso

POST/v1/integration-token
Trocar credenciais por um bearer token
Chame este endpoint para receber um token de acesso temporário. Inclua-o no cabeçalho Authorization dos pedidos seguintes.

Corpo do pedido

FieldTypeRequiredDescription
client_idstringYesO client ID da sua integração (começa por rm_ci_)
client_secretstringYesO client secret da sua integração (começa por rm_cs_)

Pedido de exemplo

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..."
  }'

Resposta de sucesso 200

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

Respostas de erro

400Falta client_id ou client_secret

401Credenciais inválidas (secret incorreto ou client_id desconhecido)

403A integração foi desativada

Endpoint

Importar job e paragens

POST/v1/integration-import
Criar um job de entrega com paragens
Importe um job de entrega com uma ou mais paragens. O RouteMate geocodifica moradas sem coordenadas, otimiza a ordem de entrega e atribui a rota ao motorista.

Cabeçalhos do pedido

FieldTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Content-TypestringYesapplication/json
Idempotency-KeystringNoChave única para evitar importações duplicadas (válida durante 24 horas)

Corpo do pedido — Campos do job

FieldTypeRequiredDescription
external_job_idstringYesO seu identificador único para este job (tem de ser único por integração)
titlestringYesTítulo do job (por exemplo, Morning Deliveries - Zone A)
driver_emailstringYesEmail do motorista a atribuir. Se tiver uma conta RouteMate, verá a rota na aplicação. Caso contrário, será criado um convite.
scheduled_datestringNoData agendada em formato ISO (YYYY-MM-DD)
timezonestringNoFuso horário IANA (por exemplo, Australia/Brisbane ou America/New_York)
metadataobjectNoDados personalizados em formato chave-valor associados ao job
stopsarrayYesArray de objetos de paragem (ver Campos da paragem abaixo)

Pedido de exemplo

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
      }
    ]
  }'

Resposta de sucesso 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: o array stops é devolvido na ordem de entrega otimizada conforme sort_order, não na ordem em que foi enviado.

Códigos de aviso

FieldTypeRequiredDescription
ROUTE_OPTIMIZEDinfoNoA rota foi otimizada com sucesso com distância e duração
ADDRESS_GEOCODEDinfoNoUma ou mais paragens foram geocodificadas a partir do texto da morada
DRIVER_AUTO_ADDEDinfoNoO motorista já tinha uma conta RouteMate e foi adicionado automaticamente à sua organização
DRIVER_NOT_FOUNDwarningNoNão foi encontrada uma conta RouteMate para este email. Foi criado um convite.
GEOCODE_FAILEDwarningNoNão foi possível geocodificar a morada de uma paragem. Forneça latitude/longitude em alternativa.
Endpoint

Consultar estado do job

GET/v1/integration-jobs
Obter detalhes do job e estados das paragens
Consulte o estado atual de um job, incluindo todas as paragens e o respetivo estado de entrega. Os resultados estão limitados à sua integração.

Parâmetros de consulta

FieldTypeRequiredDescription
external_job_idstringNoO seu ID externo do job (o mesmo fornecido durante a importação)
job_idstringNoO UUID interno do job no RouteMate

É necessário fornecer pelo menos external_job_id ou job_id.

Pedido de exemplo

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

Resposta de sucesso 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 do job

FieldTypeRequiredDescription
pendingstatusNoJob criado, mas o motorista ainda não foi atribuído ou resolvido
assignedstatusNoO motorista foi atribuído e pode ver a rota na aplicação
in_progressstatusNoO motorista iniciou a rota
completedstatusNoTodas as paragens foram entregues
Referência

Campos da paragem

Lista completa dos campos disponíveis para cada paragem no pedido de importação.

FieldTypeRequiredDescription
external_stop_idstringYesO seu identificador único para esta paragem (tem de ser único dentro do job)
addressstringYesMorada completa. Será geocodificada se latitude/longitude não forem fornecidas.
latitudenumberNoLatitude em graus decimais. Ignora a geocodificação se for enviada com longitude.
longitudenumberNoLongitude em graus decimais. Ignora a geocodificação se for enviada com latitude.
labelstringNoEtiqueta visível (por exemplo, nome do cliente ou número da encomenda)
notesstringNoInstruções de entrega para o motorista
service_typestringNoTipo de serviço (por exemplo, delivery, pickup ou service_call)
duration_minutesnumberNoDuração estimada do serviço nesta paragem, em minutos
time_window_startstringNoHora mais cedo para entrega (datetime ISO 8601)
time_window_endstringNoHora limite para entrega (datetime ISO 8601)
prioritynumberNoNível de prioridade (número menor = prioridade maior). Predefinição: 0
parcel_countnumberNoNúmero de volumes desta paragem. Predefinição: 1
metadataobjectNoDados personalizados em formato chave-valor associados a esta paragem

Dica: Dica: fornecer latitude e longitude diretamente é mais rápido e fiável do que geocodificação.

Funcionalidade

Otimização de rotas

Cada importação otimiza automaticamente a sequência de entrega para reduzir distância e tempo.

Como funciona a otimização

  1. Todas as paragens sem coordenadas são geocodificadas a partir do texto da morada
  2. A primeira paragem é tratada como origem e a última como destino
  3. Todas as paragens intermédias são otimizadas para o percurso mais curto usando a Google Routes API
  4. O campo sort_order de cada paragem é atualizado para refletir a sequência otimizada
  5. São calculados a polilinha da rota, a distância total e a duração estimada

Campos da resposta

FieldTypeRequiredDescription
optimization.total_distance_kmnumberNoDistância total da rota em quilómetros
optimization.total_duration_minutesnumberNoTempo total estimado de condução em minutos
optimization.encoded_polylinestringNoGoogle Encoded Polyline para apresentar a rota no mapa

Nota: Nota: a otimização exige pelo menos 2 paragens com coordenadas válidas. Se a geocodificação falhar em algumas paragens, a rota será otimizada apenas com as paragens geocodificadas com sucesso.

Fiabilidade

Idempotência

Repita pedidos falhados em segurança sem criar jobs duplicados.

Inclua um cabeçalho Idempotency-Key com um valor único nos pedidos de importação. Se a mesma chave for enviada dentro de 24 horas, a API devolverá a resposta em cache em vez de criar um job 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 '{ ... }'

Boa prática: Inclua sempre um Idempotency-Key em produção. Use uma chave determinística para evitar duplicados em retries de rede.

Referência

Tratamento de erros

Todos os erros devolvem um corpo JSON com um campo error.

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

// ou para erros de validação:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "messages": [
      "external_job_id is required",
      "stops[0].address is required"
    ]
  }
}
EstadoSignificadoAção
200SucessoO pedido foi concluído com sucesso
400Pedido inválidoVerifique as mensagens de erro e corrija o corpo do pedido
401Não autorizadoO seu token é inválido ou expirou. Obtenha um novo.
403ProibidoA sua integração foi desativada. Contacte o seu administrador.
404Não encontradoO job ou o endpoint não existe
405Método não permitidoUse o método HTTP correto (POST ou GET)
429Demasiados pedidosAguarde retry_after_seconds antes de tentar novamente
500Erro do servidorTente novamente com exponential backoff. Contacte o suporte se persistir.
Limites

Rate limits

Os limites são aplicados por integração numa janela móvel de 1 minuto.

PlanoPedidos / minutoMáx. paragens / importação
Team60200
EnterpriseCustomCustom

Quando limitado por taxa, a API devolve HTTP 429 com um campo retry_after_seconds.

Exemplos

Exemplos de código completos

Exemplos prontos a copiar para linguagens comuns. Todos mostram o fluxo completo: autenticar, importar e 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 .
Em breve

Webhooks

Receba notificações em tempo real quando as entregas forem concluídas.

O suporte a webhooks está a chegar. Poderá registar um URL e receber notificações POST para eventos como:

  • job.completed — Todas as paragens de um job foram entregues
  • stop.completed — Uma única paragem foi concluída (inclui prova de entrega)
  • stop.failed — Uma tentativa de entrega falhou
  • driver.location — Atualizações GPS do motorista em tempo real

Interessado em acesso antecipado? Contacte-nos.

Pronto para integrar?

Crie as suas credenciais de integração no dashboard RouteMate e comece a importar jobs em minutos.