EasyTrack API
API REST publique permettant à des applications tierces d'intégrer les fonctionnalités EasyTrack : positions GPS temps réel, devices, geofences, alertes, rapports PDF, share-links et exports d'historique.
Vue d'ensemble
L'API EasyTrack est une API REST JSON hébergée sur Cloudflare (edge, région UE).
Toutes les requêtes doivent être en HTTPS. Les réponses sont au format
application/json sauf mention contraire (PDF, CSV, KML…).
| Domaine | https://api.easytrack.ch |
|---|---|
| Format | JSON UTF-8 |
| Auth | Bearer token (obtenu via OTP email) |
| CORS | Ouvert aux origines autorisées (contacter le support) |
| Hébergement | Cloudflare EU · D1 (WEUR) · R2 |
URL de base
https://api.easytrack.ch
Versionnage
L'API n'a pas encore de préfixe de version dans l'URL. Les évolutions non rétrocompatibles
seront annoncées via un préfixe /v2 et une période de dépréciation de 6 mois.
Quotas & limites
- Rate limit par défaut : 600 req/min par token
- Payload max : 1 Mo par requête
- Export historique : pagination forcée par pages de 5000 positions
Authentification par OTP
L'authentification se fait par code à usage unique (OTP) envoyé par email. Après vérification, l'API retourne un jeton Bearer à utiliser dans toutes les requêtes ultérieures.
Envoie un code OTP à 6 chiffres à l'adresse email fournie.
Body
{
"email": "user@example.com",
"lang": "fr" // optionnel : fr, en, de, it, es, pt, nl, tr
}
Réponse
{
"success": true,
"message": "Code envoyé par email",
"expires_in": 600
}
Vérifie l'OTP et retourne un jeton Bearer.
Body
{
"email": "user@example.com",
"code": "123456"
}
Réponse (succès)
{
"success": true,
"token": "eyJhbGci…", // Bearer token
"expires_at": "2026-08-01T…Z",
"user": {
"id": 42,
"email": "user@example.com",
"role": "client",
"is_2fa_enabled": false
}
}
Réponse (2FA requis)
{
"success": true,
"requires_2fa": true,
"pending_token": "…" // à utiliser dans /auth/verify-2fa
}
Utiliser le jeton Bearer
Toutes les routes protégées attendent le header suivant :
Authorization: Bearer <token>
Magic link
Envoie un lien magique par email permettant une connexion sans code. Utile pour des liens embarqués dans des emails.
{ "email": "user@example.com", "lang": "fr" }
Deuxième facteur (TOTP)
POST /auth/2fa/setup | Génère un secret + QR-code |
POST /auth/2fa/verify | Active le 2FA après vérification |
POST /auth/verify-2fa | Vérifie le code TOTP au login |
POST /auth/2fa/disable | Désactive le 2FA |
GET /auth/2fa/status | État actuel du 2FA |
Session courante
Retourne le profil de l'utilisateur connecté.
Révoque le jeton courant.
Positions GPS
Points GPS bruts et enrichis (adresse, allumage, batterie…). Deux tables distinctes :
raw_positions (tous les points) et positions (points filtrés,
utilisés par le replay).
Dernière position connue de tous les devices auxquels le compte a accès.
Query params
| Paramètre | Type | Description |
|---|---|---|
imeis | string | Filtrer par IMEIs (séparés par virgules) |
include_address | bool | Reverse-geocode chaque point |
Réponse
{
"success": true,
"positions": [
{
"imei": "862272081390363",
"latitude": 46.2044,
"longitude": 6.1432,
"speed": 42,
"angle": 187,
"ignition": 1,
"server_timestamp": "2026-06-30T14:22:08Z",
"address": "Rue de Bâle 14, 1201 Genève, Suisse"
}
]
}
Positions filtrées (replay quality) pour un device sur une plage temporelle.
| Paramètre | Type | Description |
|---|---|---|
imei | string | Obligatoire |
from | ISO 8601 | Date de début (UTC) |
to | ISO 8601 | Date de fin (UTC) |
limit | int | Max 5000 |
Positions filtrées pour un IMEI (raccourci).
Export brut paginé (raw_positions) — tous les points GPS reçus.
Utilisez la pagination via page.
| Paramètre | Description |
|---|---|
imei | Obligatoire |
from, to | Plage temporelle (ISO 8601) |
page | Index de page (0 par défaut, 5000 points/page) |
Réponse
{
"success": true,
"imei": "…",
"page": 0,
"page_size": 5000,
"count": 4823,
"has_more": false,
"positions": [ /* … */ ]
}
Devices
Liste des devices assignés au compte connecté.
{
"success": true,
"devices": [
{
"id": 12, "imei": "862272081390363",
"plate": "GE888222", "model": "Vivaro",
"type": "vehicle",
"is_active": 1,
"last_seen_at": "2026-06-30T14:22:08Z"
}
]
}
Vue optimisée pour dashboard temps réel : liste des devices + dernière position + état allumage/mouvement en une seule requête.
Détail d'un device par son IMEI.
Jours où chaque device a été actif (utile pour construire un date picker n'affichant que les dates avec données).
Geofences
Zones géographiques déclenchant des alertes d'entrée/sortie.
Liste des geofences du compte.
Crée une geofence circulaire ou polygonale.
{
"name": "Dépôt Genève",
"type": "circle", // "circle" | "polygon"
"center": { "lat": 46.20, "lng": 6.14 },
"radius_m": 250,
"device_imeis": ["862272081390363"],
"trigger_on": ["enter", "exit"]
}
Met à jour une geofence.
Supprime une geofence.
Alertes
Liste des alertes configurées pour le compte (vitesse, kilométrage, geofence, batterie…).
Crée une règle d'alerte.
{
"type": "speed", // speed | mileage | geofence | battery | offline
"name": "Excès de vitesse",
"threshold": 130, // km/h pour speed
"device_imeis": ["…"],
"notify": ["email", "push"]
}
Rapports PDF
Rapports générés côté serveur (Cloudflare Workers + pdf-lib) et stockés dans R2. Envoi automatique par email + URL publique protégée par un token opaque.
Liste des configurations de rapports du compte.
Crée une configuration de rapport (quotidien / hebdo / mensuel).
{
"interval": "weekly", // daily | weekly | monthly
"device_imeis": ["…"],
"email_to": "user@example.com",
"sections": {
"summary": true,
"stats": true,
"trips": true,
"parkings": true,
"alerts": true
}
}
Crée automatiquement une configuration hebdomadaire par défaut incluant tous les devices du compte.
Génère un rapport à la demande, avec option de plage personnalisée. Retourne un token public permettant d'accéder au PDF.
{
"period_start": "2026-06-15T00:00:00Z",
"period_end": "2026-06-22T00:00:00Z",
"email": null // null = ne pas envoyer d'email
}
{
"success": true,
"id": 1287,
"token": "4cbc3a9bc89e783682a411…",
"public_url": "https://api.easytrack.ch/reports/pdf/4cbc3a9…"
}
Historique des exécutions d'un rapport.
Sert le PDF final. Content-Type application/pdf.
Nom de fichier : EASYTRACK-YYYY-MM-DD-<CODE>.pdf.
Aucun header d'auth n'est nécessaire : la possession du token fait foi.
Share-links publics
Un share-link permet à un tiers non authentifié de voir en temps réel un ou plusieurs devices, pendant une durée limitée. Idéal pour partager la position d'une flotte à un client externe ou à un dispatcher.
Liste des liens de partage actifs.
Crée un lien de partage limité dans le temps.
{
"name": "Campagne juin 2026",
"device_imeis": ["862272081390363", "862272081390400"],
"expires_at": "2026-07-05T18:00:00Z" // ISO 8601 ou null (permanent)
}
{
"success": true,
"id": 37,
"token": "a1b2c3d4e5f6g7h8" // → https://my.easytrack.ch/open/share/<token>
}
Met à jour un lien (renommage, activation/désactivation, changement d'expiration).
Endpoint public retournant la carte HTML avec les devices autorisés.
Aucun header d'auth : le token est la clé d'accès. Expire automatiquement
selon expires_at.
Export historique
Deux niveaux d'export sont proposés :
-
Full : tous les points GPS bruts.
Endpoint
GET /positions/export(voir ci-dessus). -
Clean : uniquement les points utilisés par le replay
(bruit et doublons filtrés). Endpoint
GET /positions.
Formats supportés côté frontend : JSON, CSV, GPX, KML, GeoJSON.
Manager (compte)
Endpoints généraux du compte connecté.
| Méthode | Chemin | Description |
|---|---|---|
| GET | /manager/profile | Profil du compte |
| PUT | /manager/profile | Mise à jour du profil |
| GET | /manager/settings | Paramètres UI/notifications |
| PUT | /manager/settings | Enregistre les paramètres |
| GET | /manager/notifications | Notifications reçues |
| GET | /manager/geofences | Idem /geofences, scoped par compte |
Format des réponses
Toutes les réponses succès suivent la structure suivante :
{
"success": true,
/* …données… */
}
En cas d'erreur :
{
"success": false,
"error": "Message lisible",
"code": "ERR_INVALID_IMEI" // optionnel
}
Codes d'erreur HTTP
| Code | Signification |
|---|---|
400 | Requête invalide (paramètre manquant/mal formé) |
401 | Jeton absent ou invalide |
403 | Accès non autorisé à cette ressource (device, geofence…) |
404 | Ressource introuvable |
410 | Ressource expirée (PDF, share-link) |
429 | Rate limit dépassé |
500 | Erreur serveur (contactez le support) |
503 | Service dépendant indisponible (stockage, mail…) |
Pagination
Les endpoints qui retournent potentiellement beaucoup de données utilisent une pagination par offset / page :
GET /positions/export?imei=…&page=0
↓
{
"page": 0,
"page_size": 5000,
"count": 5000,
"has_more": true,
"positions": [ … ]
}
Dates & fuseaux
- Tous les timestamps sont en ISO 8601 UTC (
2026-06-30T14:22:08Z). - L'affichage utilisateur (rapports PDF, share-links) est en fuseau
Europe/Zurich.
SDK & exemples
curl
# 1) Demander un OTP
curl -X POST https://api.easytrack.ch/auth/request-code \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com"}'
# 2) Vérifier le code
TOKEN=$(curl -s -X POST https://api.easytrack.ch/auth/verify-code \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","code":"123456"}' | jq -r .token)
# 3) Lister les devices
curl https://api.easytrack.ch/devices \
-H "Authorization: Bearer $TOKEN"
JavaScript / TypeScript
const API = 'https://api.easytrack.ch';
async function login(email, code) {
const r = await fetch(`${API}/auth/verify-code`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, code })
});
const { token } = await r.json();
return token;
}
async function latestPositions(token) {
const r = await fetch(`${API}/positions/latest`, {
headers: { Authorization: `Bearer ${token}` }
});
return (await r.json()).positions;
}
Python
import requests
API = "https://api.easytrack.ch"
def login(email, code):
r = requests.post(f"{API}/auth/verify-code",
json={"email": email, "code": code})
return r.json()["token"]
def latest(token):
r = requests.get(f"{API}/positions/latest",
headers={"Authorization": f"Bearer {token}"})
return r.json()["positions"]
Support
Contact : api@easytrack.ch
Support 24 h / 7 j (plan Business) :
support@easytrack.ch
Statut : status.easytrack.ch