Cette API est destinée aux sociétés de livraison partenaires de Havana Express. Elle vous permet de récupérer les colis que nous vous confions, mettre à jour leur statut et remonter les preuves de livraison.
Havana Express vous remet une clé privée sk_partner_….
Interrogez régulièrement GET /orders.
Postez le statut + preuve à chaque étape clé.
Version recommandée : un seul compte (email + mot de passe) donne un token Bearer valable 12 h, utilisable sur tous les endpoints. Aucun besoin de gérer des clés statiques.
https://www.havanaexpress.ma/api/public/v1JSON UTF-8. Codes : 200 succès · 207 aucun colis mis à jour · 400 validation · 401 token invalide/expiré · 403 compte désactivé · 404 colis introuvable · 429 quota dépassé (240 req/min) · 500 erreur serveur.
/api/public/v1/login_checkÉchange email + mot de passe contre un token Bearer valable 12 heures.
curl -X POST https://www.havanaexpress.ma/api/public/v1/login_check \
-H "Content-Type: application/json" \
-d '{"email":"api@partenaire.ma","password":"••••••••"}'{
"status": "success",
"token": "msl_9f3c…",
"token_type": "Bearer",
"expires_in": 43200,
"expires_at": "2026-08-29T02:20:11.000Z",
"partner": { "id": "…", "name": "Partenaire SARL" },
"user": { "id": "…", "email": "api@partenaire.ma", "name": "Intégration" }
}/api/public/v1/statusCodes acceptés par changeParcelStatus, avec les champs obligatoires par statut.
curl https://www.havanaexpress.ma/api/public/v1/status -H "Authorization: Bearer msl_9f3c…"{
"status": "success",
"count": 15,
"statuses": [
{ "code": "DELIVERED", "label_fr": "Livré", "category": "final", "required_fields": ["received_by"] }
]
}/api/public/v1/changeParcelStatusJusqu'à 50 colis par requête. Chaque ligne est traitée indépendamment : le résultat détaille les succès et les erreurs.
curl -X POST https://www.havanaexpress.ma/api/public/v1/changeParcelStatus \
-H "Authorization: Bearer msl_9f3c…" \
-H "Content-Type: application/json" \
-d '{
"parcels": [
{ "code": "AGA-2026-00012", "status": "DELIVERED",
"received_by": "Youssef B.", "cod_amount": 250,
"lat": 30.4278, "lng": -9.5981, "date": "2026-08-28 14:20:00" },
{ "code": "AGA-2026-00013", "status": "NO_ANSWER",
"status_comment": "Client injoignable 3 tentatives" }
]
}'{
"status": "success",
"updated": 2,
"failed": 0,
"results": [
{ "code": "AGA-2026-00012", "ok": true, "status": "DELIVERED", "label": "Livré" },
{ "code": "AGA-2026-00013", "ok": true, "status": "NO_ANSWER", "label": "Pas de réponse" }
]
}/api/public/v1/scanApplique le même statut à jusqu'à 200 codes (réception hub, départ en transit…).
curl -X POST https://www.havanaexpress.ma/api/public/v1/scan \
-H "Authorization: Bearer msl_9f3c…" \
-H "Content-Type: application/json" \
-d '{"codes":["AGA-2026-00012","AGA-2026-00013"],"status":"AT_ORIGIN_HUB"}'{
"status": "success",
"applied_status": "AT_ORIGIN_HUB",
"updated": 2,
"failed": 0,
"accepted": ["AGA-2026-00012", "AGA-2026-00013"],
"rejected": []
}/api/public/v1/parcelsPagination + filtres status, from, to, search (numéro ou téléphone).
curl "https://www.havanaexpress.ma/api/public/v1/parcels?status=IN_TRANSIT&page=1&per_page=50" \
-H "Authorization: Bearer msl_9f3c…"{
"status": "success",
"page": 1, "per_page": 50, "total": 128, "total_pages": 3,
"parcels": [
{ "code": "AGA-2026-00012", "status": "IN_TRANSIT", "recipient_name": "Salma A.",
"recipient_phone": "06…", "city": "Agadir", "cod_amount": 250 }
]
}/api/public/v1/parcels/{code}Toutes les informations du colis et la chronologie complète de ses statuts.
curl https://www.havanaexpress.ma/api/public/v1/parcels/AGA-2026-00012 -H "Authorization: Bearer msl_9f3c…"{
"status": "success",
"parcel": { "code": "AGA-2026-00012", "status": "DELIVERED", "received_by": "Youssef B." },
"history": [
{ "status": "PICKED_UP", "at": "2026-08-26T09:12:00Z" },
{ "status": "DELIVERED", "at": "2026-08-28T14:20:00Z" }
]
}/api/public/v1/logoutInvalide immédiatement le token courant.
curl -X POST https://www.havanaexpress.ma/api/public/v1/logout -H "Authorization: Bearer msl_9f3c…"{ "status": "success", "message": "Token revoked" }| Code | Libellé | Champs requis | Description |
|---|---|---|---|
| PICKED_UP | Ramassé · تم الاستلام | — | Le colis a été récupéré chez le marchand par le partenaire. |
| AT_ORIGIN_HUB | Reçu au Hub · وصل لمركز الانطلاق | — | Colis réceptionné et scanné dans l'entrepôt de départ. |
| IN_TRANSIT | Expédié · تم الإرسال | — | Colis expédié et en cours d'acheminement entre deux villes. |
| AT_DESTINATION_HUB | Reçu au hub de destination · وصل لمركز الوصول | — | Colis arrivé dans la ville de livraison. |
| ASSIGNED_DRIVER | En livraison · تم إسناده للموزع | — | Un livreur a été affecté au colis. |
| OUT_FOR_DELIVERY | En livraison · خارج للتوصيل | — | Le colis est sorti en distribution. |
| DELIVERED | Livré · تم التوصيل | received_by | Colis remis au destinataire. Le nom du réceptionnaire est obligatoire. |
| POSTPONED | Reporté · مؤجل | status_comment | Livraison reportée à la demande du destinataire. Motif obligatoire. |
| NO_ANSWER | Pas de réponse · لا يجيب | status_comment | Le destinataire ne répond pas. Motif obligatoire. |
| VOICEMAIL | Boîte vocale · المجيب الآلي | status_comment | Appel tombé sur la boîte vocale. Motif obligatoire. |
| OUT_OF_ZONE | Hors zone · خارج النطاق | status_comment | Adresse en dehors de la zone couverte. Motif obligatoire. |
| FAILED | Échec de livraison · فشل التوصيل | status_comment | Tentative de livraison échouée. Motif obligatoire. |
| RETURNED | Retourné · مرجع | status_comment | Colis renvoyé vers le marchand. Motif obligatoire. |
| REFUSED | Refusé · مرفوض | status_comment | Colis refusé par le destinataire. Motif obligatoire. |
| CANCELLED | Annulé · ملغى | status_comment | Commande annulée. Motif obligatoire. |
Les colis en statut DELIVERED ou CANCELLED sont définitifs et ne peuvent plus être modifiés via l'API.
Sur demande, Havana Express appelle votre URL à chaque changement de statut. Vérifiez la signature avant de traiter le payload.
POST https://votre-domaine.ma/webhooks/havana-express
X-Havana Express-Event: parcel.status_changed
X-Havana Express-Signature: sha256=<hmac_sha256(secret, corps_brut)>
{
"event": "parcel.status_changed",
"sent_at": "2026-08-28T14:20:11.000Z",
"data": { "code": "AGA-2026-00012", "status": "DELIVERED", "received_by": "Youssef B." }
}https://www.havanaexpress.ma/api/public/partnersJSON UTF-8. Codes : 200/201 succès, 400 validation, 401 clé invalide, 403 compte désactivé, 404 colis non assigné, 500 erreur serveur.
Ajoutez votre clé partenaire à chaque requête :
x-api-key: sk_partner_xxxxxxxxxxxxxxxxxxxxxxxxxxxxRenvoie uniquement les colis que Havana Express vous a confiés. Filtres : status, limit (1-200), offset.
/api/public/partners/orders?status=picked_up&limit=50{
"ok": true,
"count": 12,
"limit": 50,
"offset": 0,
"orders": [
{
"tracking_number": "FX-2026-00123",
"status": "in_transit",
"recipient_name": "Ali Bennani",
"recipient_phone": "0612345678",
"delivery_city": "Casablanca",
"delivery_address": "Rue Mohammed V, 12",
"cod_amount": 250,
"weight_kg": 1.2
}
]
}Informations complètes + historique (events).
/api/public/partners/orders/{tracking_number}{
"ok": true,
"order": {
"tracking_number": "FX-2026-00123",
"status": "in_transit",
"sender_name": "Boutique Atlas",
"recipient_name": "Ali Bennani",
"recipient_phone": "0612345678",
"delivery_city": "Casablanca",
"delivery_address": "Rue Mohammed V, 12",
"cod_amount": 250
},
"events": [ { "status": "in_transit", "message": "...", "created_at": "..." } ]
}Statuts autorisés : pending, picked_up, received_origin_hub, in_transit, received_destination_hub, assigned_driver, out_for_delivery, delivered, postponed, failed, returned, cancelled.
/api/public/partners/orders/{tracking_number}/statuscurl -X POST https://www.havanaexpress.ma/api/public/partners/orders/FX-2026-00123/status \
-H "x-api-key: sk_partner_..." \
-H "Content-Type: application/json" \
-d '{
"status": "delivered",
"received_by": "Ali Bennani",
"signature_url": "https://cdn.example.com/sign/abc.png",
"pod_photo_url": "https://cdn.example.com/pod/abc.jpg",
"delivery_lat": 33.5731,
"delivery_lng": -7.5898
}'{ "ok": true, "tracking_number": "FX-2026-00123", "status": "delivered" }Indiquez la raison dans le champ reason. Le client en sera notifié automatiquement.
/api/public/partners/orders/{tracking_number}/status{
"status": "failed",
"reason": "Destinataire injoignable, 3 tentatives"
}{ "ok": true, "tracking_number": "FX-2026-00123", "status": "failed" }pendingCréé, en attente de ramassagepicked_upRamassé chez l'expéditeurreceived_origin_hubReçu au Hubin_transitExpédiéreceived_destination_hubArrivé au Hub de destinationassigned_driverAffecté à un livreurout_for_deliveryEn cours de livraisondeliveredLivré ✅ (joindre POD)postponedReportéfailedÉchec (joindre raison)returnedRetourné expéditeurcancelledAnnulésk_partner_…. Conservez-la côté serveur uniquement.GET /orders.signature_url ou pod_photo_url.delivery_lat, delivery_lng) renforcent la preuve de livraison.Notre équipe technique vous accompagne pour brancher votre TMS ou app mobile.
Contacter l'équipe