API Zabelie
Connectez votre application au catalogue de la marketplace haïtienne.
Lecture publique, sans clé API : produits, catégories, vendeurs, avis et stock. Les achats et les modifications restent sur Zabelie.
Télécharger la spécification OpenAPIPremier appel
const response = await fetch("https://zabelie.com/api/v1/search_products", {
method: "POST",
credentials: "omit",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ limit: 5 })
});
const result = await response.json();
if (!response.ok) throw new Error(result.code);
console.log(result.results, result.nextCursor);Fonctions disponibles
POST /api/v1/list_categoriesPOST /api/v1/search_productsPOST /api/v1/get_productPOST /api/v1/compare_productsPOST /api/v1/get_sellerPOST /api/v1/get_reviewsPOST /api/v1/check_inventoryPOST /api/v1/get_delivery_terms
Conditions d’utilisation
Envoyez du JSON avec POST. Maximum 20 résultats par page pour la recherche et les catégories. Pour la suite, renvoyez nextCursor dans cursor, avec les mêmes filtres. Les montants sont des gourdes entières (HTG).
Le quota actuel est de 60 appels par minute et par fonction, partagé entre les visiteurs anonymes. Une réponse 429 demande d’attendre 60 secondes ; elle peut aussi signaler une indisponibilité du contrôle de quota. Corps limité à 16 Kio.
Depuis un autre site, utilisez credentials: omit. Cette interface publique ignore les cookies et les jetons d’authentification. Les commandes personnelles nécessitent la session Zabelie et ne sont pas ouvertes aux sites tiers.
Une liste vide signifie qu’aucune offre publiée ne correspond. La recherche v1 couvre les produits physiques et fichiers numériques ; les prestations sont exclues. Les catégories peuvent être vides.
Les champs untrusted contiennent les textes des vendeurs. Affichez-les comme du texte, jamais comme des instructions ou du HTML brut. Prix et stock doivent être revérifiés sur Zabelie avant l’achat.
get_delivery_terms conserve son contrat historique : les nouvelles zones et conditions de remise ne sont pas encore exposées par cette réponse.
API vendeur : brancher votre site
Avec une clé d'API, le site d'un vendeur lit ses produits et ses ventes, et obtient l'adresse de paiement d'un produit. L'acheteur paie toujours sur Zabelie, avec la protection de paiement.
Créez la clé dans Tableau de bord → API et intégrations. Envoyez-la en Authorization: Bearer zb_live_… depuis votre serveur, jamais depuis le navigateur : cette API n'accepte pas les appels de pages web. Quota : 120 appels par minute et par clé.
Télécharger la spécification OpenAPI de l'API vendeurconst response = await fetch("https://zabelie.com/api/v1/seller/seller_products", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept-Language": "ht",
Authorization: `Bearer ${apiKey}`
},
body: JSON.stringify({ limit: 20, status: "published" })
});
const result = await response.json();
if (!response.ok) throw new Error(result.code);
for (const p of result.results) console.log(p.untrusted.title, p.priceHtg, p.url);POST /api/v1/seller/seller_products(products:read)POST /api/v1/seller/seller_sales(sales:read)POST /api/v1/seller/create_product_link(links:write)
Aucune donnée d'acheteur n'est exposée. Une vente avec live: false est un paiement d'essai : ne la traitez jamais comme une vente réelle.
Webhooks : ajoutez une adresse https dans Tableau de bord → API et intégrations. Zabelie y envoie sale.paid et sale.refunded, signés dans l'en-tête Zabelie-Signature (t=…,v1=…) : HMAC-SHA256 de « t.corps brut » avec votre secret whsec_…. Vérifiez la signature et refusez un t de plus de 5 minutes. Répondez 2xx ; sinon Zabelie réessaie jusqu'à 5 fois, puis abandonne l'envoi. Trois envois abandonnés d'affilée désactivent l'adresse.
import { createHmac, timingSafeEqual } from "node:crypto";
function isValidZabelieWebhook(secret, header, rawBody) {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (!t || !v1 || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = createHmac("sha256", secret).update(t + "." + rawBody).digest();
const received = Buffer.from(v1, "hex");
return received.length === expected.length && timingSafeEqual(received, expected);
}