API Fleet v1
Passerelle SaaS multi-client entre vos systèmes et Wialon.
Base URL: localhost:8000/api/v1 (variable .env, défaut localhost:8000)
Version: v1 (préfixe URL)
Authentification
Chaque client reçoit un token API propre à la plateforme. Le token Wialon interne n’est jamais exposé.
Authorization: Bearer {votre_token_api}
Accept: application/json
Gestion des tokens
- Les tokens sont stockés en base sous forme de hash SHA-256.
- Un token peut avoir une date d’expiration (
expires_at). - Des abilities peuvent restreindre les permissions (
["*"]= accès complet). - Abilities disponibles :
fleet:read,fleet:reports,fleet:webhooks. - Le token Wialon (
WIALON_TOKEN) reste côté serveur uniquement.
| Ability | Endpoints |
|---|---|
fleet:read |
Véhicules, positions, groupes, historique, capteurs, événements, modèles de rapports |
fleet:reports |
Exécution et suivi de rapports async (/reports/*, /groups/{group}/reports) |
fleet:webhooks |
Gestion des webhooks |
* |
Accès complet |
Erreurs d’authentification
| Code | Message |
|---|---|
| 401 | Unauthenticated. — header Authorization absent |
| 401 | Invalid API token. — token inconnu |
| 401 | API token has expired. |
| 403 | Client account is inactive. |
Rate limiting
Limite par client : rate_limit_per_minute (défaut 60 req/min).
En cas de dépassement : HTTP 429 Too Many Requests.
Header de réponse Laravel standard : X-RateLimit-Limit, X-RateLimit-Remaining.
Endpoints
Véhicules
GET /vehicles
Liste les véhicules du client connecté.
Query params :
active_only(bool, défauttrue)
curl -H "Authorization: Bearer {token}" \
https://example.com/api/v1/vehicles
Réponse :
{
"data": [
{
"id": 1,
"name": "Camion 01",
"plate_number": "AB-123-CD",
"imei": "123456789012345",
"is_active": true,
"last_position_at": "2026-05-29T10:15:00+00:00",
"metadata": {}
}
]
}
GET /vehicles/{vehicle}
Détail d’un véhicule appartenant au client.
Positions
GET /vehicles/{vehicle}/position
Dernière position connue (cache local synchronisé depuis Wialon).
{
"data": {
"vehicle_id": 1,
"latitude": 48.8566,
"longitude": 2.3522,
"speed": 45.5,
"course": 180,
"altitude": 35,
"satellites": 12,
"gps_time": "2026-05-29T10:14:00+00:00",
"received_at": "2026-05-29T10:14:05+00:00"
}
}
GET /vehicles/positions
Dernières positions de tous les véhicules actifs du client.
Groupes
GET /groups
Groupes Wialon mappés au client.
GET /groups/{group}/vehicles
Véhicules d’un groupe.
Modèles de rapports
Les modèles (templates) Wialon accessibles au client sont ceux affectés à ses groupes dans le backoffice (Paramètres → Rapports ou fiche groupe Wialon). Même principe d’isolation que pour les véhicules : un template non associé au client renvoie 404.
Ability requise : fleet:read
GET /report-templates
Liste tous les templates disponibles pour le client, avec les groupes auxquels chacun est rattaché.
Query params :
| Param | Description |
|---|---|
since |
ISO 8601 — sync incrémentale (templates ou bindings modifiés depuis cette date) |
include |
wialon_data — inclut le payload JSON Wialon complet (volumineux) |
curl -H "Authorization: Bearer {token}" \
"https://example.com/api/v1/report-templates?since=2026-06-01T00:00:00Z"
Réponse :
{
"data": [
{
"id": 3,
"name": "Fuel template",
"purpose": "fuel",
"wialon_template_id": 2,
"template_type": "avl_unit",
"requires_unit": true,
"parameters": "…",
"checksum": "abc123",
"tables_count": 1,
"synced_at": "2026-05-29T10:00:00+00:00",
"updated_at": "2026-05-29T10:00:00+00:00",
"resource": {
"wialon_resource_id": 23045518,
"name": "Fuel resource"
},
"groups": [
{
"id": 1,
"name": "Fleet A",
"wialon_group_id": 20837054,
"report_purpose": "fuel",
"is_default": true
}
]
}
],
"meta": {
"catalog_synced_at": "2026-05-29T10:00:00+00:00",
"since": null,
"count": 1
}
}
GET /report-templates/{template}
Détail d’un template par son ID local (wialon_report_templates.id). Paramètre include=wialon_data supporté.
GET /groups/{group}/report-templates
Templates affectés à un groupe Wialon du client (format orienté affectation).
Query params : since, include=wialon_data
Réponse (extrait) :
{
"data": [
{
"binding_id": 12,
"report_purpose": "fuel",
"is_default": true,
"template": {
"id": 3,
"name": "Fuel template",
"wialon_template_id": 2,
"requires_unit": true,
"resource": {
"wialon_resource_id": 23045518,
"name": "Fuel resource"
}
}
}
],
"meta": {
"group_id": 1,
"group_name": "Fleet A",
"wialon_group_id": 20837054,
"catalog_synced_at": "2026-05-29T10:00:00+00:00",
"count": 1
}
}
Workflow recommandé côté client
GET /report-templates(ou sync incrémentale avecsince)- Stocker localement
id(gateway),wialon_template_id,resource.wialon_resource_id,requires_unit - Option A (recommandée) — IDs gateway locaux dans
POST /reports/execute/gateway - Option B — IDs Wialon bruts dans
POST /reports/execute
| Concept | ID gateway (local) | ID Wialon |
|---|---|---|
| Groupe | groups[].id |
groups[].wialon_group_id |
| Template | report-templates[].id |
wialon_template_id + resource.wialon_resource_id |
| Véhicule | vehicles[].id |
vehicles[].wialon_unit_id |
Historique
GET /vehicles/{vehicle}/history?from=&to=
Positions historiques en cache local.
| Param | Requis | Description |
|---|---|---|
from |
oui | ISO 8601 ou Y-m-d H:i:s |
to |
oui | ISO 8601 ou Y-m-d H:i:s |
Intervalle max : 31 jours (configurable via WIALON_HISTORY_MAX_INTERVAL_DAYS).
GET /vehicles/{vehicle}/sensors
Capteurs synchronisés depuis Wialon (sync planifiée ou manuelle).
{
"data": [
{
"id": 1,
"vehicle_id": 1,
"wialon_sensor_id": 42,
"name": "Fuel level",
"type": "fuel",
"value": "75",
"unit": "%",
"measured_at": "2026-05-29T10:14:00+00:00"
}
]
}
Trajets & carburant
Les rapports Wialon utilisent un resource ID et un template ID propres à chaque ressource Wialon. La plateforme les synchronise localement et les résout automatiquement par groupe véhicule.
Résolution du template
Ordre de priorité pour trips, fuel et general :
report_template_id(optionnel) — ID local du catalogue (wialon_report_templates.id)- Affectation par groupe Wialon — configurée dans le backoffice (Paramètres → Rapports)
- Template tagué — premier template du catalogue avec le
purposecorrespondant - Fallback
.env—WIALON_{TYPE}_REPORT_RESOURCE_ID/WIALON_{TYPE}_REPORT_TEMPLATE_ID
Synchronisation du catalogue (admin)
- Backoffice : Paramètres → Rapports → « Synchroniser depuis Wialon »
- CLI :
php artisan wialon:sync-reports(--dry-runpour prévisualiser)
Après sync, taguer chaque template (trips, fuel, general) et affecter les templates par groupe Wialon.
GET /vehicles/{vehicle}/trips?from=&to=
Query params optionnels :
| Param | Description |
|---|---|
report_template_id |
ID local du template catalogue (priorité maximale) |
GET /vehicles/{vehicle}/fuel?from=&to=
Mêmes paramètres que /trips. Données issues du rapport Wialon résolu pour le véhicule.
Réponse type :
{
"vehicle_id": 1,
"from": "2026-05-01T00:00:00+00:00",
"to": "2026-05-29T23:59:59+00:00",
"data": []
}
Événements
GET /events
Query params optionnels : vehicle_id, from, to, per_page (défaut 50).
Rapports asynchrones
Ability requise : fleet:reports
GET /reports
Liste paginée des rapports déjà générés pour le client.
Query params : group_id, status, report_template_id, from, to, per_page (défaut 30).
GET /groups/{group}/reports
Rapports stockés pour un groupe Wialon.
POST /groups/{group}/reports
Génère un rapport pour un groupe (ID mapping local dans l'URL). Le corps utilise les IDs Wialon du template :
{
"wialon_resource_id": 23045518,
"wialon_template_id": 2,
"from": "2026-05-01T00:00:00Z",
"to": "2026-05-29T23:59:59Z",
"format": "json",
"label": "Fuel May 2026",
"wialon_unit_id": 12345678
}
wialon_unit_id est requis si le template a requires_unit: true.
POST /groups/{group}/reports/gateway
Même objectif que ci-dessus, avec les IDs gateway locaux. Le groupe est déjà dans l'URL (wialon_group_mappings.id).
{
"gateway_template_id": 3,
"from": "2026-05-01T00:00:00Z",
"to": "2026-05-29T23:59:59Z",
"format": "json",
"label": "Fuel May 2026",
"gateway_vehicle_id": 42
}
gateway_vehicle_id est requis si le template a requires_unit: true.
POST /reports/execute
Lance un rapport asynchrone avec les identifiants Wialon (recommandé) :
{
"wialon_group_id": 20837054,
"wialon_resource_id": 23045518,
"wialon_template_id": 2,
"from": "2026-05-01T00:00:00Z",
"to": "2026-05-29T23:59:59Z",
"format": "json",
"label": "Fuel May 2026"
}
Pour un template unité (requires_unit: true) :
{
"wialon_group_id": 20837054,
"wialon_resource_id": 23045518,
"wialon_template_id": 2,
"wialon_unit_id": 12345678,
"from": "2026-05-01T00:00:00Z",
"to": "2026-05-29T23:59:59Z"
}
| Champ | Requis | Description |
|---|---|---|
wialon_group_id |
oui | ID groupe Wialon (groups[].wialon_group_id) |
wialon_resource_id |
oui | ID ressource Wialon du template |
wialon_template_id |
oui | ID template Wialon dans la ressource |
from / to |
oui | Période ISO 8601 |
wialon_unit_id |
si template unité | ID unité Wialon dans le groupe |
format |
non | json, pdf, csv (défaut json) |
label |
non | Libellé libre |
Mode legacy — résolution automatique par type :
{
"type": "trips",
"wialon_unit_id": 12345678,
"from": "2026-05-01T00:00:00Z",
"to": "2026-05-29T23:59:59Z",
"format": "json"
}
Types legacy : trips, fuel, general. Le template est résolu via le groupe du véhicule, puis le catalogue tagué, puis .env.
POST /reports/execute/gateway
Lance un rapport asynchrone avec les IDs gateway (locaux à la plateforme). La résolution Wialon est faite côté serveur.
{
"gateway_group_id": 1,
"gateway_template_id": 3,
"from": "2026-05-01T00:00:00Z",
"to": "2026-05-29T23:59:59Z",
"format": "json",
"label": "Fuel May 2026"
}
Pour un template unité (requires_unit: true) :
{
"gateway_group_id": 1,
"gateway_template_id": 3,
"gateway_vehicle_id": 42,
"from": "2026-05-01T00:00:00Z",
"to": "2026-05-29T23:59:59Z"
}
| Champ | Requis | Description |
|---|---|---|
gateway_group_id |
oui | ID mapping groupe (GET /groups → id) |
gateway_template_id |
oui | ID template catalogue (GET /report-templates → id) |
from / to |
oui | Période ISO 8601 |
gateway_vehicle_id |
si template unité | ID véhicule local (GET /vehicles → id) |
format |
non | json, pdf, csv (défaut json) |
label |
non | Libellé libre |
Réponse 202 Accepted — inclut les IDs Wialon résolus dans meta.resolved_wialon :
{
"data": {
"id": 12,
"report_type": "fuel",
"status": "pending",
"group_id": 1,
"report_template_id": 3,
"from": "...",
"to": "...",
"format": "json"
},
"meta": {
"resolved_wialon": {
"wialon_group_id": 20837054,
"wialon_resource_id": 23045518,
"wialon_template_id": 2,
"wialon_unit_id": null
}
}
}
Les endpoints gateway (/reports/execute/gateway, /groups/{group}/reports/gateway) renvoient meta.resolved_wialon. Les endpoints Wialon bruts renvoient uniquement data.
Réponse 202 Accepted (mode Wialon ou legacy) :
{
"data": {
"id": 12,
"report_type": "trips",
"status": "pending",
"vehicle_id": 1,
"from": "...",
"to": "...",
"format": "json"
}
}
GET /reports/{reportJob}
Statut : pending, running, completed, failed. Inclut result lorsque le rapport est terminé.
GET /reports/{reportJob}/wialon-responses
Liste les archives JSON brutes Wialon liées au job (appels API, payloads).
GET /reports/{reportJob}/wialon-responses/{archive}
Contenu décodé d'une archive Wialon (archive + payload).
Webhooks
GET /webhooks
POST /webhooks
{
"url": "https://client.example.com/webhooks/fleet",
"events": ["vehicle.position.updated", "vehicle.event.created"]
}
Réponse 201 — le champ secret n’est retourné qu’à la création.
DELETE /webhooks/{webhookEndpoint}
Signature HMAC des webhooks
Chaque livraison inclut :
| Header | Description |
|---|---|
X-Satf-Signature |
HMAC-SHA256 du body JSON brut |
X-Satf-Event |
Type d’événement |
X-Satf-Delivery-Id |
ID de livraison |
Vérification côté client :
$expected = hash_hmac('sha256', $request->getContent(), $secret);
if (! hash_equals($expected, $request->header('X-Satf-Signature'))) {
abort(401);
}
Les échecs sont retentés automatiquement (max 5 tentatives, intervalle 5 min).
Erreurs courantes
| Code | Cas |
|---|---|
| 404 | Ressource inexistante ou n’appartenant pas au client |
| 422 | Validation (intervalle trop long, paramètres manquants) |
| 429 | Rate limit dépassé |
| 502 | Erreur Wialon interne |
Format :
{
"message": "Description lisible",
"errors": {}
}
Synchronisation & cache
Jobs planifiés (Scheduler Laravel + cron) :
| Job | Fréquence |
|---|---|
SyncWialonUnitsJob |
toutes les 10 min |
SyncWialonPositionsJob |
toutes les 1 min |
SyncWialonSensorsJob |
toutes les 15 min |
SyncWialonVehicleHistoryJob |
toutes les heures |
RetryFailedWebhooksJob |
toutes les 5 min |
Cron serveur :
* * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1
Versionnement
- Version actuelle : v1 (préfixe
/api/v1) - Les breaking changes futurs seront publiés sous
/api/v2 - v1 restera supportée pendant une période de transition annoncée
Sécurité
- Token Wialon : variable d’environnement serveur uniquement
- Tokens clients : hash SHA-256, rotation possible via création d’un nouveau token
- Isolation stricte par
client_idsur véhicules, positions, événements, modèles de rapports, rapports et webhooks - Journalisation API (
api_request_logs) : client, endpoint, méthode, durée, statut HTTP