Lesen Sie Positionen, Fahrzeugdaten, Fahrten, Fehlercodes und Berichte Ihrer Flotte, und richten Sie ihre Fahrzeuge, Fahrer, Geofences und Warnregeln ein, aus Ihren eigenen Skripten und Produkten. Einfaches JSON über HTTPS, mit einem Schlüssel, den Sie selbst erstellen.
Öffnen Sie im Panel Verwaltung, dann API-Schlüssel, und erstellen Sie einen Schlüssel. Wählen Sie, was er lesen darf, was er ändern darf und wann er aufhört zu funktionieren. Sein Geheimnis erscheint nur einmal, bewahren Sie es sicher auf.
import json
import os
import urllib.request
request = urllib.request.Request(
"https://trackingen.com/api/v1/vehicles",
headers={
"Authorization": f"Bearer {os.environ['TRACKINGEN_API_KEY']}",
},
)
with urllib.request.urlopen(request, timeout=30) as answer:
print(json.load(answer)["data"])
Anfrage · JavaScript
const answer = await fetch(
"https://trackingen.com/api/v1/vehicles",
{
headers: {
Authorization: `Bearer ${process.env.TRACKINGEN_API_KEY}`,
},
},
);
if (!answer.ok) {
throw new Error(`The API answered ${answer.status}`);
}
const { data } = await answer.json();
console.log(data);
Ein Schlüssel funktioniert, solange Ihre Organisation das API-Paket hat. Fragen Sie es auf der Seite Paket an.
Die ganze Referenz gibt es auch als OpenAPI-3.1-Dokument, das Ihre Werkzeuge lesen und aus dem sie einen Client erzeugen können.openapi.json öffnen
Antworten, Seiten und Ablehnungen
Jede Antwort ist ein JSON-Objekt mit dem Ergebnis in data.
200
{ "data": … }
Eine Liste kommt in Seiten und endet (keyset pagination): Jede Seite hat page.next, einen Cursor, den Sie unverändert zurückschicken und nie selbst bauen oder lesen (opaque cursor), und für die nächste Seite fragen Sie erneut mit after gleich diesem Wert. Auf der letzten Seite ist page.next null, und die Liste ist zu Ende. limit sagt, wie viele höchstens auf einer Seite kommen.
Eine Kopie endet nie: Sie gibt, was nach ihrem Cursor empfangen wurde, in der Reihenfolge des Empfangs und sobald es eine Minute alt ist, sodass keine verspätete Meldung übersprungen wird. page.next ist immer die Stelle, an der es weitergeht; senden Sie es beim nächsten Mal als after, auch wenn die Seite leer war. page.more sagt, ob Sie sofort erneut fragen: true, solange noch mehr wartet, false, sobald Sie auf dem neuesten Stand sind; dann fragen Sie eine Minute oder später wieder. Ohne after beginnt eine Kopie 14 Tage zurück. Mit from an einem Moment der letzten 14 Tage zu beginnen, zählt gegen nichts; weiter zurück, innerhalb Ihrer aufbewahrten Daten, zählt es gegen 5 Starts am Tag für jeden Schlüssel und jede Person, beide Kopien zusammen. Ein Eintrag kann mehr als einmal kommen (at-least-once delivery), mit mehr Inhalt, also speichern Sie jeden nach deviceId und recordedAt.
Eine Ablehnung hat ihren HTTP-Status und einen error mit einem gleichbleibenden Code, einer Nachricht für Menschen und bei manchen Codes details.
404
{
"error": {
"code": "NOT_FOUND",
"message": "No such vehicle"
}
}
Jeder Moment ist in UTC und in ISO 8601 geschrieben, etwa 2026-11-04T08:00:00.000Z.
Jede Route hat ihre Grenze (rate limiting): Eine Route zählt Ihre Anfragen in einem Zeitfenster, eine Kopie zählt stattdessen die Einträge, die sie durchgeht. Über der Grenze antwortet eine Route mit 429 und Retry-After, den Sekunden bis zum nächsten Versuch.
Eine Route, die etwas ändert, nimmt ihren Inhalt als JSON, gesendet mit Content-Type: application/json. Eine Route, die etwas anlegt, antwortet mit 201 und dem Angelegten und nimmt einen Header Idempotency-Key aus 8 bis 64 Buchstaben, Ziffern, Binde- oder Unterstrichen: Geht eine Antwort verloren, senden Sie dieselbe Anfrage mit demselben Schlüssel, und einen Tag lang erhalten Sie die erste Antwort zurück, markiert mit Idempotent-Replayed: true, statt eines zweiten Eintrags. Derselbe Schlüssel mit einem anderen Inhalt antwortet IDEMPOTENCY_KEY_REUSED. Eine Änderung setzt die Felder, die sie nennt, auf das Gesendete, also ändert ein erneutes Senden nichts weiter, und ein Löschen antwortet 204, danach 404, sobald der Eintrag weg ist. Jede Änderung zählt gegen ihre eigene Grenze für jeden Schlüssel und jede Person.
Version 1 hält ihr Wort: Eine Antwort kann Felder dazubekommen und eine Werteliste wachsen, aber nichts wird umbenannt oder entfernt. Überspringen Sie, was Sie nicht kennen, ein Feld ebenso wie einen Feed-Eintrag einer Art, die Sie noch nicht gesehen haben.
Routen
Fahrzeuge und Positionen
Ihre Fahrzeuge, wo jedes gerade ist, seine Spur in einem Zeitraum, eine Kopie jeder Position, sobald sie eintrifft, und die Tracker, die es hatte.
GET/api/v1/vehicles
Ihre Fahrzeuge
Ihre Fahrzeuge, jedes mit dem eingebauten Tracker, ob dieser Tracker das Fahrzeugkit hat, und mit der Hardware, die Ihr Paket noch braucht
Berechtigungen
vehicle:readFahrzeuge sehen
Paket
Jedes Paket
Anfragegrenze
120 Anfragen pro Minute
Parameter
limitAbfrageinteger
Wie viele höchstens auf einer Seite kommen
1 bis 100Standard 50
afterAbfragestring
Das page.next der vorigen Seite, um die nächste Seite abzufragen; senden Sie es, wie es kam (opaque cursor)
Gibt einem Fahrzeug eine eigene Bezeichnung oder nimmt sie weg; Kennzeichen, FIN und Tracker bleiben, wie die Plattform sie führt. Antwortet mit dem Fahrzeug, wie Ihre Fahrzeugliste es gibt, und der Feed nennt die Änderung vehicle-changed.
Berechtigungen
vehicle:labelFahrzeugbezeichnung ändern
vehicle:readFahrzeuge sehen
Paket
Jedes Paket
Anfragegrenze
60 Anfragen pro Minute
Parameter
vehicleIdPfaduuidPflicht
Die ID des Fahrzeugs, aus Ihrer Fahrzeugliste
labelInhaltstringPflicht
Ein Name, den Ihre Organisation dem Fahrzeug gibt, einfacher Text; null, um ihn wegzunehmen
Die Positionen jedes Fahrzeugs in der Reihenfolge ihres Empfangs, ab dem Ende Ihrer letzten Seite, sobald sie eine Minute alt sind
Berechtigungen
position:readPositionen sehen
Paket
Jedes Paket
Anfragegrenze
120.000 Einträge pro Minute
Parameter
afterAbfragestring
Das page.next der vorigen Seite, um dort weiterzumachen, wo sie endete
fromAbfragedate-time
Stattdessen hier eine neue Kopie beginnen. Innerhalb der letzten 14 Tage zählt das gegen nichts; weiter zurück, innerhalb Ihrer aufbewahrten Daten, zählt es gegen 5 Starts am Tag für jeden Schlüssel und jede Person
Was der Tracker zuletzt über sich meldete: sein Mobilfunksignal, die Versorgung aus dem Fahrzeug, seine Satellitenposition und wie lange er schon läuft. Jedes Feld ist null, bis er zum ersten Mal meldet
Fügt einen Fahrer hinzu, von Anfang an aktiv, dem Ihre Touren gegeben werden können
Berechtigungen
driver:createFahrer hinzufügen
Paket
Tourenplanung
Anfragegrenze
60 Anfragen pro Minute
Parameter
Idempotency-KeyHeaderstring
Ihr eigener Schlüssel für diese Anfrage, 8 bis 64 Buchstaben, Ziffern, Binde- oder Unterstriche. Senden Sie denselben Schlüssel, wenn Sie die Anfrage nach einer verlorenen Antwort erneut senden, dann kommt die erste Antwort zurück statt eines zweiten Eintrags
nameInhaltstringPflicht
Der volle Name des Fahrers, einfacher Text
phoneInhaltstring
Eine Telefonnummer mit 7 bis 15 Ziffern, mit + und Ländervorwahl davor oder ohne; Leerzeichen, Klammern, Punkte und Bindestriche fallen weg. null für keine
licenseNumberInhaltstring
Die Führerscheinnummer, in Großbuchstaben gespeichert; null für keine
userIdInhaltuuid
Die ID des Kontos, mit dem sich der Fahrer anmeldet, um seine Touren zu sehen. Nur eine angemeldete Person verknüpft ein Konto oder löst es: Ein Schlüssel lässt das Feld weg oder sendet es unverändert, sonst erhält er PERSON_REQUIRED
Ändert die gesendeten Felder und behält den Rest. Ein inaktiver Fahrer bekommt keine neuen Touren, und sein Konto sieht seine Touren nicht mehr.
Berechtigungen
driver:updateFahrer bearbeiten
driver:readFahrer sehen
Paket
Tourenplanung
Anfragegrenze
60 Anfragen pro Minute
Parameter
driverIdPfaduuidPflicht
Die ID des Fahrers, aus Ihren Fahrern
nameInhaltstring
Der volle Name des Fahrers, einfacher Text
phoneInhaltstring
Eine Telefonnummer mit 7 bis 15 Ziffern, mit + und Ländervorwahl davor oder ohne; Leerzeichen, Klammern, Punkte und Bindestriche fallen weg. null für keine
licenseNumberInhaltstring
Die Führerscheinnummer, in Großbuchstaben gespeichert; null für keine
statusInhaltstring
active oder inactive. Bei einem mit einem Konto verknüpften Fahrer ändert ihn nur eine angemeldete Person, denn er entscheidet, was das Konto sieht: Ein Schlüssel erhält PERSON_REQUIRED
activeinactive
userIdInhaltuuid
Die ID des Kontos, mit dem sich der Fahrer anmeldet, um seine Touren zu sehen. Nur eine angemeldete Person verknüpft ein Konto oder löst es: Ein Schlüssel lässt das Feld weg oder sendet es unverändert, sonst erhält er PERSON_REQUIRED
Jedes Signal, das der Tracker eines Fahrzeugs liest: sein Name, seine Bezeichnungen in jeder Sprache, seine Art und bei einer Zahl Einheit und Nachkommastellen, bei einem Zustand dessen Werte
Die Messwerte jedes Fahrzeugs in der Reihenfolge ihres Empfangs, ab dem Ende Ihrer letzten Seite, sobald sie eine Minute alt sind. Jede Zeile, die eine Seite durchgeht, zählt zur Grenze, auch eine, die wegfällt, weil sie keines Ihrer Signale enthält.
Berechtigungen
vehicle:readFahrzeuge sehen
position:readPositionen sehen
Paket
Fahrzeugdaten
Anfragegrenze
120.000 Einträge pro Minute
Parameter
afterAbfragestring
Das page.next der vorigen Seite, um dort weiterzumachen, wo sie endete
fromAbfragedate-time
Stattdessen hier eine neue Kopie beginnen. Innerhalb der letzten 14 Tage zählt das gegen nichts; weiter zurück, innerhalb Ihrer aufbewahrten Daten, zählt es gegen 5 Starts am Tag für jeden Schlüssel und jede Person
limitAbfrageinteger
Wie viele höchstens auf einer Seite kommen
1 bis 1000Standard 1000
signalsAbfragearray
Nur diese Signale, durch Kommas getrennt, höchstens 32, mit den Namen aus der Signalliste eines Fahrzeugs
Jedes Steuergerät, dessen Seriennummer sich an derselben Adresse desselben Fahrzeugs änderte, die neuesten zuerst, mit der Seriennummer davor und danach, wie das Steuergerät sie nannte, hexadezimal
Berechtigungen
vehicle:readFahrzeuge sehen
position:readPositionen sehen
Paket
Fahrzeugdaten
Anfragegrenze
120 Anfragen pro Minute
Parameter
limitAbfrageinteger
Wie viele höchstens auf einer Seite kommen
1 bis 100Standard 50
afterAbfragestring
Das page.next der vorigen Seite, um die nächste Seite abzufragen; senden Sie es, wie es kam (opaque cursor)
vehicleIdAbfrageuuid
Nur die getauschten Steuergeräte dieses Fahrzeugs, nach seiner ID
Die Kraftstoff- und AdBlue-Tanks jedes Fahrzeugs und die Verluste und Tankvorgänge, die die Plattform darin erkennt. Sie kommen mit dem Paket Kraftstoffüberwachung.
GET/api/v1/vehicles/{vehicleId}/fuel-tanks
Die Tanks eines Fahrzeugs
Der Kraftstoff- und der AdBlue-Tank des Fahrzeugs, jeder mit seiner Größe, wo die Plattform sie kennt, und ob das Fahrzeug seinen Füllstand liefert
Berechtigungen
fuel:readKraftstoffverluste und Tankvorgänge sehen
Jeder Verlust und jeder Tankvorgang, den die Plattform in einem Tank erkannte, die neuesten zuerst, mit dem Füllstand davor und danach und wie viele Liter das sind
Berechtigungen
fuel:readKraftstoffverluste und Tankvorgänge sehen
Paket
Kraftstoffüberwachung
Anfragegrenze
120 Anfragen pro Minute
Parameter
limitAbfrageinteger
Wie viele höchstens auf einer Seite kommen
1 bis 100Standard 50
afterAbfragestring
Das page.next der vorigen Seite, um die nächste Seite abzufragen; senden Sie es, wie es kam (ein undurchsichtiger Cursor)
vehicleIdAbfrageuuid
Nur die Verluste und Tankvorgänge dieses Fahrzeugs, nach seiner ID
Ein Verlust oder Tankvorgang, wie die Liste ihn gibt, mit dem Ort, an dem das Fahrzeug stand, als der Füllstand davor gelesen wurde; ein Schlüssel ohne position:read sieht ihn nicht
Berechtigungen
fuel:readKraftstoffverluste und Tankvorgänge sehen
Paket
Kraftstoffüberwachung
Anfragegrenze
120 Anfragen pro Minute
Parameter
eventIdPfaduuidPflicht
Die ID des Verlusts oder Tankvorgangs, aus der Liste
Die starken Beschleunigungen und das starke Bremsen eines Fahrzeugs von einem Moment zum anderen, höchstens 32 Tage, die ältesten zuerst: wann jedes am stärksten war, wie stark in m/s², bei welcher Geschwindigkeit es begann und endete und, wenn bekannt, wo es geschah. Es kommen nur Manöver, die mindestens so stark sind wie die Schwellen, mit denen die harten Manöver einer Fahrt gezählt werden.
Die Orte, die Sie auf der Karte zeichnen, deren Ein- und Ausfahrten der Feed nennt, wie viele Sie haben dürfen und die Aufenthalte jedes Fahrzeugs darin.
GET/api/v1/geofences
Ihre Geofences
Ihre Geofences, jedes mit seiner Form, was es meldet und wie viele Fahrzeuge darin sind
Berechtigungen
geofence:readGeofences sehen; Aufenthalte und ihre Meldungen brauchen auch Positionen sehen
Paket
Geofences
Anfragegrenze
120 Anfragen pro Minute
Parameter
limitAbfrageinteger
Wie viele höchstens auf einer Seite kommen
1 bis 100Standard 50
afterAbfragestring
Das page.next der vorigen Seite, um die nächste Seite abzufragen; senden Sie es, wie es kam (ein undurchsichtiger Cursor)
Zeichnet ein Geofence; hinein- und hinausfahrende Fahrzeuge werden von da an beurteilt. Geofences zeichnen, ändern und entfernen zählt außerdem zusammen gegen 60 pro Minute für Ihre ganze Organisation.
Berechtigungen
geofence:configureGeofences zeichnen und ändern
Paket
Geofences
Anfragegrenze
60 Anfragen pro Minute
Parameter
Idempotency-KeyHeaderstring
Ihr eigener Schlüssel für diese Anfrage, 8 bis 64 Buchstaben, Ziffern, Binde- oder Unterstriche. Senden Sie denselben Schlüssel, wenn Sie die Anfrage nach einer verlorenen Antwort erneut senden, dann kommt die erste Antwort zurück statt eines zweiten Eintrags
nameInhaltstringPflicht
Ein Name für das Geofence, einfacher Text, eindeutig unter Ihren Geofences ohne Rücksicht auf Groß- und Kleinschreibung
shapeInhaltobjectPflicht
Ein Kreis, {kind: circle, center, radiusMeters}, oder ein Vieleck, {kind: polygon, corners}, jeder Ort {latitude, longitude} in Grad. Die Route der Geofence-Grenzen sagt, wie viele Ecken und welchen Radius Sie zeichnen dürfen
tellEntriesInhaltboolean
Ob ein hineinfahrendes Fahrzeug gemeldet wird, Ihren Leuten als Benachrichtigung und im Feed als geofence-entered; true, wenn es bei einem neuen Geofence fehlt
tellExitsInhaltboolean
Ob ein hinausfahrendes Fahrzeug gemeldet wird, als Benachrichtigung und im Feed als geofence-left; true, wenn es bei einem neuen Geofence fehlt
Ändert die gesendeten Felder und behält den Rest. Eine neue Form wird ab dem Moment beurteilt, in dem sie gezeichnet wird. Geofences zeichnen, ändern und entfernen zählt außerdem zusammen gegen 60 pro Minute für Ihre ganze Organisation.
Berechtigungen
geofence:configureGeofences zeichnen und ändern
geofence:readGeofences sehen; Aufenthalte und ihre Meldungen brauchen auch Positionen sehen
Paket
Geofences
Anfragegrenze
60 Anfragen pro Minute
Parameter
geofenceIdPfaduuidPflicht
Die ID des Geofence, aus Ihren Geofences
nameInhaltstring
Ein Name für das Geofence, einfacher Text, eindeutig unter Ihren Geofences ohne Rücksicht auf Groß- und Kleinschreibung
shapeInhaltobject
Ein Kreis, {kind: circle, center, radiusMeters}, oder ein Vieleck, {kind: polygon, corners}, jeder Ort {latitude, longitude} in Grad. Die Route der Geofence-Grenzen sagt, wie viele Ecken und welchen Radius Sie zeichnen dürfen
tellEntriesInhaltboolean
Ob ein hineinfahrendes Fahrzeug gemeldet wird, Ihren Leuten als Benachrichtigung und im Feed als geofence-entered; true, wenn es bei einem neuen Geofence fehlt
tellExitsInhaltboolean
Ob ein hinausfahrendes Fahrzeug gemeldet wird, als Benachrichtigung und im Feed als geofence-left; true, wenn es bei einem neuen Geofence fehlt
Entfernt ein Geofence: Fahrzeuge darin werden nicht mehr beurteilt, ihre Aufenthalte enden ohne Meldung, und seine Aufenthalte bleiben in ihrer Geschichte. Geofences zeichnen, ändern und entfernen zählt außerdem zusammen gegen 60 pro Minute für Ihre ganze Organisation.
Jede Zeit, in der ein Fahrzeug in einem Geofence war, von der Einfahrt bis zur Ausfahrt, die neuesten zuerst; ein Aufenthalt, der noch andauert, hat kein Ende
Berechtigungen
geofence:readGeofences sehen; Aufenthalte und ihre Meldungen brauchen auch Positionen sehen
position:readPositionen sehen
Paket
Geofences
Anfragegrenze
120 Anfragen pro Minute
Parameter
limitAbfrageinteger
Wie viele höchstens auf einer Seite kommen
1 bis 100Standard 50
afterAbfragestring
Das page.next der vorigen Seite, um die nächste Seite abzufragen; senden Sie es, wie es kam (ein undurchsichtiger Cursor)
vehicleIdAbfrageuuid
Nur die Aufenthalte dieses Fahrzeugs, nach seiner ID
geofenceIdAbfrageuuid
Nur die Aufenthalte in diesem Geofence, nach seiner ID
Die Regeln, die warnen, wenn ein Messwert eines Fahrzeugs eine Schwelle überschreitet, die Signale, die eine Regel beobachten darf, und die ausgelösten Warnungen.
GET/api/v1/alert-rules
Ihre Warnregeln
Ihre Warnregeln, an und aus, und jedes Signal, das eine Regel beobachten darf, mit den Schwellen, die es nimmt, und ob Ihr Paket eine Regel darauf jetzt zulässt
Fügt eine Regel hinzu, von Anfang an an: Ein Fahrzeug, dessen Signal für die Haltezeit jenseits der Schwelle bleibt, löst eine Warnung aus, Ihren Leuten gemeldet und im Feed als vehicle-alert. Warnregeln hinzufügen und ändern zählt außerdem zusammen gegen 100 pro Tag für Ihre ganze Organisation.
Berechtigungen
alert:configureWarnregeln festlegen
Paket
Jedes Paket
Anfragegrenze
60 Anfragen pro Minute
Parameter
Idempotency-KeyHeaderstring
Ihr eigener Schlüssel für diese Anfrage, 8 bis 64 Buchstaben, Ziffern, Binde- oder Unterstriche. Senden Sie denselben Schlüssel, wenn Sie die Anfrage nach einer verlorenen Antwort erneut senden, dann kommt die erste Antwort zurück statt eines zweiten Eintrags
nameInhaltstringPflicht
Ein Name für die Regel, einfacher Text, mit jeder Warnung gezeigt
signalInhaltstringPflicht
Das Signal, das die Regel beobachtet: eines der Signale, die die Liste der Warnregeln nennt, oder battery-low
comparisonInhaltstringPflicht
above oder below: auf welcher Seite der Schwelle gewarnt wird
abovebelow
thresholdInhaltstringPflicht
Der Wert, den das Signal überschreiten muss, in seinem Bereich und seinen Schritten, wie die Liste der Warnregeln sie nennt; null für battery-low, dessen Schwelle die Plattform setzt
holdSecondsInhaltintegerPflicht
Wie viele ganze Sekunden das Signal jenseits der Schwelle bleibt, bevor gewarnt wird; 0 warnt sofort
Ändert die gesendeten Felder, behält den Rest und schaltet die Regel an oder aus. Warnregeln hinzufügen und ändern zählt außerdem zusammen gegen 100 pro Tag für Ihre ganze Organisation.
Berechtigungen
alert:configureWarnregeln festlegen
alert:readWarnungen sehen
Paket
Jedes Paket
Anfragegrenze
60 Anfragen pro Minute
Parameter
ruleIdPfaduuidPflicht
Die ID der Regel, aus Ihren Warnregeln
nameInhaltstring
Ein Name für die Regel, einfacher Text, mit jeder Warnung gezeigt
signalInhaltstring
Das Signal, das die Regel beobachtet: eines der Signale, die die Liste der Warnregeln nennt, oder battery-low
comparisonInhaltstring
above oder below: auf welcher Seite der Schwelle gewarnt wird
abovebelow
thresholdInhaltstring
Der Wert, den das Signal überschreiten muss, in seinem Bereich und seinen Schritten, wie die Liste der Warnregeln sie nennt; null für battery-low, dessen Schwelle die Plattform setzt
holdSecondsInhaltinteger
Wie viele ganze Sekunden das Signal jenseits der Schwelle bleibt, bevor gewarnt wird; 0 warnt sofort
0 bis 3600
onInhaltboolean
Ob die Regel warnt; sind so viele Regeln an, wie gleichzeitig an sein dürfen, antwortet das Anschalten ALERT_RULE_LIMIT
Jedes Mal, wenn ein Messwert eines Fahrzeugs die Schwelle einer Warnregel überschritt, die neuesten zuerst, mit wie weit und wie lange, und wo es begann, für einen Schlüssel mit position:read
Berechtigungen
alert:readWarnungen sehen
Paket
Jedes Paket
Anfragegrenze
120 Anfragen pro Minute
Parameter
limitAbfrageinteger
Wie viele höchstens auf einer Seite kommen
1 bis 100Standard 50
afterAbfragestring
Das page.next der vorigen Seite, um die nächste Seite abzufragen; senden Sie es, wie es kam (ein undurchsichtiger Cursor)
vehicleIdAbfrageuuid
Nur die Warnungen dieses Fahrzeugs, nach seiner ID
Was in Ihrer Flotte geschah und was sich an Ihren Fahrzeugen, Geräten und Ihrem Paket änderte, in einer Reihenfolge.
GET/api/v1/feed
Der Feed
Was in Ihrer Flotte geschah, in der Reihenfolge, in der es geschrieben wurde, ab dem Ende Ihrer letzten Seite, sobald es eine Minute alt ist, und 14 Tage lang. Jeder Eintrag ist von einer Art und trägt, worum es geht, so wie dessen eigene Liste es gibt, mit einem Cursor, um direkt danach weiterzumachen. Jede Art braucht ihre eigene Berechtigung, und ohne position:read fehlt der Ort eines Eintrags. Ohne das Fahrzeugdaten-Paket kommt eine Fahrt nur mit Fahrzeit und Strecke, so wie die Fahrtenliste des Fahrzeugs sie gibt. Mit der Zeit können weitere Arten kommen; überspringen Sie einen Eintrag einer Art, die Sie nicht kennen, und machen Sie nach seinem Cursor weiter.
Berechtigungen
alert:readWarnungen sehen
device:readGeräte sehen
fault:readFahrzeugfehler sehen
fuel:readKraftstoffverluste und Tankvorgänge sehen
geofence:readGeofences sehen; Aufenthalte und ihre Meldungen brauchen auch Positionen sehen
Ein Webhook sendet die Einträge des Feeds an Ihren eigenen https-Endpunkt, sobald sie feststehen, sodass Ihr System von einem Alarm, einem überquerten Geofence oder einer abgeschlossenen Fahrt erfährt, ohne zu fragen. Er ist der Feed als Push: dieselben Einträge, in derselben Reihenfolge, mit denselben Cursors.
Eine Person richtet einen Webhook im Panel ein, unter Verwaltung und dann Webhooks, mit ihrem Passwort; ein API-Schlüssel nie, und alle, die Ihr Team verwalten, erfahren von einem neuen. Wählen Sie die Arten, die er bekommt, und ob er Orte sieht. Ein Webhook gehört zu einer Person, die ihn eingerichtet oder zuletzt geprüft hat, und hält nie mehr, als diese Person lesen darf: Jede Zustellung prüft erneut, was diese Person jetzt lesen darf, ob Ihre Organisation das API-Paket hat und ob der Webhook die Art des Eintrags lesen darf, sodass eine abgeschaltete Funktion ihre Arten anhält. Geht diese Person oder darf sie keine API-Schlüssel mehr verwalten, pausiert der Webhook, und alle, die Ihre API-Schlüssel verwalten, werden benachrichtigt. Er wird nie wieder geprüft, da sein Endpunkt noch das Geheimnis kennt, das diese Person gesehen hat: Entfernen Sie ihn und richten Sie einen neuen ein, der ein neues Geheimnis mitbringt. Prüft jemand anderes einen Webhook, der nur wegen seiner Fehlschläge pausiert, wird diese Person für ihn verantwortlich. Ohne Orte ist der Ort eines Alarms null, wie der Feed ihn ohne position:read gibt. Das Signaturgeheimnis, das mit whsec_ beginnt, erscheint einmal; wir bewahren es versiegelt auf.
Der Endpunkt ist https auf Port 443 unter einem öffentlichen Hostnamen. Wir lösen den Namen auf, lehnen ihn ab, wenn auch nur eine Adresse, die er ergibt, privat, Loopback, Link-Local, geteilt oder sonst nicht öffentlich ist, in IPv4 oder einer beliebigen IPv6-Form, verbinden uns dann mit genau dieser Adresse und prüfen ihr Zertifikat gegen den Namen.
Bevor etwas gesendet wird, prüfen Sie den Endpunkt im Panel. Wir senden ihm eine signierte Challenge, und er antwortet mit 2xx und JSON, dessen answer das HMAC-SHA256 der Challenge in base64 ist, mit dem Geheimnis als Schlüssel wie bei einer Signatur; das beweist, dass er das Geheimnis kennt. Ein Webhook, der seine Prüfung nicht bestanden hat, bekommt nichts; ein pausierter macht dort weiter, wo er stehen blieb, sobald er sie wieder besteht.
HTTP/1.1 200 OK
Content-Type: application/json
{"answer":"kOcc0/V1k6uRAwpp/m/bzF5VAhPZm7t/QXJRO0qG5ZY="}
Jede Zustellung ist ein POST mit einem Feed-Eintrag als JSON-Body, genau wie GET /api/v1/feed ihn listet, mit seinem Cursor. Einträge gehen in der Reihenfolge des Feeds, einer nach dem anderen je Webhook, frühestens eine Minute nach dem Geschehen, und ein Eintrag wird erneut gesendet, bis Ihr Endpunkt ihn annimmt (at-least-once delivery); bewahren Sie jeden daher nach seiner id auf. webhook-id ist die id des Eintrags. Überspringen Sie eine Art, die Sie nicht kennen.
Jede Zustellung und jede Challenge ist mit dem eigenen Geheimnis des Webhooks signiert, nach den Headern von Standard Webhooks, sodass auch deren Bibliotheken sie prüfen. Signiert wird webhook-id, ein Punkt, webhook-timestamp, ein Punkt und der rohe Body. Sein HMAC-SHA256, mit dem base64-dekodierten Geheimnis nach whsec_ als Schlüssel, steht base64-kodiert in webhook-signature nach v1,, und der Header kann mehrere tragen, durch Leerzeichen getrennt. Vergleichen Sie in konstanter Zeit, am Body, wie er ankam, bevor Sie ihn parsen.
webhook-timestamp ist der Moment, in dem wir sendeten, in Sekunden seit 1970 UTC. Lehnen Sie eine Zustellung ab, deren Zeitstempel mehr als 300 Sekunden von Ihrer Uhr abweicht, und bewahren Sie die webhook-id-Werte auf, die Sie in diesem Fenster angenommen haben, um eine Wiederholung abzulehnen.
import base64, hashlib, hmac, time
def mac_of(secret: str, content: bytes) -> str:
key = base64.b64decode(secret.removeprefix("whsec_"))
return base64.b64encode(hmac.new(key, content, hashlib.sha256).digest()).decode()
def challenge_answer(secret: str, challenge: str) -> str:
return mac_of(secret, challenge.encode())
def is_from_trackingen(secret: str, headers: dict, raw_body: bytes) -> bool:
sent_at = int(headers["webhook-timestamp"])
if abs(time.time() - sent_at) > 300:
return False
signed = f'{headers["webhook-id"]}.{headers["webhook-timestamp"]}.'.encode() + raw_body
expected = mac_of(secret, signed)
return any(
hmac.compare_digest(each.removeprefix("v1,"), expected)
for each in headers["webhook-signature"].split(" ")
if each.startswith("v1,")
)
Antworten Sie innerhalb von 10 Sekunden mit 2xx, und erledigen Sie die Arbeit nach der Antwort. Jede andere Antwort, eine Weiterleitung, eine Zeitüberschreitung, eine abgelehnte Verbindung oder ein Zertifikat, das nicht zum Namen des Endpunkts passt, gilt als Fehlschlag. Wir folgen nie einer Weiterleitung, und wir bewahren den Body Ihrer Antwort nicht auf und lesen nicht mehr als ein paar Bytes davon.
Ein gescheiterter Eintrag wird 30 Sekunden später erneut gesendet, dann jedes Mal nach doppelt so langer Zeit, höchstens alle 60 Minuten, und nichts danach wird vor ihm gesendet (backoff). Nach 30 Fehlschlägen in Folge, etwa einem Tag, pausiert der Webhook, und alle, die Ihre API-Schlüssel verwalten, werden benachrichtigt. Wir bewahren von jedem Fehlschlag nur auf, wie er ausging und wann, nie einen Body.
Solange ein Webhook scheitert oder pausiert, geht nichts verloren: Lesen Sie GET /api/v1/feed mit dem zuletzt erhaltenen Cursor als after, mit denselben Arten, und machen Sie von dort weiter. Der Feed bewahrt 14 Tage auf.
Ein Webhook bekommt höchstens 60 Zustellungen pro Minute, alle Webhooks einer Organisation zusammen 120; was wartet, geht als Nächstes. Eine Organisation hat bis zu 5 Webhooks.
Fehlercodes
Eine Ablehnung nennt einen dieser Codes. Bauen Sie auf den Code: Er bleibt gleich, die Nachricht kann besser formuliert werden.
CodeStatusBedeutung
INVALID_REQUEST400Ein Wert in Pfad, Abfrage oder Inhalt fehlt oder ist fehlerhaft. Nur eine Route, die einen Inhalt annimmt, antwortet auf einen zu großen Inhalt mit 413 und auf einen vom falschen Typ mit 415
UNAUTHENTICATED401Mit der Anfrage kam kein gültiges Bearer-Token, keine Sitzung und kein gültiger API-Schlüssel
FEATURE_DISABLED403Das Paket des Kunden enthält die nötige Funktion nicht, oder die Organisation des API-Schlüssels hat das API-Paket nicht
FORBIDDEN403Dem Aufrufer fehlt eine nötige Berechtigung, oder die Anfrage kam von einer anderen Website
KEY_NOT_ALLOWED403Ein API-Schlüssel erreicht nur die Schlüsselrouten, und diese Route mit dieser Methode gehört nicht dazu
PASSWORD_CHANGE_REQUIRED403Die angemeldete Person muss vor allem anderen ihr Passwort ändern. Das erhält nur die Sitzung einer Person; ein API-Schlüssel nie, denn er hat kein Passwort
PERSON_REQUIRED403Das tut nur eine angemeldete Person, etwa eine Aktion, die nach dem Passwort fragt; ein API-Schlüssel nie
NOT_FOUND404Nichts in der Reichweite des Aufrufers hat diese ID
METHOD_NOT_ALLOWED405Der Pfad nimmt diese Methode nicht an; der Header Allow nennt die, die er annimmt
ALERT_RULE_LIMIT409So viele Warnregeln, wie gleichzeitig an sein dürfen, sind an
CONFLICT409Die Anfrage widerspricht dem jetzigen Stand
GEOFENCE_LIMIT409Der Kunde hat so viele Geofences, wie er haben darf
GEOFENCE_NAME_TAKEN409Ein anderes Geofence hat diesen Namen
IDEMPOTENCY_KEY_REUSED409Dieser Idempotency-Schlüssel wurde schon für eine andere Anfrage verwendet
CURSOR_EXPIRED410Der Cursor ist zu alt, um dort weiterzumachen; beginnen Sie die Kopie neu, mit from für weiter zurück
RATE_LIMITED429Zu viele Anfragen; der Header Retry-After sagt, wann es wieder geht