Créez votre application GPS avec Claude, ChatGPT ou Gemini

Donnez à votre assistant IA toute la documentation de l’API en un seul fichier, puis choisissez un prompt prêt à l’emploi. Il écrit le code, vous le testez avec une clé de test.

Le prompt de départ

Collez-le en premier message, après avoir remplacé la partie entre crochets par votre projet. Il contient les règles de sécurité et toute la documentation de l’API : routes, champs, webhooks et codes d’erreur.

  1. 1Créez une clé de test dans votre espace client (Mon compte, Clés API).
  2. 2Copiez le prompt, décrivez votre projet à la place des crochets et envoyez-le.
  3. 3Enregistrez la clé dans la variable d’environnement QENTRA_API_KEY, jamais dans la conversation.

Vous préférez un fichier ? Le même contenu, sans la consigne d’introduction, est disponible ici : qentra-api.md.

Tu es un développeur expérimenté. Je veux construire : [DÉCRIS TON PROJET EN UNE OU DEUX PHRASES].
Ce projet utilise l’API GPS Qentra System. Sa documentation complète est ci-dessous : respecte-la strictement et applique toutes ses règles impératives.
Avant d’écrire du code, pose-moi les questions utiles (langage, hébergement, base de données). Ensuite, avance étape par étape : explique où placer chaque fichier et comment le tester avec ma clé de test.
Ne me demande jamais ma clé API dans la conversation : utilise la variable d’environnement QENTRA_API_KEY.

---

# API Qentra System : contexte pour assistant de code

API REST de suivi GPS de véhicules (positions, historique, trajets, alertes, zones, partage, webhooks, commandes moteur).
Documentation officielle : https://qentrasystem.com/developpeurs/documentation

## Règles impératives

- La clé API reste côté serveur, dans une variable d’environnement QENTRA_API_KEY. Jamais dans le navigateur, une application mobile, une capture d’écran ou un dépôt Git.
- Commencer avec une clé de test qsk_test_ (véhicules simulés 9001, 9002 et 9003), puis passer à une clé qsk_live_ sans changer le code.
- Toujours lire le champ success, puis error.code en cas d’échec. Ne jamais baser la logique sur error.message.
- Respecter 60 requêtes par minute et par clé. Sur une erreur 429, attendre la durée de l’en-tête Retry-After. Réessayer avec un délai croissant uniquement pour 429, 502 et 503.
- Ne pas appeler /positions plus d’une fois toutes les 15 secondes. Utiliser les webhooks pour les alertes au lieu d’interroger en boucle.
- Historique : 7 jours au plus par appel. Découper les périodes plus longues.
- Webhooks : vérifier la signature Qentra-Signature (HMAC-SHA256 de « t.corps_brut » avec le secret whsec_) par comparaison à temps constant, refuser les envois de plus de 5 minutes, répondre 2xx en moins de 10 secondes, dédoublonner avec Qentra-Delivery.
- Commandes moteur : demander une confirmation explicite à l’utilisateur dans l’interface, envoyer {"confirm":true} et gérer l’erreur vehicle_moving.
- N’utiliser que les routes et les champs décrits dans ce document. Ne rien inventer : en cas de doute, demander.

## Bases

- URL de base : `https://qentrasystem.com/api/public/v1`
- Authentification : en-tête `Authorization: Bearer <clé>` sur chaque requête, HTTPS uniquement.
- Corps des requêtes POST : JSON avec `Content-Type: application/json`. Toujours envoyer `Accept: application/json`.
- Succès : `{"success":true,"data":...,"meta":{...}}`. Erreur : `{"success":false,"error":{"code":"...","message":"...","request_id":"..."}}`.
- Listes paginées : `meta.page`, `meta.per_page`, `meta.total`, `meta.last_page`.
- Dates ISO 8601 en UTC, vitesses en km/h, distances en kilomètres.
- En-têtes de réponse : `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-Quota-Limit`, `X-Quota-Remaining`, `Retry-After` (après 429), `X-Request-Id`.
- Quota : 20 000 appels par véhicule et par mois en production, 1 000 par jour avec une clé de test.

## Droits des clés (scopes)

- `vehicles:read` : Lire les véhicules et leurs positions
- `history:read` : Lire l'historique et les rapports
- `alerts:read` : Lire les alertes
- `zones:read` : Lire les zones
- `shares:write` : Créer des liens de partage de position
- `webhooks:manage` : Gérer les webhooks
- `commands:engine` : Couper et remettre le moteur

## Routes

### Vérifier la clé

`GET /me`

Renvoie le compte, le mode (test ou production), les droits de la clé et la consommation du quota. Idéal pour tester votre configuration.

Exemple : `GET https://qentrasystem.com/api/public/v1/me`

Réponse :
```json
{
    "success": true,
    "data": {
        "account": {
            "id": 42,
            "name": "Transports Kouassi",
            "company": "TK SARL"
        },
        "key": {
            "name": "ERP livraison",
            "prefix": "qsk_live_8fK2pQ",
            "mode": "live",
            "scopes": [
                "vehicles:read",
                "history:read"
            ],
            "expires_at": null
        },
        "quota": {
            "period": "month",
            "limit": 200000,
            "used": 1840,
            "resets_at": "2026-11-01T00:00:00+00:00"
        },
        "rate_limit_per_minute": 60
    }
}
```

### Lister les véhicules

`GET /vehicles` (droit `vehicles:read`)

Tous les véhicules du compte, avec leur état de connexion. Utilisez /positions pour obtenir aussi la dernière position.

Exemple : `GET https://qentrasystem.com/api/public/v1/vehicles`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "id": 9001,
            "name": "Véhicule de test 1",
            "plate": "AB-1234-CI",
            "imei": "860000000009001",
            "model": "Simulateur",
            "vehicle_type": "car",
            "status": "online",
            "last_update": "2026-10-01T14:20:05Z"
        }
    ],
    "meta": {
        "count": 1
    }
}
```

### Détail d’un véhicule

`GET /vehicles/9001` (droit `vehicles:read`)

Un véhicule et sa dernière position connue.

Paramètres :
- `id` (entier, obligatoire) : Identifiant du véhicule (dans l’adresse).

Exemple : `GET https://qentrasystem.com/api/public/v1/vehicles/9001`

Réponse :
```json
{
    "success": true,
    "data": {
        "id": 9001,
        "name": "Véhicule de test 1",
        "plate": "AB-1234-CI",
        "imei": "860000000009001",
        "model": "Simulateur",
        "vehicle_type": "car",
        "status": "online",
        "last_update": "2026-10-01T14:20:05Z",
        "position": {
            "latitude": 5.341224,
            "longitude": -4.017311,
            "speed_kmh": 40,
            "course": 212,
            "altitude": 12,
            "fix_time": "2026-10-01T14:20:05Z",
            "valid": true,
            "ignition": true,
            "motion": true,
            "battery_level": 100,
            "power_volts": 12.6,
            "odometer_km": 15230.4
        }
    }
}
```

### Dernières positions

`GET /positions` (droit `vehicles:read`)

La dernière position de tous les véhicules en un seul appel. Pour un suivi en continu, interrogez cette route toutes les 15 à 30 secondes, ou utilisez les webhooks pour les alertes.

Exemple : `GET https://qentrasystem.com/api/public/v1/positions`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "id": 9001,
            "name": "Véhicule de test 1",
            "status": "online",
            "position": {
                "latitude": 5.341224,
                "longitude": -4.017311,
                "speed_kmh": 40,
                "course": 212,
                "fix_time": "2026-10-01T14:20:05Z",
                "ignition": true
            }
        }
    ],
    "meta": {
        "count": 1
    }
}
```

### Historique des positions

`GET /vehicles/9001/history` (droit `history:read`)

Tous les points GPS d’une période (7 jours au plus, 5 000 points au plus).

Paramètres :
- `from` (date ISO 8601, obligatoire) : Début de la période (UTC conseillé).
- `to` (date ISO 8601, obligatoire) : Fin de la période, postérieure à from.

Exemple : `GET https://qentrasystem.com/api/public/v1/vehicles/9001/history?from=2026-10-01T06:00:00Z&to=2026-10-01T12:00:00Z`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "latitude": 5.336401,
            "longitude": -4.008712,
            "speed_kmh": 38,
            "course": 95,
            "altitude": 12,
            "fix_time": "2026-10-01T06:00:00Z",
            "valid": true,
            "ignition": true,
            "motion": true,
            "battery_level": 100,
            "power_volts": 12.6,
            "odometer_km": 15190.2
        }
    ],
    "meta": {
        "vehicle_id": 9001,
        "from": "2026-10-01T06:00:00Z",
        "to": "2026-10-01T12:00:00Z",
        "count": 361
    }
}
```

### Trajets

`GET /vehicles/9001/trips` (droit `history:read`)

Les trajets de la période, avec départ, arrivée, durée, distance et vitesses.

Paramètres :
- `from` (date ISO 8601, obligatoire) : Début de la période.
- `to` (date ISO 8601, obligatoire) : Fin de la période.

Exemple : `GET https://qentrasystem.com/api/public/v1/vehicles/9001/trips?from=2026-10-01T00:00:00Z&to=2026-10-02T00:00:00Z`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "start_time": "2026-10-01T07:12:00Z",
            "end_time": "2026-10-01T07:57:00Z",
            "duration_seconds": 2700,
            "distance_km": 18.4,
            "average_speed_kmh": 32,
            "max_speed_kmh": 61,
            "start": {
                "latitude": 5.3364,
                "longitude": -4.0267,
                "address": "Plateau, Abidjan"
            },
            "end": {
                "latitude": 5.3464,
                "longitude": -4.0167,
                "address": "Cocody, Abidjan"
            }
        }
    ],
    "meta": {
        "vehicle_id": 9001,
        "count": 1
    }
}
```

### Arrêts

`GET /vehicles/9001/stops` (droit `history:read`)

Les arrêts de la période, avec leur durée et leur position.

Paramètres :
- `from` (date ISO 8601, obligatoire) : Début de la période.
- `to` (date ISO 8601, obligatoire) : Fin de la période.

Exemple : `GET https://qentrasystem.com/api/public/v1/vehicles/9001/stops?from=2026-10-01T00:00:00Z&to=2026-10-02T00:00:00Z`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "start_time": "2026-10-01T08:00:00Z",
            "end_time": "2026-10-01T08:15:00Z",
            "duration_seconds": 900,
            "latitude": 5.3464,
            "longitude": -4.0167,
            "address": "Cocody, Abidjan"
        }
    ],
    "meta": {
        "vehicle_id": 9001,
        "count": 1
    }
}
```

### Résumé d’activité

`GET /vehicles/9001/summary` (droit `history:read`)

Distance, vitesses et heures moteur de la période, ou jour par jour avec daily=1.

Paramètres :
- `from` (date ISO 8601, obligatoire) : Début de la période.
- `to` (date ISO 8601, obligatoire) : Fin de la période.
- `daily` (0 ou 1, facultatif) : 1 : un résumé par jour.

Exemple : `GET https://qentrasystem.com/api/public/v1/vehicles/9001/summary?from=2026-09-24T00:00:00Z&to=2026-10-01T00:00:00Z&daily=1`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "date": "2026-09-24T00:00:00Z",
            "distance_km": 42.7,
            "average_speed_kmh": 31,
            "max_speed_kmh": 64,
            "engine_hours": 2.4
        }
    ],
    "meta": {
        "vehicle_id": 9001,
        "count": 7
    }
}
```

### Alertes

`GET /alerts` (droit `alerts:read`)

Les alertes du compte, de la plus récente à la plus ancienne, avec pagination.

Paramètres :
- `status` (open, resolved ou all, facultatif) : Filtre sur l’état (all par défaut).
- `vehicle_id` (entier, facultatif) : Un seul véhicule.
- `type` (texte, facultatif) : Type d’alerte, par exemple powerCut, overspeed, geofenceExit.
- `from / to` (date ISO 8601, facultatif) : Période de survenue.
- `per_page` (1 à 100, facultatif) : 50 par défaut.
- `page` (entier, facultatif) : Numéro de page.

Exemple : `GET https://qentrasystem.com/api/public/v1/alerts?status=open&per_page=50`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "vehicle_id": 9001,
            "type": "geofenceExit",
            "label": "Sortie d'une zone",
            "level": "warning",
            "latitude": 5.3501,
            "longitude": -4.0102,
            "occurrences": 1,
            "occurred_at": "2026-10-01T14:08:00Z",
            "last_seen_at": "2026-10-01T14:08:00Z",
            "resolved": false,
            "resolved_at": null
        }
    ],
    "meta": {
        "page": 1,
        "per_page": 50,
        "total": 1,
        "last_page": 1
    }
}
```

### Zones

`GET /zones` (droit `zones:read`)

Les zones (géorepérage) du compte et les véhicules qui y sont rattachés.

Exemple : `GET https://qentrasystem.com/api/public/v1/zones`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "name": "Dépôt de test",
            "type": "circle",
            "geometry": "CIRCLE (5.3364 -4.0267, 500)",
            "alert_on_enter": true,
            "alert_on_exit": true,
            "vehicle_ids": [
                9001,
                9002,
                9003
            ]
        }
    ],
    "meta": {
        "count": 1
    }
}
```

### Partager une position

`POST /vehicles/9001/shares` (droit `shares:write`)

Crée un lien public de suivi en direct, valable pour la durée choisie.

Paramètres :
- `duration` (1h, 6h, 24h ou 7j, obligatoire) : Durée de validité du lien.
- `label` (texte, facultatif) : Libellé interne (60 caractères).

Exemple : `POST https://qentrasystem.com/api/public/v1/vehicles/9001/shares`

Corps :
```json
{
    "duration": "24h",
    "label": "Livraison client 4587"
}
```

Réponse :
```json
{
    "success": true,
    "data": {
        "url": "https://qentrasystem.com/p/Hk2…",
        "expires_at": "2026-10-02T14:20:00Z"
    }
}
```

### Couper le moteur

`POST /vehicles/9001/engine/stop` (droit `commands:engine`)

Immobilise le véhicule. Refusé si le véhicule roule à plus de 10 km/h. Le propriétaire est notifié et un webhook command.sent est envoyé.

Paramètres :
- `confirm` (true, obligatoire) : Confirmation explicite obligatoire.

Exemple : `POST https://qentrasystem.com/api/public/v1/vehicles/9001/engine/stop`

Corps :
```json
{
    "confirm": true
}
```

Réponse :
```json
{
    "success": true,
    "data": {
        "status": "sent",
        "message": "Commande envoyée au boîtier.",
        "command": "engine_stop",
        "vehicle_id": 9001
    }
}
```

### Remettre le moteur en marche

`POST /vehicles/9001/engine/resume` (droit `commands:engine`)

Lève l’immobilisation. Le propriétaire est notifié.

Paramètres :
- `confirm` (true, obligatoire) : Confirmation explicite obligatoire.

Exemple : `POST https://qentrasystem.com/api/public/v1/vehicles/9001/engine/resume`

Corps :
```json
{
    "confirm": true
}
```

Réponse :
```json
{
    "success": true,
    "data": {
        "status": "sent",
        "message": "Commande envoyée au boîtier.",
        "command": "engine_resume",
        "vehicle_id": 9001
    }
}
```

### Lister les webhooks

`GET /webhooks` (droit `webhooks:manage`)

Les webhooks du compte et l’état de leur dernier envoi.

Exemple : `GET https://qentrasystem.com/api/public/v1/webhooks`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "id": 3,
            "url": "https://mon-logiciel.ci/webhooks/qentra",
            "events": [
                "alert.created",
                "alert.resolved"
            ],
            "active": true,
            "failures": 0,
            "last_status": 200,
            "last_delivery_at": "2026-10-01T14:08:02Z",
            "created_at": "2026-09-30T10:00:00Z"
        }
    ]
}
```

### Créer un webhook

`POST /webhooks` (droit `webhooks:manage`)

Enregistre une adresse HTTPS publique. Le secret de signature n’est renvoyé qu’à la création.

Paramètres :
- `url` (adresse HTTPS, obligatoire) : Adresse de votre serveur (les adresses internes sont refusées).
- `events` (liste, obligatoire) : alert.created, alert.resolved, command.sent.

Exemple : `POST https://qentrasystem.com/api/public/v1/webhooks`

Corps :
```json
{
    "url": "https://mon-logiciel.ci/webhooks/qentra",
    "events": [
        "alert.created",
        "alert.resolved"
    ]
}
```

Réponse :
```json
{
    "success": true,
    "data": {
        "id": 3,
        "url": "https://mon-logiciel.ci/webhooks/qentra",
        "events": [
            "alert.created",
            "alert.resolved"
        ],
        "active": true,
        "failures": 0,
        "last_status": null,
        "last_delivery_at": null,
        "created_at": "2026-10-01T14:20:00Z",
        "secret": "whsec_…"
    },
    "meta": {
        "notice": "Conservez ce secret : il ne sera plus jamais affiché."
    }
}
```

### Tester un webhook

`POST /webhooks/3/test` (droit `webhooks:manage`)

Envoie un événement test.ping signé à votre adresse.

Exemple : `POST https://qentrasystem.com/api/public/v1/webhooks/3/test`

Réponse :
```json
{
    "success": true,
    "data": {
        "event_id": "5b0c7e2a-1f7d-4a38-9a51-0c8a2b7d1e44",
        "status": "queued"
    }
}
```

### Historique des envois

`GET /webhooks/3/deliveries` (droit `webhooks:manage`)

Les 50 derniers envois d’un webhook, avec le code HTTP reçu.

Exemple : `GET https://qentrasystem.com/api/public/v1/webhooks/3/deliveries`

Réponse :
```json
{
    "success": true,
    "data": [
        {
            "event_id": "5b0c7e2a-1f7d-4a38-9a51-0c8a2b7d1e44",
            "event": "test.ping",
            "status": "success",
            "attempts": 1,
            "response_code": 200,
            "error": null,
            "created_at": "2026-10-01T14:20:01Z",
            "delivered_at": "2026-10-01T14:20:02Z"
        }
    ]
}
```

### Supprimer un webhook

`DELETE /webhooks/3` (droit `webhooks:manage`)

Arrête définitivement les envois vers cette adresse.

Exemple : `DELETE https://qentrasystem.com/api/public/v1/webhooks/3`

Réponse :
```json
{
    "success": true,
    "data": {
        "deleted": true,
        "id": 3
    }
}
```

## Webhooks

Requête POST JSON envoyée à votre adresse HTTPS publique pour chaque événement.

- `alert.created` : Nouvelle alerte
- `alert.resolved` : Alerte résolue
- `command.sent` : Commande moteur envoyée
- `test.ping` : envoi de test

Contenu : `{"id":"<uuid>","type":"alert.created","created_at":"2026-10-01T14:08:01Z","data":{ alerte au format de GET /alerts + "vehicle":{"id","name","plate"} }}`

En-têtes : `Qentra-Signature: t=<horodatage>,v1=<hex>`, `Qentra-Event`, `Qentra-Delivery` (identifiant unique de l’envoi), `User-Agent: Qentra-Webhooks/1.0`.

Signature : `v1 = hex(HMAC_SHA256(secret_whsec, t + "." + corps_brut))`. Comparer à temps constant et refuser si l’horodatage a plus de 300 secondes.

Nouvelles tentatives si la réponse n’est pas 2xx : 5 fois (1 min, 5 min, 30 min, 2 h, 6 h). Désactivation après 20 échecs consécutifs.

## Codes d’erreur

| Code | HTTP | Signification | Que faire |
|---|---|---|---|
| `missing_api_key` | 401 | En-tête Authorization absent. | Ajoutez « Authorization: Bearer qsk_… ». |
| `invalid_api_key` | 401 | Clé inconnue ou mal recopiée. | Vérifiez la clé, sans espace ni retour à la ligne. |
| `revoked_api_key` | 401 | Clé révoquée. | Créez une nouvelle clé dans votre espace. |
| `expired_api_key` | 401 | Clé expirée. | Créez une nouvelle clé dans votre espace. |
| `account_disabled` | 403 | Compte désactivé. | Contactez le service client. |
| `ip_not_allowed` | 403 | Appel depuis une IP non autorisée pour cette clé. | Ajoutez l’IP de votre serveur à la clé. |
| `insufficient_scope` | 403 | La clé n’a pas le droit nécessaire (indiqué dans required_scope). | Créez une clé avec ce droit. |
| `forbidden` | 403 | Le compte n’est pas autorisé à cette action. | Demandez l’autorisation à votre gestionnaire. |
| `vehicle_not_found` | 404 | Véhicule inconnu ou absent de ce compte. | Utilisez un id renvoyé par /vehicles. |
| `webhook_not_found` | 404 | Webhook inconnu. | Utilisez un id renvoyé par /webhooks. |
| `route_not_found` | 404 | Adresse ou méthode inconnue. | Vérifiez l’adresse et la méthode (GET, POST, DELETE). |
| `vehicle_moving` | 409 | Coupure moteur refusée : le véhicule roule (vitesse dans speed_kmh). | Réessayez quand le véhicule est à l’arrêt. |
| `validation_failed` | 422 | Paramètre manquant ou invalide (détail par champ dans fields). | Corrigez les champs indiqués. |
| `period_too_long` | 422 | Période supérieure au maximum (max_days). | Découpez la période. |
| `too_many_points` | 422 | Trop de points GPS sur la période. | Réduisez la période. |
| `invalid_webhook_url` | 422 | Adresse refusée : pas en HTTPS, interne ou introuvable. | Utilisez une adresse HTTPS publique. |
| `limit_reached` | 422 | Nombre maximal de webhooks atteint. | Supprimez un webhook inutilisé. |
| `share_limit_reached` | 422 | Trop de liens de partage actifs pour ce véhicule. | Révoquez un lien existant. |
| `command_unavailable` | 422 | Commande non disponible sur la plateforme. | Contactez le service client. |
| `service_required` | 402 | Service non souscrit pour ce véhicule (option indiquée dans feature). | Activez le service dans votre espace, rubrique Abonnement. |
| `rate_limited` | 429 | Plus de 60 requêtes par minute (attente dans retry_after). | Attendez le délai indiqué par l’en-tête Retry-After. |
| `quota_exceeded` | 429 | Quota du mois (ou du jour en test) atteint (reprise dans resets_at). | Attendez la remise à zéro ou contactez-nous. |
| `command_failed` | 502 | Le boîtier n’a pas accepté la commande. | Vérifiez que le boîtier est en ligne, puis réessayez. |
| `gps_unavailable` | 503 | Serveur GPS momentanément indisponible. | Réessayez après quelques secondes. |

Selon votre outil

Claude

Dans Claude, créez un projet et ajoutez le fichier qentra-api.md à ses connaissances, ou collez le prompt de départ dans la conversation. Avec Claude Code, enregistrez le fichier à la racine du projet sous le nom CLAUDE.md.

ChatGPT

Créez un projet ou un GPT personnalisé et ajoutez-y le fichier qentra-api.md, ou collez le prompt de départ. Avec Codex, enregistrez le fichier sous le nom AGENTS.md à la racine du dépôt.

Gemini

Créez un Gem et ajoutez le fichier dans ses connaissances, ou collez le prompt de départ. Avec Gemini CLI, enregistrez le fichier sous le nom GEMINI.md.

Cursor, Windsurf, Copilot

Placez le fichier dans les règles du projet : .cursor/rules/qentra.md pour Cursor, les règles de l’espace de travail pour Windsurf, .github/copilot-instructions.md pour GitHub Copilot.

Lovable, Bolt, v0

Collez le prompt de départ en premier message. Exigez que les appels à l’API passent par une fonction côté serveur : la clé ne doit jamais se retrouver dans le code du navigateur.

Récupérer le fichier directement dans votre projet :

curl -o CLAUDE.md https://qentrasystem.com/developpeurs/qentra-api.md   # Claude Code
curl -o AGENTS.md https://qentrasystem.com/developpeurs/qentra-api.md   # Codex
curl -o GEMINI.md https://qentrasystem.com/developpeurs/qentra-api.md   # Gemini CLI

Prompts prêts à l’emploi

Envoyez d’abord le prompt de départ (ou le fichier), puis l’un de ces prompts. Remplacez les choix entre crochets.

Carte de la flotte en direct

Une page web avec tous les véhicules sur une carte, rafraîchie automatiquement.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), crée une page web qui affiche tous mes véhicules sur une carte Leaflet (OpenStreetMap).
- Un petit serveur [Node.js / PHP / Python] appelle GET /positions toutes les 20 secondes avec la clé lue dans QENTRA_API_KEY et expose une route /api/flotte à la page. La clé ne doit jamais arriver dans le navigateur.
- Un marqueur par véhicule, vert s’il roule, gris s’il est arrêté, avec le nom, la vitesse et l’heure de la dernière position.
- Une liste latérale cliquable pour centrer la carte sur un véhicule.
- Gère les erreurs rate_limited et gps_unavailable sans planter la page.
Donne-moi tous les fichiers et les commandes pour lancer le projet.

Rapport kilométrique mensuel

Distance, vitesse maximale et heures moteur par véhicule, exportés en Excel.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), écris un script [Python / PHP / Node.js] qui produit le rapport du mois précédent pour tous mes véhicules.
- Récupère la liste avec GET /vehicles, puis GET /vehicles/{id}/summary?daily=1 en découpant le mois en périodes de 7 jours au plus.
- Une ligne par véhicule et par jour : date, véhicule, plaque, distance (km), vitesse moyenne, vitesse maximale, heures moteur, puis un total par véhicule.
- Exporte en fichier Excel (.xlsx) nommé rapport-AAAA-MM.xlsx.
- Respecte la limite de requêtes par minute et réessaie après Retry-After en cas d’erreur 429.
Explique comment le lancer automatiquement le 1er de chaque mois.

Alertes par e-mail ou Telegram

Un webhook qui reçoit les alertes et les transmet à votre équipe.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), crée un petit serveur [Node.js Express / PHP / Python Flask] qui reçoit les webhooks alert.created.
- Vérifie la signature Qentra-Signature avec le secret lu dans QENTRA_WEBHOOK_SECRET, à temps constant, et refuse les envois de plus de 5 minutes.
- Ignore les doublons grâce à l’en-tête Qentra-Delivery.
- Répond 200 tout de suite, puis envoie un message [e-mail / Telegram] avec le type d’alerte, le véhicule, l’heure locale (Africa/Abidjan) et un lien Google Maps vers la position.
- Ajoute le script curl qui enregistre ce webhook avec POST /webhooks et celui qui le teste avec POST /webhooks/{id}/test.
Indique comment l’héberger avec une adresse HTTPS publique.

Synchronisation Google Sheets

Les positions et les alertes copiées dans un tableur, sans serveur.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), écris un script Google Apps Script pour un Google Sheets.
- La clé est enregistrée dans les propriétés du script (PropertiesService), jamais dans une cellule.
- Un onglet « Positions » mis à jour toutes les 15 minutes avec GET /positions : véhicule, latitude, longitude, vitesse, contact, heure.
- Un onglet « Alertes » qui ajoute les nouvelles alertes de GET /alerts?status=all sans créer de doublons (utilise l’id).
- Un menu « Qentra » pour lancer la mise à jour à la main.
Explique pas à pas comment installer le script et le déclencheur automatique.

Intégration dans un site Laravel

Un service propre et testé pour votre application Laravel.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), intègre l’API dans mon application Laravel.
- Une classe App\Services\QentraClient basée sur le client HTTP de Laravel : URL et clé dans config/services.php, lues depuis .env (QENTRA_API_KEY).
- Une méthode par route (vehicles, positions, history, trips, alerts…) qui renvoie data ou lève une exception QentraException contenant error.code et request_id.
- Réessais automatiques pour 429, 502 et 503 seulement, et cache de 15 secondes sur /positions.
- Un contrôleur de webhook qui vérifie la signature et déclenche un événement Laravel.
- Des tests avec Http::fake().
Donne le code fichier par fichier.

Extension WordPress

Un shortcode pour afficher un véhicule ou un lien de suivi sur votre site.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), crée une extension WordPress « Qentra Suivi ».
- Une page de réglages réservée aux administrateurs pour saisir la clé (stockée dans les options, jamais affichée en clair après enregistrement).
- Un shortcode [qentra_vehicule id="9001"] qui affiche le nom, le statut et la dernière position sur une petite carte, avec un cache de 30 secondes (transients).
- Tous les appels se font côté serveur avec wp_remote_get.
- Les erreurs s’affichent proprement aux administrateurs et restent invisibles pour les visiteurs.
Donne la structure des fichiers et le code complet.

Application mobile Flutter

Une application qui passe par votre serveur, sans exposer la clé.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), crée une application Flutter de suivi de mes véhicules.
- L’application n’appelle jamais l’API Qentra directement : elle passe par mon propre serveur [Laravel / Node.js], qui ajoute la clé et filtre les données de chaque utilisateur.
- Écran liste des véhicules avec statut et vitesse, écran carte (flutter_map), écran historique du jour avec le tracé.
- Rafraîchissement toutes les 20 secondes uniquement quand l’écran est visible.
Donne d’abord le code du serveur intermédiaire, puis celui de l’application.

Lien de suivi pour vos clients

Envoyez à un client un lien de suivi temporaire de sa livraison.

En suivant la documentation de l’API Qentra System (fichier qentra-api.md ou prompt de départ), ajoute à mon logiciel de livraison [précise : Laravel, Node.js, autre] un bouton « Envoyer le suivi au client ».
- Au clic, appelle POST /vehicles/{id}/shares avec duration 6h et un label contenant le numéro de commande.
- Envoie l’url renvoyée au client par [e-mail / SMS] avec l’heure d’expiration en heure locale.
- Gère l’erreur share_limit_reached avec un message clair pour l’opérateur.
Donne le code et un exemple de message au client.

Les règles que l’assistant doit suivre

Elles sont déjà dans le prompt de départ. Vérifiez que le code produit les respecte avant de passer en production.

  • La clé API reste côté serveur, dans une variable d’environnement QENTRA_API_KEY. Jamais dans le navigateur, une application mobile, une capture d’écran ou un dépôt Git.
  • Commencer avec une clé de test qsk_test_ (véhicules simulés 9001, 9002 et 9003), puis passer à une clé qsk_live_ sans changer le code.
  • Toujours lire le champ success, puis error.code en cas d’échec. Ne jamais baser la logique sur error.message.
  • Respecter 60 requêtes par minute et par clé. Sur une erreur 429, attendre la durée de l’en-tête Retry-After. Réessayer avec un délai croissant uniquement pour 429, 502 et 503.
  • Ne pas appeler /positions plus d’une fois toutes les 15 secondes. Utiliser les webhooks pour les alertes au lieu d’interroger en boucle.
  • Historique : 7 jours au plus par appel. Découper les périodes plus longues.
  • Webhooks : vérifier la signature Qentra-Signature (HMAC-SHA256 de « t.corps_brut » avec le secret whsec_) par comparaison à temps constant, refuser les envois de plus de 5 minutes, répondre 2xx en moins de 10 secondes, dédoublonner avec Qentra-Delivery.
  • Commandes moteur : demander une confirmation explicite à l’utilisateur dans l’interface, envoyer {"confirm":true} et gérer l’erreur vehicle_moving.
  • N’utiliser que les routes et les champs décrits dans ce document. Ne rien inventer : en cas de doute, demander.

Questions fréquentes

Faut-il savoir programmer pour utiliser ces prompts ?

Non. L’assistant écrit le code et vous guide. Il vous faut seulement une clé de test, créée dans votre espace client, et un endroit où lancer le projet.

Puis-je donner ma clé API à l’assistant ?

Ne collez jamais une clé qsk_live_ dans une conversation. Le code lit la clé dans une variable d’environnement, que vous renseignez vous-même. Si une clé a été partagée par erreur, révoquez-la dans votre espace.

Pourquoi fournir le fichier qentra-api.md ?

Il contient toute la documentation de l’API dans un format que les assistants lisent bien. Avec lui, l’assistant utilise les vraies routes et les vrais champs au lieu de les deviner.

Le fichier est-il à jour ?

Oui. Il est généré automatiquement depuis la documentation officielle : téléchargez-le à nouveau au début de chaque projet.

Besoin du détail d’une route ? Consultez la documentation complète.