RouteMateRouteMate
Entwicklerleitfaden

API-Dokumentation

Alles, was du brauchst, um deine Lieferplattform mit RouteMate zu integrieren.

Überblick

Erste Schritte

Mit der RouteMate-Integrations-API kannst du Lieferjobs programmatisch importieren, Routen automatisch optimieren und den Jobstatus aus deinen bestehenden Systemen abfragen.

Basis-URL

https://api.routemate.app/v1

So funktioniert es

  1. Integration erstellen — Gehe in der RouteMate-Web-App zu Integrationen und klicke auf Integration erstellen. Du erhältst eine client_id und ein client_secret.
  2. Zugriffstoken abrufen — Tausche deine Zugangsdaten gegen ein kurzlebiges Bearer-Token mit 1 Stunde Gültigkeit.
  3. Job importieren — Sende deine Lieferstopps per POST. RouteMate geokodiert die Adressen, optimiert die Routenreihenfolge und weist den Job einem Fahrer zu.
  4. Status abfragen — Prüfe den Fortschritt deines Jobs jederzeit, um zu sehen, welche Stopps abgeschlossen wurden.

Voraussetzungen

  • Ein RouteMate-Konto im Team- oder Enterprise-Tarif
  • Eine in der RouteMate-Web-App erstellte Organisation
  • Eine aktive Integration mit Client Credentials
Authentifizierung

Client-Credentials-Flow

Die API verwendet OAuth2 Client Credentials. Dein Secret wird niemals gespeichert, sondern nur als SHA-256-Hash auf unseren Servern hinterlegt.

Sicherheitsmodell

  • Client-Secrets werden mit SHA-256 gehasht und nie im Klartext gespeichert
  • Access Tokens sind opak (keine JWTs) und 1 Stunde gültig
  • Tokens sind einmalig nutzbar und auf deine Integration beschränkt
  • Alle Anfragen müssen über HTTPS erfolgen
  • Sende das Token bei jeder Anfrage mit: Authorization: Bearer <token>

Wichtig: Dein client_secret wird nur einmal angezeigt, wenn du die Integration erstellst. Speichere es sicher, zum Beispiel in Umgebungsvariablen oder einem Secret-Manager. Wenn es verloren geht, musst du es im RouteMate-Dashboard neu generieren.

Endpunkt

Zugriffstoken abrufen

POST/v1/integration-token
Zugangsdaten gegen ein Bearer-Token tauschen
Rufe diesen Endpunkt auf, um ein kurzlebiges Zugriffstoken zu erhalten. Sende es im Authorization-Header aller folgenden Anfragen mit.

Request-Body

FieldTypeRequiredDescription
client_idstringYesDie Client-ID deiner Integration (beginnt mit rm_ci_)
client_secretstringYesDas Client-Secret deiner Integration (beginnt mit rm_cs_)

Beispielanfrage

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

Erfolgsantwort 200

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

Fehlerantworten

400client_id oder client_secret fehlt

401Ungültige Zugangsdaten (falsches Secret oder unbekannte client_id)

403Die Integration wurde deaktiviert

Endpunkt

Job und Stopps importieren

POST/v1/integration-import
Einen Lieferjob mit Stopps erstellen
Importiere einen Lieferjob mit einem oder mehreren Stopps. RouteMate geokodiert Adressen ohne Koordinaten, optimiert die Lieferreihenfolge und weist die Route dem Fahrer zu.

Request-Header

FieldTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Content-TypestringYesapplication/json
Idempotency-KeystringNoEindeutiger Schlüssel zur Vermeidung doppelter Importe (24 Stunden gültig)

Request-Body — Job-Felder

FieldTypeRequiredDescription
external_job_idstringYesDeine eindeutige Kennung für diesen Job (muss pro Integration eindeutig sein)
titlestringYesJobtitel (zum Beispiel Morning Deliveries - Zone A)
driver_emailstringYesE-Mail des zugewiesenen Fahrers. Wenn der Fahrer ein RouteMate-Konto hat, sieht er die Route in seiner App. Andernfalls wird eine Einladung erstellt.
scheduled_datestringNoGeplantes Datum im ISO-Format (YYYY-MM-DD)
timezonestringNoIANA-Zeitzone (zum Beispiel Australia/Brisbane oder America/New_York)
metadataobjectNoBenutzerdefinierte Schlüssel-Wert-Daten, die dem Job zugeordnet sind
stopsarrayYesArray mit Stopp-Objekten (siehe Stopp-Felder unten)

Beispielanfrage

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

Erfolgsantwort 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" }
  ]
}

Hinweis: Hinweis: Das Array stops wird in optimierter Lieferreihenfolge anhand von sort_order zurückgegeben, nicht in der ursprünglich gesendeten Reihenfolge.

Warncodes

FieldTypeRequiredDescription
ROUTE_OPTIMIZEDinfoNoDie Route wurde erfolgreich mit Distanz und Dauer optimiert
ADDRESS_GEOCODEDinfoNoEin oder mehrere Stopps wurden aus dem Adresstext geokodiert
DRIVER_AUTO_ADDEDinfoNoDer Fahrer hatte bereits ein RouteMate-Konto und wurde automatisch zu deiner Organisation hinzugefügt
DRIVER_NOT_FOUNDwarningNoFür diese E-Mail wurde kein RouteMate-Konto gefunden. Eine Einladung wurde erstellt.
GEOCODE_FAILEDwarningNoDie Adresse eines Stopps konnte nicht geokodiert werden. Gib stattdessen latitude/longitude an.
Endpunkt

Jobstatus abfragen

GET/v1/integration-jobs
Jobdetails und Stoppstatus abrufen
Frage den aktuellen Status eines Jobs einschließlich aller Stopps und ihres Lieferstatus ab. Die Ergebnisse sind auf deine Integration beschränkt.

Query-Parameter

FieldTypeRequiredDescription
external_job_idstringNoDeine externe Job-ID (die beim Import übermittelt wurde)
job_idstringNoDie interne UUID des Jobs in RouteMate

Mindestens einer der Parameter external_job_id oder job_id muss angegeben werden.

Beispielanfrage

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

Erfolgsantwort 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"
}

Job-Status

FieldTypeRequiredDescription
pendingstatusNoJob wurde erstellt, aber der Fahrer ist noch nicht zugewiesen oder aufgelöst
assignedstatusNoDer Fahrer wurde zugewiesen und kann die Route in seiner App sehen
in_progressstatusNoDer Fahrer hat die Route begonnen
completedstatusNoAlle Stopps wurden zugestellt
Referenz

Stopp-Felder

Vollständige Liste der verfügbaren Felder für jeden Stopp in der Importanfrage.

FieldTypeRequiredDescription
external_stop_idstringYesDeine eindeutige Kennung für diesen Stopp (muss innerhalb des Jobs eindeutig sein)
addressstringYesVollständige Straßenadresse. Wird geokodiert, wenn latitude/longitude nicht mitgegeben werden.
latitudenumberNoBreitengrad in Dezimalgrad. Überspringt Geokodierung, wenn longitude ebenfalls vorhanden ist.
longitudenumberNoLängengrad in Dezimalgrad. Überspringt Geokodierung, wenn latitude ebenfalls vorhanden ist.
labelstringNoAnzeigelabel (zum Beispiel Kundenname oder Bestellnummer)
notesstringNoLieferhinweise für den Fahrer
service_typestringNoArt der Leistung (zum Beispiel delivery, pickup oder service_call)
duration_minutesnumberNoErwartete Servicezeit an diesem Stopp in Minuten
time_window_startstringNoFrühester Lieferzeitpunkt (ISO 8601 datetime)
time_window_endstringNoSpätester Lieferzeitpunkt (ISO 8601 datetime)
prioritynumberNoPrioritätsstufe (kleinere Zahl = höhere Priorität). Standard: 0
parcel_countnumberNoAnzahl der Pakete für diesen Stopp. Standard: 1
metadataobjectNoBenutzerdefinierte Schlüssel-Wert-Daten, die diesem Stopp zugeordnet sind

Tipp: Tipp: latitude und longitude direkt mitzuliefern ist schneller und zuverlässiger als Geokodierung.

Funktion

Routenoptimierung

Jeder Import optimiert automatisch die Lieferreihenfolge für minimale Fahrzeit und Distanz.

So funktioniert die Optimierung

  1. Alle Stopps ohne Koordinaten werden aus dem Adresstext geokodiert
  2. Der erste Stopp gilt als Ursprung und der letzte als Ziel
  3. Alle Zwischenstopps werden für die kürzeste Fahrstrecke mit der Google Routes API optimiert
  4. Das Feld sort_order jedes Stopps wird aktualisiert, um die optimierte Reihenfolge abzubilden
  5. Routen-Polylinie, Gesamtdistanz und geschätzte Dauer werden berechnet

Antwortfelder

FieldTypeRequiredDescription
optimization.total_distance_kmnumberNoGesamtdistanz der Route in Kilometern
optimization.total_duration_minutesnumberNoGeschätzte Gesamtfahrzeit in Minuten
optimization.encoded_polylinestringNoGoogle Encoded Polyline zur Darstellung der Route auf einer Karte

Hinweis: Für die Optimierung sind mindestens 2 Stopps mit gültigen Koordinaten erforderlich. Wenn die Geokodierung bei einigen Stopps fehlschlägt, wird die Route nur mit den erfolgreich geokodierten Stopps optimiert.

Zuverlässigkeit

Idempotenz

Fehlgeschlagene Requests sicher wiederholen, ohne doppelte Jobs zu erzeugen.

Füge Importanfragen einen Idempotency-Key mit einem eindeutigen Wert hinzu. Wird derselbe Schlüssel innerhalb von 24 Stunden erneut gesendet, liefert die API die zwischengespeicherte Antwort statt einen doppelten Job zu erstellen.

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

Best Practice: Verwende in Produktion immer einen Idempotency-Key. Nutze einen deterministischen Schlüssel, damit Netzwerk-Wiederholungen keine Duplikate erzeugen.

Referenz

Fehlerbehandlung

Alle Fehler liefern einen JSON-Body mit einem error-Feld zurück.

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

// oder bei Validierungsfehlern:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "messages": [
      "external_job_id is required",
      "stops[0].address is required"
    ]
  }
}
StatusBedeutungAktion
200ErfolgDie Anfrage wurde erfolgreich abgeschlossen
400Ungültige AnfragePrüfe die Fehlermeldungen und korrigiere den Request-Body
401Nicht autorisiertDein Token ist ungültig oder abgelaufen. Hole ein neues.
403VerbotenDeine Integration wurde deaktiviert. Wende dich an deinen Admin.
404Nicht gefundenDer Job oder der Endpunkt existiert nicht
405Methode nicht erlaubtVerwende die richtige HTTP-Methode (POST oder GET)
429Zu viele AnfragenWarte retry_after_seconds, bevor du es erneut versuchst
500ServerfehlerErneut mit exponentiellem Backoff versuchen. Bei anhaltenden Problemen Support kontaktieren.
Limits

Rate Limits

Rate Limits gelten pro Integration in einem rollierenden 1-Minuten-Fenster.

TarifAnfragen / MinuteMax. Stopps / Import
Team60200
EnterpriseCustomCustom

Bei Überschreitung des Limits gibt die API HTTP 429 mit dem Feld retry_after_seconds zurück.

Beispiele

Vollständige Codebeispiele

Kopierfertige Beispiele für gängige Sprachen. Alle zeigen den vollständigen Ablauf: authentifizieren, importieren und abfragen.

#!/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 .
Demnächst

Webhooks

Erhalte Benachrichtigungen in Echtzeit, wenn Lieferungen abgeschlossen werden.

Webhook-Unterstützung kommt bald. Du kannst dann eine URL registrieren und POST-Benachrichtigungen für Ereignisse wie diese erhalten:

  • job.completed — Alle Stopps eines Jobs wurden zugestellt
  • stop.completed — Ein einzelner Stopp wurde zugestellt (inklusive Zustellnachweis)
  • stop.failed — Ein Zustellversuch ist fehlgeschlagen
  • driver.location — GPS-Updates des Fahrers in Echtzeit

Interesse an Early Access? Kontaktiere uns.

Bereit zur Integration?

Erstelle deine Integrationszugangsdaten im RouteMate-Dashboard und beginne in wenigen Minuten mit dem Import von Jobs.