RouteMateRouteMate
Guide développeur

Documentation API

Tout ce dont vous avez besoin pour intégrer votre plateforme de livraison à RouteMate.

Vue d'ensemble

Premiers pas

L'API d'intégration RouteMate vous permet d'importer des missions de livraison par programmation, d'optimiser automatiquement les itinéraires et de consulter le statut des missions depuis vos systèmes existants.

URL de base

https://api.routemate.app/v1

Fonctionnement

  1. Créer une intégration — Dans l'application web RouteMate, allez dans Intégrations puis cliquez sur Créer une intégration. Vous recevrez un client_id et un client_secret.
  2. Obtenir un jeton d'accès — Échangez vos identifiants contre un bearer token temporaire valable 1 heure.
  3. Importer un job — Envoyez vos arrêts de livraison via POST. RouteMate géocode les adresses, optimise l'ordre de livraison et assigne le job à un conducteur.
  4. Consulter le statut — Vérifiez la progression de votre job à tout moment pour voir quels arrêts sont terminés.

Prérequis

  • Un compte RouteMate sur l'offre Team ou Enterprise
  • Une organisation créée dans l'application web RouteMate
  • Une intégration active avec des identifiants client
Authentification

Flux client credentials

L'API utilise des identifiants client OAuth2. Votre secret n'est jamais stocké : seul un hash SHA-256 est conservé sur nos serveurs.

Modèle de sécurité

  • Les secrets client sont hachés en SHA-256 et jamais stockés en clair
  • Les jetons d'accès sont opaques (pas des JWT) et valables pendant 1 heure
  • Les jetons sont à usage unique et limités à votre intégration
  • Toutes les requêtes doivent être effectuées via HTTPS
  • Incluez le jeton dans chaque requête : Authorization: Bearer <token>

Important : Votre client_secret n'est affiché qu'une seule fois lors de la création de l'intégration. Stockez-le de manière sécurisée, par exemple dans des variables d'environnement ou un gestionnaire de secrets. En cas de perte, vous devrez le régénérer depuis le tableau de bord RouteMate.

Endpoint

Obtenir un jeton d'accès

POST/v1/integration-token
Échanger des identifiants contre un bearer token
Appelez cet endpoint pour recevoir un jeton d'accès temporaire. Incluez-le dans l'en-tête Authorization des requêtes suivantes.

Corps de la requête

FieldTypeRequiredDescription
client_idstringYesL'identifiant client de votre intégration (commence par rm_ci_)
client_secretstringYesLe secret client de votre intégration (commence par rm_cs_)

Exemple de requête

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

Réponse de succès 200

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

Réponses d'erreur

400client_id ou client_secret manquant

401Identifiants invalides (mauvais secret ou client_id inconnu)

403L'intégration a été désactivée

Endpoint

Importer un job et des arrêts

POST/v1/integration-import
Créer un job de livraison avec des arrêts
Importez un job de livraison avec un ou plusieurs arrêts. RouteMate géocode les adresses sans coordonnées, optimise l'ordre de livraison et affecte l'itinéraire au conducteur.

En-têtes de la requête

FieldTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Content-TypestringYesapplication/json
Idempotency-KeystringNoClé unique pour éviter les imports en double (valable 24 heures)

Corps de la requête — Champs du job

FieldTypeRequiredDescription
external_job_idstringYesVotre identifiant unique pour ce job (doit être unique par intégration)
titlestringYesTitre du job (par exemple Morning Deliveries - Zone A)
driver_emailstringYesEmail du conducteur à assigner. S'il possède un compte RouteMate, il verra la tournée dans son application. Sinon, une invitation sera créée.
scheduled_datestringNoDate planifiée au format ISO (YYYY-MM-DD)
timezonestringNoFuseau horaire IANA (par exemple Australia/Brisbane ou America/New_York)
metadataobjectNoDonnées clé-valeur personnalisées attachées au job
stopsarrayYesTableau d'objets arrêt (voir Champs d'arrêt ci-dessous)

Exemple de requête

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

Réponse de succès 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" }
  ]
}

Remarque : Remarque : le tableau stops est renvoyé dans l'ordre de livraison optimisé selon sort_order, et non dans l'ordre d'envoi.

Codes d'avertissement

FieldTypeRequiredDescription
ROUTE_OPTIMIZEDinfoNoL'itinéraire a été optimisé avec succès avec distance et durée
ADDRESS_GEOCODEDinfoNoUn ou plusieurs arrêts ont été géocodés à partir du texte de l'adresse
DRIVER_AUTO_ADDEDinfoNoLe conducteur possédait déjà un compte RouteMate et a été automatiquement ajouté à votre organisation
DRIVER_NOT_FOUNDwarningNoAucun compte RouteMate n'a été trouvé pour cet email. Une invitation a été créée.
GEOCODE_FAILEDwarningNoImpossible de géocoder l'adresse d'un arrêt. Fournissez latitude/longitude à la place.
Endpoint

Consulter le statut d'un job

GET/v1/integration-jobs
Obtenir les détails d'un job et les statuts des arrêts
Consultez le statut actuel d'un job, y compris tous les arrêts et leur statut de livraison. Les résultats sont limités à votre intégration.

Paramètres de requête

FieldTypeRequiredDescription
external_job_idstringNoVotre identifiant externe de job (celui fourni lors de l'import)
job_idstringNoL'UUID interne du job dans RouteMate

Au moins l'un des paramètres external_job_id ou job_id doit être fourni.

Exemple de requête

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

Réponse de succès 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"
}

Statuts du job

FieldTypeRequiredDescription
pendingstatusNoJob créé, mais le conducteur n'a pas encore été assigné ou résolu
assignedstatusNoLe conducteur a été assigné et peut voir la tournée dans son application
in_progressstatusNoLe conducteur a commencé la tournée
completedstatusNoTous les arrêts ont été livrés
Référence

Champs d'arrêt

Liste complète des champs disponibles pour chaque arrêt dans la requête d'import.

FieldTypeRequiredDescription
external_stop_idstringYesVotre identifiant unique pour cet arrêt (doit être unique dans le job)
addressstringYesAdresse complète. Elle sera géocodée si latitude/longitude ne sont pas fournies.
latitudenumberNoLatitude en degrés décimaux. Le géocodage est ignoré si longitude est aussi fournie.
longitudenumberNoLongitude en degrés décimaux. Le géocodage est ignoré si latitude est aussi fournie.
labelstringNoLibellé affiché (par exemple nom du client ou numéro de commande)
notesstringNoInstructions de livraison pour le conducteur
service_typestringNoType de service (par exemple delivery, pickup ou service_call)
duration_minutesnumberNoDurée de service prévue à cet arrêt en minutes
time_window_startstringNoHeure de livraison la plus tôt (datetime ISO 8601)
time_window_endstringNoHeure limite de livraison (datetime ISO 8601)
prioritynumberNoNiveau de priorité (plus la valeur est basse, plus la priorité est élevée). Par défaut : 0
parcel_countnumberNoNombre de colis pour cet arrêt. Par défaut : 1
metadataobjectNoDonnées clé-valeur personnalisées attachées à cet arrêt

Astuce : Astuce : fournir directement latitude et longitude est plus rapide et plus fiable que le géocodage.

Fonction

Optimisation d'itinéraire

Chaque import optimise automatiquement la séquence de livraison pour réduire temps et distance.

Fonctionnement de l'optimisation

  1. Tous les arrêts sans coordonnées sont géocodés à partir du texte de leur adresse
  2. Le premier arrêt est traité comme origine et le dernier comme destination
  3. Tous les arrêts intermédiaires sont optimisés pour l'itinéraire routier le plus court via Google Routes API
  4. Le champ sort_order de chaque arrêt est mis à jour pour refléter la séquence optimisée
  5. La polyligne de l'itinéraire, la distance totale et la durée estimée sont calculées

Champs de réponse

FieldTypeRequiredDescription
optimization.total_distance_kmnumberNoDistance totale de l'itinéraire en kilomètres
optimization.total_duration_minutesnumberNoTemps total de conduite estimé en minutes
optimization.encoded_polylinestringNoGoogle Encoded Polyline pour afficher l'itinéraire sur une carte

Remarque : L'optimisation nécessite au moins 2 arrêts avec des coordonnées valides. Si le géocodage échoue pour certains arrêts, l'itinéraire sera optimisé uniquement avec ceux qui ont pu être géocodés.

Fiabilité

Idempotence

Relancez les requêtes échouées sans créer de jobs en double.

Ajoutez un en-tête Idempotency-Key avec une valeur unique aux requêtes d'import. Si la même clé est renvoyée dans les 24 heures, l'API renverra la réponse en cache au lieu de créer un doublon.

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

Bonne pratique : Ajoutez toujours un Idempotency-Key en production. Utilisez une clé déterministe pour éviter les doublons lors des retries réseau.

Référence

Gestion des erreurs

Toutes les erreurs renvoient un corps JSON avec un champ error.

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

// ou pour les erreurs de validation :
{
  "error": {
    "code": "VALIDATION_ERROR",
    "messages": [
      "external_job_id is required",
      "stops[0].address is required"
    ]
  }
}
StatutSignificationAction
200SuccèsLa requête a été traitée avec succès
400Requête invalideVérifiez les messages d'erreur et corrigez le corps de la requête
401Non autoriséVotre jeton est invalide ou expiré. Obtenez-en un nouveau.
403InterditVotre intégration a été désactivée. Contactez votre administrateur.
404IntrouvableLe job ou l'endpoint n'existe pas
405Méthode non autoriséeUtilisez la bonne méthode HTTP (POST ou GET)
429Trop de requêtesAttendez retry_after_seconds avant de réessayer
500Erreur serveurRéessayez avec un backoff exponentiel. Contactez le support si le problème persiste.
Limites

Limites de débit

Les limites de débit s'appliquent par intégration sur une fenêtre glissante d'une minute.

OffreRequêtes / minuteArrêts max / import
Team60200
EnterpriseCustomCustom

En cas de limitation, l'API renvoie HTTP 429 avec un champ retry_after_seconds.

Exemples

Exemples de code complets

Exemples prêts à copier-coller pour les langages courants. Tous montrent le flux complet : authentifier, importer et consulter.

#!/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 .
Bientôt disponible

Webhooks

Recevez des notifications en temps réel lorsque les livraisons sont terminées.

La prise en charge des webhooks arrive bientôt. Vous pourrez enregistrer une URL et recevoir des notifications POST pour des événements tels que :

  • job.completed — Tous les arrêts d'un job ont été livrés
  • stop.completed — Un seul arrêt a été livré (avec preuve de livraison)
  • stop.failed — Une tentative de livraison a échoué
  • driver.location — Mises à jour GPS du conducteur en temps réel

Intéressé par un accès anticipé ? Contactez-nous.

Prêt à intégrer ?

Créez vos identifiants d'intégration dans le tableau de bord RouteMate et commencez à importer des jobs en quelques minutes.