L'API publique tibida v1 : boutiques, catalogue, commandes, réservations et fidélité. Clés à portées granulaires, prix calculés côté serveur, webhooks signés.
Les clés API sont délivrées par le commerçant, dans son Admin → Clés API. Chaque clé a ses portées et son périmètre de boutiques.
Le commerçant crée une clé dans Admin → Clés API et vous la transmet. Elle commence par tib_live_.
Envoyez la clé dans l'en-tête Authorization: Bearer (ou X-API-Key).
Base : https://app.tibida.com/api/v1. Les prix sont toujours calculés côté serveur.
curl -s https://app.tibida.com/api/v1/outlets \
-H "Authorization: Bearer VOTRE_CLE"curl -s -X POST https://app.tibida.com/api/v1/orders \
-H "Authorization: Bearer VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"outlet_id":1,"customer_name":"Awa Diallo",
"customer_phone":"+221771234567","type":"pickup",
"items":[{"product_id":54,"qty":2}]}'Généré depuis la spécification openapi.json (OpenAPI 3.1). Toutes les erreurs suivent l'enveloppe {"error": "<code>", "message": "…"}.
Recevez order.created, order.cancelled, reservation.created et reservation.cancelled. Chaque livraison est signée et peut être vérifiée.
| En-tête | Contenu |
|---|---|
Tibida-Event | nom de l'événement |
Tibida-Timestamp | secondes Unix |
Tibida-Signature | HMAC-SHA256 hexadécimal |
Tibida-Delivery | identifiant unique de livraison |
Signature = HMAC_SHA256(secret, timestamp + "." + corps_brut). Rejetez tout horodatage vieux de plus de 5 minutes (anti-rejeu). 3 tentatives de livraison (0 s, 5 s, 30 s), délai d'attente 10 s.
const crypto = require('crypto');
function verifyWebhook(secret, timestamp, rawBody, signature) {
// Anti-rejeu : 5 minutes max
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + rawBody, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected, 'utf8'),
Buffer.from(signature, 'utf8')
);
}import hmac, hashlib, time
def verify_webhook(secret: str, timestamp: str, raw_body: bytes, signature: str) -> bool:
# Anti-rejeu : 5 minutes max
if abs(time.time() - int(timestamp)) > 300:
return False
expected = hmac.new(
secret.encode(), f'{timestamp}.'.encode() + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)function verifyWebhook(string $secret, string $timestamp, string $rawBody, string $signature): bool {
// Anti-rejeu : 5 minutes max
if (abs(time() - (int) $timestamp) > 300) return false;
$expected = hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
return hash_equals($expected, $signature);
}Envoyez Idempotency-Key sur les POST de création (commandes, réservations, points). Rejouer la même clé avec le même corps renvoie la réponse d'origine, sans créer de doublon. Un corps différent → 422.
Chaque clé a sa propre limite (requêtes/minute, configurable par le commerçant). Dépassement → 429. Les clés de test sont plus strictement limitées.
| HTTP | Code | Sens |
|---|---|---|
400 | parametres_invalides | champ manquant ou invalide |
401 | cle_api_manquante · cle_api_invalide · cle_api_revoquee · cle_api_expiree | authentification |
403 | portee_insuffisante · boutique_hors_perimetre | autorisation (fail-closed) |
404 | commande_introuvable · produit_introuvable … | ressource inexistante ou hors périmètre |
409 | commande_deja_annulee | conflit d'état |
422 | cle_idempotence_reutilisee | clé d'idempotence réutilisée avec un autre corps |
429 | limite_debit_depassee | trop de requêtes |
L'API v1 est du REST standard : elle fonctionne avec n'importe quel client HTTP. Utilisez la collection Postman ci-dessus ou appelez-la depuis Activepieces, n8n ou Make avec un nœud HTTP générique.
GET https://app.tibida.com/api/v1/products?outlet_id=1&limit=50
Authorization: Bearer VOTRE_CLE