API Partenaires Pikoli
Tout ce qu'il vous faut pour intégrer Pikoli dans votre tunnel de vente : créer des commandes, suivre les livraisons, recevoir les webhooks de statut. Cette page documente uniquement les endpoints accessibles aux partenaires marchands B2B.
Vue d'ensemble
L'API Pikoli est une API REST classique. Toutes les requêtes utilisent JSON, sauf mention contraire. Toutes les réponses contiennent un objet JSON, ou un corps d'erreur standardisé décrit dans la section Codes d'erreur.
Idempotency-Key sur POST /orders /api/v1/... stable Authentification
Chaque partenaire reçoit deux clés à la création de son compte API :
pk_test_… (sandbox) et
pk_live_… (production). Passez la clé dans le
header Authorization: Bearer de chaque requête.
curl https://api.pikoli.fr/api/v1/partners/quote \
-H "Authorization: Bearer pk_live_••••••••••" \
-H "Content-Type: application/json" pk_live_* donne l'accès à votre
compte facturable. Ne la commitez jamais dans git et ne l'exposez pas côté
navigateur — utilisez-la depuis votre serveur uniquement.
Devis · POST /partners/quote
Calcule le prix d'une livraison sans rien créer. Idéal pour afficher le coût dans votre checkout avant que le client ne valide.
Requête
POST https://api.pikoli.fr/api/v1/partners/quote
Authorization: Bearer pk_live_••••
Content-Type: application/json
{
"pickup_quartier_id": "a4f3c2d8-...",
"dropoff_quartier_id": "b1e9f0aa-...",
"weight_kg": 2.5,
"mode": "direct"
} Réponse 200 OK
{
"price_cents": 250000,
"distance_m": 4830,
"duration_s": 720,
"weight_surcharge_cents": 0,
"mode_multiplier": 1.0,
"branch": "intra_arrondissement",
"escale_count": 0
} | Champ | Type | Description |
|---|---|---|
pickup_quartier_id | UUID | Quartier de retrait (cf. référentiel) |
dropoff_quartier_id | UUID | Quartier de livraison |
weight_kg | number | Poids estimé en kg (max 30) |
mode | enum | direct · relay · express |
Créer une commande · POST /partners/orders
Crée et planifie une livraison. La commande est facturée mensuellement (vous ne
payez pas à la création). Le champ Idempotency-Key est fortement
recommandé pour protéger contre les retries.
POST https://api.pikoli.fr/api/v1/partners/orders
Authorization: Bearer pk_live_••••
Idempotency-Key: order-2026-05-21-acme-4711
{
"pickup": {
"address": "Marché Central, N'Djamena",
"lat": 12.1098, "lng": 15.0461,
"quartier_id": "a4f3..."
},
"dropoff": {
"address": "Quartier Klemat, lot 14",
"lat": 12.1180, "lng": 15.0530,
"quartier_id": "b1e9..."
},
"recipient": {
"name": "Awa Mahamat",
"phone": "+23566010203"
},
"weight_kg": 2.5,
"mode": "direct",
"cod_amount_cents": 1500000,
"notes": "Sonner deux fois"
} Réponse 201 Created
{
"nc": "NC-A92F",
"tracking_url": "https://app.pikoli.fr/track/NC-A92F",
"price_cents": 250000,
"payment_required": false,
"created_at": "2026-05-21T08:42:11Z"
} Lister les commandes · GET /partners/orders
Liste paginée par curseur (pas d'offset). Filtrable par statut et par plage de dates.
GET https://api.pikoli.fr/api/v1/partners/orders?status=in_transit&limit=50
Authorization: Bearer pk_live_•••• | Paramètre | Description |
|---|---|
status | created, assigned, in_transit, delivered, cancelled |
cursor | Curseur de pagination renvoyé dans next_cursor |
limit | 1 à 100 (défaut 25) |
created_after | ISO-8601, inclusif |
created_before | ISO-8601, exclusif |
Détail d'une commande · GET /partners/orders/{nc}
GET https://api.pikoli.fr/api/v1/partners/orders/NC-A92F
Authorization: Bearer pk_live_•••• Réponse : statut courant, historique d'événements, position du livreur (si en cours), preuve de livraison (photo + signature) une fois la course terminée.
Référentiel quartiers · GET /partners/quartiers
Liste tous les quartiers couverts par Pikoli, avec leur UUID, leur arrondissement et leur centroïde. À mettre en cache (mise à jour rare). Aujourd'hui 48 quartiers actifs à N'Djamena répartis sur 10 arrondissements.
GET https://api.pikoli.fr/api/v1/partners/quartiers
Authorization: Bearer pk_live_••••
# Réponse (extrait)
[
{
"id": "a4f3c2d8-...",
"name": "Klemat",
"arrondissement": { "id": "9b1a...", "name": "1er", "city": "N'Djamena" },
"centroid": { "lat": 12.1180, "lng": 15.0530 }
},
...
] Webhooks
Pikoli pousse les événements de cycle de vie vers une URL HTTPS que vous
configurez depuis votre portail partenaire. Chaque payload est signé HMAC-SHA256
avec votre webhook_secret dans le header X-Pikoli-Signature.
Événements émis
| Événement | Quand |
|---|---|
order.created | Création d'une commande |
order.assigned | Un livreur accepte la course |
order.in_transit | Le retrait a eu lieu |
order.delivered | Remise + preuve photo signée |
order.cancelled | Annulation client / livreur / admin |
invoice.generated | Facture mensuelle disponible |
Payload (exemple)
POST https://votre-domaine.com/pikoli-webhook
X-Pikoli-Signature: sha256=ab12cd34…
Content-Type: application/json
{
"id": "evt_8f3a...",
"type": "order.delivered",
"created_at": "2026-05-21T09:15:02Z",
"data": {
"nc": "NC-A92F",
"delivered_at": "2026-05-21T09:14:45Z",
"proof_url": "https://cdn.pikoli.fr/proofs/...",
"signature_url": "https://cdn.pikoli.fr/signatures/..."
}
} Vérification de la signature
import hmac, hashlib
def verify(signature_header: str, body: bytes, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(
signature_header.removeprefix("sha256="),
expected,
) Codes d'erreur
Toutes les erreurs suivent le format suivant :
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": { ... }
}
} | HTTP | Code | Cause |
|---|---|---|
| 400 | VALIDATION_ERROR | Body / params invalides |
| 401 | INVALID_API_KEY | Clé manquante, invalide ou révoquée |
| 403 | FORBIDDEN | Accès non autorisé à cette ressource |
| 404 | NOT_FOUND | Ressource inexistante |
| 409 | CONFLICT | Idempotency-Key réutilisée avec un body différent |
| 422 | VALIDATION_ERROR | Schéma incorrect (champ manquant, type, taille) |
| 429 | RATE_LIMITED | Quota dépassé — voir header Retry-After |
| 500 | INTERNAL_ERROR | Erreur serveur — réessayez avec backoff |
Sandbox & support
Une fois votre demande d'accès validée, vous recevez par email vos deux clés
pk_test_… et pk_live_…. La sandbox utilise la même base
URL (https://api.pikoli.fr/api/v1) — c'est la clé qui détermine le mode. Les
commandes en sandbox ne déclenchent pas de livraison réelle et ne sont pas
facturées.