Keine Verbindung. Änderungen werden nicht gespeichert.
Wieder verbunden.

Entwickler

Drive Analytics API

Eine HTTP/JSON-REST-API für den programmatischen Zugriff auf deine eigenen Fahrzeug-, Fahrten-, Tank-, Wartungs-, Geofence- und Benachrichtigungsdaten. Authentifizierung über einen persönlichen API-Key. Jeder Aufruf ist strikt auf deinen Account beschränkt; geteilte Fahrzeuge siehst du lesend. Diese Seite ist die vollständige Referenz mit Beispiel-Requests, Beispiel-Antworten und einer Feld-Referenz.

Schnellstart

  1. In Einstellungen → API-Zugriff einen Key erstellen. Der Klartext wird einmalig angezeigt, kopiere ihn sofort.
  2. Den Key bei jeder Anfrage im Authorization-Header mitschicken.
  3. Loslegen, z. B. deine Fahrzeuge abrufen:
curl -H "Authorization: Bearer da_DEIN_KEY" \
     https://driveanalytics.uk/api/v1/cars

Antwort:

{
  "data": [
    {
      "id": 6,
      "license_plate": "M-AB-1234",
      "make": "Mercedes-Benz",
      "model": "C 220 d",
      "is_registered": true,
      "access": "owner",
      "current_mileage": 84210,
      "position": { "lat": 52.5163, "lon": 13.3777, "fuel_percent": 64,
                    "voltage_v": 12.7, "seen_at": "2026-06-25T09:12:00+00:00" }
    }
  ],
  "meta": { "count": 1 }
}

Authentifizierung

Jede Anfrage braucht deinen API-Key als Bearer-Token im Authorization-Header (alternativ der Header X-API-Key). Keys beginnen mit da_. Auf dem Server wird nur ein Hash gespeichert, der Klartext ist nach dem Erstellen nicht mehr abrufbar. Du kannst beliebig viele Keys mit eigenen Namen anlegen (max. 20 aktiv) und einzeln widerrufen, ein widerrufener Key wird sofort mit 401 abgelehnt.

Authorization: Bearer da_QMQvA2zPe8x1k...   # empfohlen
X-API-Key: da_QMQvA2zPe8x1k...               # Alternative
Behandle den Key wie ein Passwort. Er gewährt vollen Lese- und Schreibzugriff auf deine Daten. Nicht im Frontend/Client-Code oder in öffentlichen Repos ablegen.

Basis-URL & Version

Alle Endpunkte liegen unter https://driveanalytics.uk/api/v1. Die Versionsnummer im Pfad bleibt stabil; abwärtskompatible Ergänzungen (neue Felder/Endpunkte) kommen ohne Versionswechsel dazu. Alle Anfragen laufen ausschließlich über HTTPS.

Antwort-Format

Erfolg, Einzelobjekt:

{ "data": { "id": 6, ... } }

Erfolg, Liste (mit meta):

{ "data": [ { ... }, { ... } ], "meta": { "count": 2, "limit": 50, "offset": 0 } }
  • Zeitstempel: ISO 8601 mit Zeitzone (UTC), z. B. 2026-06-25T09:12:00+00:00.
  • Geldbeträge und Liter: Strings (volle Dezimal-Präzision), z. B. "46.43".
  • Distanzen (m/km), Koordinaten, Geschwindigkeiten, Zähler und Scores: Zahlen.
  • null bedeutet „nicht vorhanden / unbekannt".

Fehler

Fehler kommen als JSON mit passendem HTTP-Status:

{ "error": { "code": "forbidden", "message": "Nur der Besitzer kann Fahrten löschen." } }
StatuscodeBedeutung
400invalidUngültige Eingabe (z. B. fehlendes Feld)
401unauthorizedKein / ungültiger / widerrufener Key
403forbiddenKein Schreibrecht (z. B. geteiltes Fahrzeug)
404not_foundNicht gefunden oder kein Zugriff
409uncategorized_tripsExport bei unkategorisierten Fahrten
429rate_limitedZu viele Anfragen

Rate-Limits

120 Anfragen pro Minute je API-Key. Bei Überschreitung kommt 429 mit code: "rate_limited", warte dann kurz und wiederhole.

Paginierung & Filter

Listen unterstützen ?limit= (Standard 50, max. 200) und ?offset=. Fahrten und der Export akzeptieren zusätzlich einen Zeitraum über ?from=YYYY-MM-DD und ?to=YYYY-MM-DD.

# Zweite Seite à 25, nur Juni 2026
curl -H "Authorization: Bearer da_DEIN_KEY" \
  "https://driveanalytics.uk/api/v1/cars/6/trips?limit=25&offset=25&from=2026-06-01&to=2026-06-30"

Code-Beispiele

Dieselbe Anfrage (Fahrten eines Autos) in drei Sprachen:

cURL

curl -H "Authorization: Bearer $DA_KEY" \
  "https://driveanalytics.uk/api/v1/cars/6/trips?limit=10"

JavaScript (fetch)

const res = await fetch(
  "https://driveanalytics.uk/api/v1/cars/6/trips?limit=10",
  { headers: { Authorization: `Bearer ${process.env.DA_KEY}` } }
);
const { data, meta } = await res.json();
console.log(meta.count, data[0].distance_km);

Python (requests)

import os, requests
r = requests.get(
    "https://driveanalytics.uk/api/v1/cars/6/trips",
    params={"limit": 10},
    headers={"Authorization": f"Bearer {os.environ['DA_KEY']}"},
)
r.raise_for_status()
for trip in r.json()["data"]:
    print(trip["started_at"], trip["distance_km"], "km")

Objekt: Fahrzeug

Felder eines car-Objekts.

{
  "id": 6,                          // int, eindeutige Fahrzeug-ID
  "vin": "WVWZZZ1KZAW000000",       // string|null, Fahrgestellnummer
  "license_plate": "M-AB-1234",     // string|null
  "license_country": "D",           // string|null
  "make": "Mercedes-Benz",          // string|null, Marke
  "model": "C 220 d",               // string|null
  "first_registration": "2019-03-01", // date|null, Erstzulassung
  "body_class": "Limousine",        // string|null
  "is_registered": true,            // bool, aktiver Tracker?
  "access": "owner",                // "owner" | "manager" (Flotten-Verwalter) | "shared"
  "current_mileage": 84210,         // int|null, km
  "odometer_auto": true,            // bool, km automatisch via OBD?
  "mileage_updated_at": "2026-06-25T09:12:00+00:00",
  "manual_avg_fuel_l_per_100km": 7.5, // float|null, manueller Ø-Verbrauch
  "learned_avg_fuel_l_per_100km": 6.8, // float|null, gelernt aus Tankbelegen
  "estimated_avg_fuel_l_per_100km": 6.5, // float|null, typischer Modellwert
                                    // Leiter für estimated_cost_eur:
                                    // manuell > gelernt > typisch (gemessener
                                    // Trip-Verbrauch gewinnt immer)
  "position": {                     // object|null, letzte bekannte Position
    "lat": 52.5163, "lon": 13.3777,
    "fuel_percent": 64,             // int|null, Tankfüllstand in %. Aus fuel_liters
                                    // und tank_capacity_l, wo beides vorliegt,
                                    // sonst der Sensorwert des Fahrzeugs
    "fuel_liters": null,            // int|null, gemessener Resttank in L
    "tank_capacity_l": null,        // int|null, eingetragene Tankgröße in L
    "range_km": 540,                // int|null
    "voltage_v": 12.7,              // float|null, Bordspannung
    "dtc_codes": [],                // string[], Fehlercodes
    "seen_at": "2026-06-25T09:12:00+00:00",
                                    // Zeitstempel des jüngsten Datensatzes,
                                    // also wie aktuell die Position ist
    "moved_at": "2026-06-25T08:55:00+00:00",
    "packet_at": "2026-06-25T09:12:03+00:00",
                                    // datetime|null, wann das Paket bei uns
                                    // ankam. Puffert der Tracker im Funkloch und
                                    // liefert später nach, ist seen_at deutlich
                                    // älter als packet_at. Für „sendet das
                                    // Gerät?" ist packet_at maßgeblich.
    "moving": false,                // bool, fährt das Auto gerade?
    "speed_kmh": null               // int|null, aktuelle Geschwindigkeit
                                    // (nur während der Fahrt, sonst null)
  },
  "created_at": "2026-06-19T06:58:08+00:00"
}

Objekt: Fahrt

Die Übersicht (trip_summary); das Detail enthält zusätzlich route, speed_series, events, score_breakdown.

{
  "id": 42, "car_id": 6,
  "started_at": "2026-06-24T08:00:00+00:00",
  "ended_at": "2026-06-24T08:30:00+00:00",
  "duration_min": 30,
  "distance_m": 18230,
  "distance_km": 18.23,
  "top_speed_kmh": 121,
  "avg_fuel_l_per_100km": "6.4",    // string|null
  "estimated_cost_eur": "2.14",     // string|null, geschätzte Kraftstoffkosten
  "fuel_price_source": "Beleg 12.06.", // string|null, Basis der Schätzung; endet
                                    // auf "· Ø-Verbrauch" (manueller Wert),
                                    // "· Ø aus Tankbelegen" (gelernt) oder
                                    // "· typischer Verbrauch" (Modellwert),
                                    // wenn kein gemessener Trip-Verbrauch vorlag
  "category": "business",           // "private"|"business"|"commute"|null
  "purpose": "Kundentermin Müller", // string|null (nur bei business)
  "driver_id": 3,                   // int|null, Fahrer-Override (Geschäftskonto).
                                    // Abgeleiteter Fahrer aus einer Zuordnung
                                    // ist hier null; über /fleet/assignments
                                    // rekonstruierbar.
  "driving_score": 88,              // int|null, 0–100
  "event_count": 1,                 // Anzahl Ereignisse (harsh_brake, ...)
  "shared": false,
  "share_url": null                 // string|null, öffentlicher Link
}

Objekt: Tankrechnung

{
  "id": 3, "car_id": 6,
  "fueled_at": "2026-06-13T18:08:00+00:00",
  "liters": "46.43",                // string
  "price_per_liter": "1.899",       // string
  "total_amount": "88.17",          // string, in Originalwährung
  "discount_amount": null,          // string|null
  "currency": "EUR",
  "total_amount_eur": "88.17",      // string, in EUR umgerechnet
  "fx_rate": null, "fx_rate_date": null,
  "fuel_type": "diesel",            // e5|e10|super_plus|diesel|...
  "station_name": "Shell Berlin",
  "station_address": "...",
  "status": "confirmed",
  "owned": true,                    // false = geteiltes Fahrzeug (nur lesen)
  "image_url": "/api/v1/fuel-receipts/3/image"
}

Objekte: Wartung, Geofence, Mitteilung, Batterie

Wartungsposition

{ "id": 12, "kind": "oil_change", "name": "Motoröl",
  "interval_km": 10000, "interval_months": 12,
  "last_service_date": "2025-11-02", "last_service_mileage": 71200,
  "due_date": "2026-11-02", "due_km": 81200,
  "severity": "ok",                 // "ok"|"warn"|"danger"
  "notify_lead_times": ["1_month","1000_km"] }

Geofence-Zone

{ "id": 1, "name": "Zuhause", "lat": 52.5, "lon": 13.4,
  "radius_m": 150, "notify_enter": true, "notify_leave": true, "enabled": true }

Mitteilung

{ "id": 87, "type": "theft", "priority": "critical",
  "title": "Manipulationsversuch", "body": "...", "car_id": 6,
  "deeplink_url": "/cars/6", "read": false, "read_at": null,
  "created_at": "2026-06-24T18:30:00+00:00" }

Batterie-Gesundheit

{ "status": "good",               // good|watch|critical|no_data
  "label": "Gut", "resting_v": 12.7, "crank_min_v": 11.1,
  "charge_max_v": 14.9, "charging_ok": true,
  "trend": "stable", "days": 14, "note": "Batterie in gutem Zustand.",
  "spark": [12.6, 12.7, 12.7] }

Endpunkte · Konto

GET /api/v1

Discovery-Index der Sammlungen.

GET /api/v1/me

Eigenes Konto-Profil (Name, E-Mail, Sprache, Zeitzone).

Endpunkte · Fahrzeuge

GET /api/v1/cars

Liste aller zugänglichen Fahrzeuge (eigene + geteilte).

GET /api/v1/cars/{id}

Einzelnes Fahrzeug inkl. Live-Position.

GET /api/v1/cars/{id}/battery

Batterie-Gesundheit (siehe Objekt oben).

GET /api/v1/cars/{id}/trips

Fahrten des Fahrzeugs. Query: limit, offset, from, to, q (Textsuche im Fahrt-Zweck).

GET /api/v1/cars/{id}/fuel-receipts

Tankrechnungen des Fahrzeugs.

GET /api/v1/cars/{id}/fuel-stats

Aggregierte Tank-Kennzahlen (Ø/Monat, YTD, Ø Preis/Liter).

GET /api/v1/cars/{id}/maintenance

Wartungspositionen mit Fälligkeit (siehe Objekt).

POST /api/v1/cars/{id}/maintenance/{item_id}/done

Wartung quittieren. Besitzer oder Flotten-Verwalter. Mit „cost“ entsteht zugleich eine Kostenposition.

Request-Body (JSON)

{ "date": "2026-06-25", "mileage": 84210, "cost": "189,90", "currency": "EUR" }   // alle optional

Endpunkte · Fahrten

GET /api/v1/trips/{id}

Fahrt-Detail inkl. Route, Speed-Profil, Ereignissen.

GET /api/v1/trips/{id}/export.gpx

Fahrt als GPX herunterladen (auch .kml). Route wird als Track exportiert.

PATCH /api/v1/trips/{id}

Kategorie/Zweck und/oder Fahrer-Override setzen. driver_id nur im Geschäftskonto; null löscht den Override.

Request-Body (JSON)

{ "category": "business", "purpose": "Kundentermin Müller", "driver_id": 3 }
POST /api/v1/trips/category-bulk

Sammel-Kategorisierung mehrerer Fahrten in einem Schritt (bis 200). Alles-oder-nichts: eine fremde Kennung lässt die ganze Anfrage scheitern (404).

Request-Body (JSON)

{ "ids": [12, 15, 18], "category": "business" }
DELETE /api/v1/trips/{id}

Fahrt löschen. Nur Besitzer.

POST /api/v1/trips/{id}/share

Öffentlichen, widerrufbaren Link erzeugen.

Beispiel-Antwort

{ "data": { "share_url": "https://driveanalytics.uk/t/AbC123", "token": "AbC123" } }
DELETE /api/v1/trips/{id}/share

Teilen wieder aufheben.

Endpunkte · Tankrechnungen

GET /api/v1/fuel-receipts

Alle Tankrechnungen über deine Fahrzeuge.

GET /api/v1/fuel-receipts/{id}

Einzelne Tankrechnung.

GET /api/v1/fuel-receipts/{id}/image

Belegfoto als JPEG (kein JSON).

DELETE /api/v1/fuel-receipts/{id}

Tankrechnung löschen. Nur Besitzer.

Endpunkte · Kosten

Kraftstoff kommt aus den Tankrechnungen und wird nicht über diese Endpunkte erfasst. Laufende Kosten (Versicherung, Steuer) werden anteilig auf den Zeitraum umgelegt, nicht als Einmalzahlung gezählt. km_source sagt, worauf die Kilometer beruhen: odometer (Tachostand) oder trips (nur aufgezeichnete Fahrten, Wert je Kilometer fällt dann eher zu hoch aus).

GET /api/v1/costs/overview

Kontoweite Kosten-Übersicht: alle Kostenarten (Monatsverlauf über 12 Monate, by_kind, Fahrzeug-Vergleich, cost_per_km_eur) plus geschätzte Aufteilung nach Fahrtzweck (category_split_estimated). Beträge als String, Währung EUR.

GET /api/v1/cars/{id}/costs

Kosten eines Fahrzeugs: Summe, Aufteilung nach Kostenart, Kosten je Kilometer, Einzelposten und laufende Positionen. Query: from, to (Standard letzte 12 Monate).

POST /api/v1/cars/{id}/costs

Einmalkosten erfassen. Nur Besitzer. kind: maintenance, repair, tires, inspection, insurance, tax, purchase, other. occurred_on nicht in der Zukunft, Standard heute.

Request-Body (JSON)

{ "kind": "repair", "amount": "249,90", "currency": "EUR",
  "occurred_on": "2026-07-14", "mileage": 84210, "note": "Bremsen vorne" }
DELETE /api/v1/cars/{id}/costs/{cost_id}

Kostenposition löschen. Nur Besitzer. Aus einer Wartung erzeugte Positionen verlieren dabei auch den Betrag an der Wartung.

POST /api/v1/cars/{id}/recurring-costs

Laufende Kosten anlegen. Nur Besitzer. kind: insurance, tax, parking, leasing, other. period: monthly, quarterly, yearly. ends_on leer = läuft weiter.

Request-Body (JSON)

{ "kind": "insurance", "amount": "480,00", "period": "yearly",
  "starts_on": "2026-01-01", "note": "Haftpflicht plus Teilkasko" }
DELETE /api/v1/cars/{id}/recurring-costs/{rec_id}

Laufende Kosten löschen. Nur Besitzer.

Endpunkte · Flotte

Nur für Geschäftskonten. Andere Konten erhalten 403.

GET /api/v1/fleet/drivers

Fahrer-Stammliste.

POST /api/v1/fleet/drivers

Fahrer anlegen.

Request-Body (JSON)

{ "name": "Max Mustermann", "email": "[email protected]" }
PATCH /api/v1/fleet/drivers/{id}

Fahrer ändern (name, email, active).

Request-Body (JSON)

{ "active": false }
DELETE /api/v1/fleet/drivers/{id}

Fahrer löschen. Zuordnungen entfallen, Fahrt-Overrides werden auf leer gesetzt.

GET /api/v1/fleet/assignments

Fahrer-Fahrzeug-Zuordnungen.

POST /api/v1/fleet/assignments

Zuordnung anlegen (überlappungsfrei je Fahrzeug). ends_on optional.

Request-Body (JSON)

{ "driver_id": 3, "car_id": 7, "starts_on": "2026-07-01", "ends_on": "2026-07-31" }
DELETE /api/v1/fleet/assignments/{id}

Zuordnung entfernen.

GET /api/v1/fleet/report

Monatsbericht je Fahrer und Fahrzeug (km, Fahrten, geschätzte Kosten) plus vehicle_costs: fahrzeuggebundene Kosten des Monats, die bewusst NICHT auf Fahrer verteilt werden. Query: year, month (Standard voriger Monat).

Endpunkte · Wartung

Siehe Fahrzeuge: GET /cars/{id}/maintenance und POST /cars/{id}/maintenance/{item_id}/done.

Endpunkte · Geofence-Zonen

GET /api/v1/geofences

Alle eigenen Zonen. Jede Zone trägt active_start_min/active_end_min (Minuten seit lokaler Mitternacht, null = ganztägig) und car_ids (leer = alle Fahrzeuge).

POST /api/v1/geofences

Zone anlegen. radius_m optional (Standard 200). active_start_min/active_end_min setzen ein Zeitfenster (z. B. 1320/360 = 22:00 bis 06:00), car_ids beschränkt auf Fahrzeuge.

Request-Body (JSON)

{ "name": "Zuhause", "lat": 52.5, "lon": 13.4, "radius_m": 150,
  "notify_enter": true, "notify_leave": true,
  "active_start_min": 1320, "active_end_min": 360, "car_ids": [7] }
PATCH /api/v1/geofences/{id}

Zone ändern. active_start_min/active_end_min auf gleich oder ungültig setzen = wieder ganztägig; car_ids: [] = wieder alle Fahrzeuge.

Request-Body (JSON)

{ "enabled": false, "active_start_min": 1320, "active_end_min": 360 }
DELETE /api/v1/geofences/{id}

Zone löschen. Entfernt auch den gesamten Verlauf dieser Zone.

GET /api/v1/geofences/{id}/events

Verlauf der Ein- und Austritte, neueste zuerst. direction ist "enter" oder "leave". notified sagt, ob eine Benachrichtigung entstanden ist: außerhalb des Zeitfensters einer Zone wird der Übergang aufgezeichnet, aber nicht gemeldet. limit (Standard 50, max. 200) und offset blättern, meta.total nennt die Gesamtzahl.

GET /api/v1/webhooks

Alle eigenen Webhook-Ziele. Das Geheimnis steht NICHT in der Liste, es wird nur beim Anlegen einmal ausgegeben.

POST /api/v1/webhooks

Ziel anlegen. Die Adresse muss https sein und oeffentlich aufloesen; interne Adressen werden abgelehnt. Moegliche Ereignisse: trip.completed, zone.entered, zone.left, alert.raised. Die Antwort enthaelt das Geheimnis genau einmal.

Request-Body (JSON)

{ "label": "Mein System", "url": "https://example.com/hook",
  "events": ["zone.entered", "zone.left"] }
DELETE /api/v1/webhooks/{id}

Ziel widerrufen. Bereits eingereihte Zustellungen werden nicht mehr versucht.

GET /api/v1/cars/{id}/zone-events

Verlauf eines Fahrzeugs über alle eigenen Zonen hinweg. Nur für eigene Fahrzeuge: die Zone ist eine Einstellung ihres Besitzers, ihr Verlauf gibt dessen Orte preis. Für ein lediglich freigegebenes Fahrzeug antwortet der Endpunkt mit 404.

Endpunkte · Benachrichtigungen

GET /api/v1/notifications

Mitteilungen (paginiert). Query: ?unread=1 für nur ungelesene. meta.unread enthält die Gesamtzahl.

GET /api/v1/notifications/unread-count

Anzahl ungelesener Mitteilungen.

POST /api/v1/notifications/{id}/read

Eine Mitteilung als gelesen markieren.

POST /api/v1/notifications/read-all

Alle als gelesen markieren.

Endpunkte · Fahrtenbuch-Export

GET /api/v1/logbook/export

Fahrtenbuch als Datei. Query: format=pdf|csv|xlsx, from, to, car_id (optional). Liefert die Datei direkt (kein JSON).

Gibt es im Zeitraum unkategorisierte Fahrten, kommt 409 uncategorized_trips — setze zuerst überall eine Kategorie via PATCH /api/v1/trips/{id}.

curl -L -H "Authorization: Bearer $DA_KEY" \
  "https://driveanalytics.uk/api/v1/logbook/export?format=pdf&from=2026-01-01&to=2026-03-31" \
  -o fahrtenbuch.pdf

API v1 · Diese Referenz wächst mit dem Produkt mit. Fehlt dir eine Funktion? Schreib uns.