API Kountabl
Accédez à vos données Kountabl par programmation. API REST en lecture seule avec authentification par clé API.
Authentification
Générez une clé API dans Paramètres > Administration > API. Chaque clé commence par le préfixe mk_live_ et est liée à votre entreprise.
Envoyez la clé dans le header Authorization :
Authorization: Bearer mk_live_your_api_key_hereExemple cURL
curl -H"Authorization: Bearer mk_live_your_key" \
https://kountabl.com/api/v1/invoicesExemple JavaScript
const res = await fetch('https://kountabl.com/api/v1/invoices', {
headers: {
'Authorization': 'Bearer mk_live_your_key',
'Content-Type': 'application/json',
},
});
const { data, meta } = await res.json();
console.log(data); // Array of invoices
console.log(meta); // { page, per_page, total, total_pages }Rate Limiting
L'API est limitée à 100 requêtes par minute par clé API. Les headers suivants sont inclus dans chaque réponse :
| Paramètre | Type | Requis | Description |
|---|---|---|---|
| X-RateLimit-Limit | number | Non | Nombre maximum de requêtes par fenêtre (100) |
| X-RateLimit-Remaining | number | Non | Requêtes restantes dans la fenêtre courante |
| X-RateLimit-Reset | number | Non | Timestamp Unix de la prochaine remise à zéro |
429 Too Many Requests avec un header Retry-After indiquant le nombre de secondes à attendre.Endpoints
Tous les endpoints suivent le format /api/v1/{entity}. Les réponses utilisent une enveloppe standard avec data et meta.
Factures (Invoices)
GET /api/v1/invoices
GET /api/v1/invoices/:id
| Paramètre | Type | Requis | Description |
|---|---|---|---|
| page | number | Non | Numéro de page (défaut : 1) |
| per_page | number | Non | Éléments par page (défaut : 20, max : 100) |
| status | string | Non | Filtrer par statut: draft, final, cancelled |
| date_from | string | Non | Date de début (YYYY-MM-DD) |
| date_to | string | Non | Date de fin (YYYY-MM-DD) |
Exemple de réponse
{
"data": [
{
"id":"a1b2c3d4-...",
"invoice_number":"2026-0001",
"status":"final",
"issue_date":"2026-03-01",
"due_date":"2026-04-01",
"buyer_name":"ACME SARL",
"total_ht":"5000.00",
"created_at":"2026-03-01T10:00:00Z"
}
],
"meta": {
"page": 1,
"per_page": 20,
"total": 42,
"total_pages": 3
}
}Clients
GET /api/v1/clients
GET /api/v1/clients/:id
| Paramètre | Type | Requis | Description |
|---|---|---|---|
| page | number | Non | Numéro de page (défaut : 1) |
| per_page | number | Non | Éléments par page (défaut : 20, max : 100) |
| q | string | Non | Recherche par nom |
Devis (Quotes)
GET /api/v1/quotes
GET /api/v1/quotes/:id
| Paramètre | Type | Requis | Description |
|---|---|---|---|
| page | number | Non | Numéro de page (défaut : 1) |
| per_page | number | Non | Éléments par page (défaut : 20, max : 100) |
| status | string | Non | Filtrer par statut: draft, sent, accepted, rejected, converted |
| date_from | string | Non | Date de début (YYYY-MM-DD) |
| date_to | string | Non | Date de fin (YYYY-MM-DD) |
Recettes (Revenue)
GET /api/v1/revenue
GET /api/v1/revenue/:id
| Paramètre | Type | Requis | Description |
|---|---|---|---|
| page | number | Non | Numéro de page (défaut : 1) |
| per_page | number | Non | Éléments par page (défaut : 20, max : 100) |
| date_from | string | Non | Date de début (YYYY-MM-DD) |
| date_to | string | Non | Date de fin (YYYY-MM-DD) |
| payment_method | string | Non | Filtrer par méthode de paiement |
Dépenses (Expenses)
GET /api/v1/expenses
GET /api/v1/expenses/:id
| Paramètre | Type | Requis | Description |
|---|---|---|---|
| page | number | Non | Numéro de page (défaut : 1) |
| per_page | number | Non | Éléments par page (défaut : 20, max : 100) |
| category | string | Non | Filtrer par catégorie de dépense |
| date_from | string | Non | Date de début (YYYY-MM-DD) |
| date_to | string | Non | Date de fin (YYYY-MM-DD) |
Webhooks
Les webhooks vous permettent de recevoir des notifications en temps reel lorsqu'un événement se produit dans votre compte Kountabl.
Enregistrement
Enregistrez un endpoint webhook via l'API :
curl -X POST https://kountabl.com/api/v1/webhooks \
-H"Authorization: Bearer mk_live_your_key" \
-H"Content-Type: application/json" \
-d '{
"url":"https://your-server.com/webhooks/kountabl",
"events": ["invoice.created","invoice.paid"]
}'secret qui ne sera affiché qu'une seule fois. Conservez-le pour vérifier les signatures des payloads.Gestion des webhooks
GET /api/v1/webhooks — Lister vos endpoints
DELETE /api/v1/webhooks/:id — Supprimer un endpoint
Types d'événements
| Événement | Description |
|---|---|
| invoice.created | Une facture a été finalisée |
| invoice.paid | Un paiement a été enregistré pour une facture |
| invoice.cancelled | Une facture a été annulée |
| quote.created | Un devis a été finalisé et envoyé |
| quote.accepted | Un devis a été accepté par le client |
| revenue.created | Une recette a été enregistrée |
| expense.created | Une dépense a été enregistrée |
| client.created | Un nouveau client a été créé |
| invoice.whatsapp_sent | invoice.whatsapp_sent |
| reminder.whatsapp_sent | reminder.whatsapp_sent |
Format du payload
{
"event":"invoice.created",
"timestamp":"2026-03-23T10:00:00.000Z",
"data": {
"id":"a1b2c3d4-...",
"invoice_number":"2026-0001",
"status":"final",
"total_ht":"5000.00",
"issue_date":"2026-03-01"
},
"idempotency_key":"f47ac10b-58cc-4372-a567-0e02b2c3d479"
}Vérification de signature
Chaque requête webhook inclut un header X-Mokawil-Signature contenant un HMAC-SHA256 du body signé avec votre secret. Vérifiez-le avant de traiter le payload :
import { createHmac, timingSafeEqual } from 'crypto';
function verifyWebhookSignature(body, signature, secret) {
const expected = createHmac('sha256', secret)
.update(body)
.digest('hex');
const sig = Buffer.from(signature, 'hex');
const exp = Buffer.from(expected, 'hex');
return sig.length === exp.length && timingSafeEqual(sig, exp);
}
// In your webhook handler:
app.post('/webhooks/kountabl', (req, res) => {
const signature = req.headers['x-mokawil-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.KOUNTABL_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook event
const { event, data } = req.body;
console.log('Received event:', event, data);
res.status(200).json({ received: true });
});Tentatives de renvoi (Retry)
Si votre endpoint ne répond pas avec un status 2xx, Kountabl réessaiera avec un backoff exponentiel :
| Tentative | Délai |
|---|---|
| 1 | Immédiate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 1 heure |
| 6 | 2 heures |
| 7 | 4 heures |
| 8 | 8 heures |
| 9 | 12 heures |
| 10 | 24 heures |
Erreurs
Les erreurs utilisent une enveloppe standard :
{
"error": {
"code":"unauthorized",
"message":"Invalid or missing API key"
}
}Codes d'erreur
| Status HTTP | Code | Description |
|---|---|---|
| 400 | validation_error | Paramètres de requête invalides |
| 401 | unauthorized | Clé API manquante ou invalide |
| 404 | not_found | Ressource introuvable |
| 429 | rate_limited | Limite de requêtes atteinte |
| 500 | server_error | Erreur interne du serveur |
Votre activité mérite mieux qu'un tableur Excel
Rejoignez les auto-entrepreneurs marocains qui gèrent leur conformité avec confiance grâce à Kountabl.
Sur invitation uniquement