Pedalel Delivery API
Branche ta plateforme sur la flotte de livreurs Pedalel. Quand tu as une commande prête, tu appelles l'API : Pedalel affecte automatiquement le livreur le plus proche et te renvoie chaque changement de statut en temps réel. Pensé pour les restaurants et marketplaces (KFC, Yassir…) et pour les supermarchés (le livreur fait les achats, façon personal shopper).
https://api.pedalel.sn/v1https://sandbox.api.pedalel.sn/v1Comment ça marche
Le partenaire n'installe rien : il appelle l'API depuis son back-office. Pedalel gère les livreurs, la carte, le dispatch et le suivi.
Brancher en 4 étapes
sk_test_ par sk_live_. C'est tout.Authentification
Chaque partenaire a une clé d'API secrète, envoyée dans l'en-tête Authorization. Les clés de test commencent par sk_test_, celles de production par sk_live_. Ne jamais exposer la clé côté client.
# Toutes les requêtes Authorization: Bearer sk_live_pedalel_kfc_9f2a... Content-Type: application/json
Devis (optionnel)
POST/quotes — connaître le prix et le délai avant de créer la course.
curl https://api.pedalel.sn/v1/quotes \ -H "Authorization: Bearer sk_live_..." \ -d 'type=package' \ -d 'dropoff[address]=Ouakam, Rue 27, Dakar' // réponse { "fee_fcfa": 1500, "eta_minutes": 22, "distance_km": 5.5, "currency": "XOF" }
Créer une livraison
POST/deliveries — le cœur de l'intégration. Exemple : une commande KFC prête à récupérer.
curl https://api.pedalel.sn/v1/deliveries \
-H "Authorization: Bearer sk_live_..." \
-H "Idempotency-Key: KFC-2026-0098" \
-H "Content-Type: application/json" \
-d '{
"external_id": "KFC-2026-0098",
"type": "package",
"reference": "B7C1", // n° vérifié au retrait
"pickup": {
"name": "KFC Almadies",
"address": "Route de Ngor, Almadies, Dakar",
"lat": 14.7440, "lng": -17.5150,
"phone": "+221771112233",
"instructions": "Commande prête au comptoir, réf B7C1"
},
"dropoff": {
"name": "Awa Touré",
"address": "Ouakam, Cité Avion, Rue 27",
"lat": 14.7230, "lng": -17.4930,
"phone": "+221770009988"
},
"package": { "size": "medium", "value_fcfa": 6500 },
"payment": { "collect_on_delivery": true, "amount_fcfa": 6500, "method": "cash" },
"webhook_url": "https://kfc.example/pedalel/webhooks"
}'
// 201 Created { "id": "dlv_3f9a12", "external_id": "KFC-2026-0098", "type": "package", "status": "pending", "fee_fcfa": 1500, "eta_minutes": 22, "tracking_url": "https://track.pedalel.sn/dlv_3f9a12", "courier": null }
reference est affiché au livreur à l'étape de retrait pour qu'il prenne la bonne commande — indispensable quand il porte deux commandes.Corps de la requête
| Champ | Type | Description |
|---|---|---|
type | string | package commande prête · shopping le livreur fait les achats |
external_id | string | Ton identifiant de commande (renvoyé dans les webhooks). |
reference | string | N° vérifié au retrait. |
pickup | object | Point de retrait (adresse, lat/lng, téléphone). Requis pour package. |
dropoff | object | Adresse de livraison client. |
payment | object | Encaissement à la livraison (cash, wave, orange_money…). |
webhook_url | string | URL qui recevra les mises à jour de statut. |
Course supermarché (personal shopper)
Pour un supermarché/boutique, envoie type: "shopping" avec la liste d'achats. Le livreur va au magasin, scanne chaque code-barres, gère les ruptures (substitution) et passe en caisse — puis livre.
{
"external_id": "AUCHAN-88213",
"type": "shopping",
"store_id": "store_auchan_scr",
"dropoff": { "name": "Awa Touré", "address": "Ouakam, Rue 27", "lat": 14.7230, "lng": -17.4930 },
"items": [
{ "sku": "RIZ-PARF-5KG", "barcode": "6111234567", "name": "Riz parfumé 5 kg", "qty": 1, "unit_price_fcfa": 4500, "allow_substitute": true },
{ "sku": "HUILE-VEG-2L", "barcode": "6111234892", "name": "Huile végétale 2 L", "qty": 1, "unit_price_fcfa": 3200 }
],
"payment": { "collect_on_delivery": true, "method": "cash", "service_fee_fcfa": 1500 },
"webhook_url": "https://auchan.example/pedalel/webhooks"
}
Les substitutions (rupture → remplacement) sont renvoyées en temps réel par le webhook delivery.item_substituted, pour accord du client si besoin.
Suivre & annuler
GET/deliveries/{id} — état courant + position du livreur.
{
"id": "dlv_3f9a12",
"status": "en_route_dropoff",
"courier": { "name": "Moussa K.", "phone": "+2217...", "lat": 14.719, "lng": -17.487, "rating": 4.9 }
}
POST/deliveries/{id}/cancel — annuler tant que la course n'est pas récupérée.
Webhooks
Pedalel envoie un POST à ton webhook_url à chaque changement de statut. Vérifie l'en-tête X-Pedalel-Signature (HMAC-SHA256 du corps avec ta clé secrète de webhook), et réponds 2xx.
// POST vers ton webhook_url { "id": "evt_88c1", "type": "delivery.status_updated", "created_at": "2026-07-23T20:14:05Z", "data": { "id": "dlv_3f9a12", "external_id": "KFC-2026-0098", "status": "picked_up", "courier": { "name": "Moussa K." } } }
Événements
delivery.status_updated delivery.item_substituted delivery.courier_location delivery.delivered delivery.canceled
Catalogue magasin
Réservé aux partenaires magasin. PUT/catalog/products synchronise les produits (code-barres, prix, stock, photo). C'est ce catalogue qui alimente la liste de picking et la reconnaissance au scan côté livreur.
{
"store_id": "store_auchan_scr",
"products": [
{ "sku": "RIZ-PARF-5KG", "barcode": "6111234567", "name": "Riz parfumé 5 kg", "price_fcfa": 4500, "stock": 120, "image_url": "https://cdn.auchan/riz.jpg" }
]
}
Cycle de vie des statuts
| Statut | Signification |
|---|---|
pending | Créée, en attente d'affectation. |
assigned | Un livreur a accepté. |
en_route_pickup | En route vers le retrait / magasin. |
arrived_pickup | Arrivé au point de retrait. |
shopping_started | (shopping) Achats en cours en magasin. |
picked_up | Commande récupérée / achats payés. |
en_route_dropoff | En route vers le client. |
arrived_dropoff | Arrivé chez le client. |
delivered | Livré. Course terminée. |
canceled | Annulée. |
openapi.yaml (importable dans Postman / Swagger) pour que les développeurs de KFC, Yassir ou tes supermarchés génèrent leur intégration.