Ce document décrit toutes les routes API REST exposées par le backend de KADI.
Chaque requête doit être accompagnée d’un token Bearer (issu de Supabase) afin de garantir l’isolation multi‑tenant.
Le frontend web authentifie désormais l’utilisateur directement avec le client Supabase JS.
Le backend reste responsable de l’inscription, du profil entreprise, des emails transactionnels et des routes métier protégées par le token Bearer Supabase.
Inscription d’un nouvel utilisateur (email + mot de passe) et création du profil entreprise.
Body JSON :
{
"email": "user@exemple.com",
"password": "123456",
"company": "Nom de l'entreprise",
"manager_name": "Responsable",
"logo_file": "data:image/png;base64,...",
"logo_filename": "logo.png"
}Réponse :
{
"user": {"id": "uuid", "email": "user@exemple.com"},
"profile": {"company": "Nom de l'entreprise"},
"emailConfirmationRequired": true,
"emailVerificationSent": true,
"logoUploaded": true,
"message": "Compte créé. Un email de confirmation vous a été envoyé."
}Compatibilité legacy. Cette route n’est pas utilisée par le frontend web actuel. Connexion utilisateur via Supabase.
Body JSON :
{
"email": "user@exemple.com",
"password": "123456"
}Réponse :
{
"session": {
"access_token": "jwt-token",
"user": {"id": "uuid", "email": "user@exemple.com"}
}
}Compatibilité legacy. Cette route n’est pas utilisée par le frontend web actuel.
Déconnexion. Répond 204 No Content.
Renvoie un email de confirmation si le compte n’est pas encore validé (idempotent).
La réponse ne renvoie jamais de lien de confirmation.
Body JSON :
{
"email": "user@exemple.com"
}Réponse :
{
"emailVerificationSent": true,
"message": "Un nouvel email de confirmation vous a été envoyé."
}Déclenche l’envoi d’un email sécurisé pour réinitialiser le mot de passe.
Body JSON :
{
"email": "user@exemple.com"
}Réponse :
{
"resetEmailSent": true,
"message": "Un email de réinitialisation vient de vous être envoyé."
}Seuls company, tagline, logo_url, manager_name, address, city, state, national_id, rccm, nif, phone, website sont acceptés.
Le champ logo_url, lorsqu'il est envoyé, doit être un chemin interne du bucket Supabase de l'utilisateur connecté, jamais une URL externe.
Création ou mise à jour du profil d’entreprise associé à l’utilisateur connecté.
Body JSON :
{
"company": "Nom de l'entreprise",
"manager_name": "Responsable",
"address": "Lubumbashi, RDC"
}Réponse :
{"message": "Profil mis à jour"}Retourne la liste des clients du tenant connecté.
Headers : Authorization: Bearer <token>
Réponse :
[
{
"id": "uuid",
"company_name": "Alpha SARL",
"contact_name": "Jean Dupont",
"email": "jean@alpha.com"
}
]Ajoute un client.
Seuls les champs company_name, contact_name, email, phone, address sont acceptés.
Les champs système comme tenant_id, id, created_at sont rejetés.
Body JSON :
{
"company_name": "Alpha SARL",
"contact_name": "Jean Dupont",
"email": "jean@alpha.com",
"phone": "+243...",
"address": "Lubumbashi, RDC"
}Réponse :
{"message": "Client ajouté avec succès"}Met à jour les informations d’un client.
Seuls les champs company_name, contact_name, email, phone, address sont acceptés.
Body JSON :
{"phone": "+24390000000"}Réponse :
{"message": "Client mis à jour"}Supprime un client par ID.
Réponse :
{"message": "Client supprimé"}Liste tous les produits du tenant connecté.
Ajoute un nouveau produit ou service.
{
"name": "Consultation",
"description": "Service de conseil",
"unit_price": 50,
"currency": "USD"
}Modifie un produit existant.
Supprime un produit.
Réponse standard :
{"message": "Produit mis à jour/supprimé avec succès"}Retourne toutes les factures du tenant.
Retourne une facture spécifique.
Crée une nouvelle facture manuellement.
Seuls les champs client_id, issue_date, due_date, status, notes, items, currency sont acceptés.
invoice_number, subtotal_amount, total_amount et tenant_id sont générés ou calculés côté serveur.
Body JSON :
{
"client_id": "uuid",
"items": [
{"name": "Produit A", "quantity": 2, "unit_price": 15},
{"name": "Produit B", "quantity": 1, "unit_price": 30}
],
"currency": "USD",
"notes": "Merci pour votre confiance."
}Réponse :
{"message": "Facture créée", "invoice_number": "FAC-20260316-1A2B3C4D"}Met à jour une facture existante (statut, notes, items…).
Les champs système invoice_number, subtotal_amount, total_amount, tenant_id, id sont rejetés.
Supprime une facture.
Génère et télécharge le PDF d’une facture.
Retourne les indicateurs et jeux de données nécessaires au tableau de bord.
Paramètres de requête :
period(optionnel) :day|month|year(défautmonth).start/end(optionnels) : bornes personnalisées au formatYYYY-MM-DD.
Réponse exemple :
{
"totals": {
"revenue": 12850.5,
"outstanding": 2350,
"totalAmount": 15640.5,
"invoiceCount": 18,
"draftCount": 2,
"averagePaymentDelay": 4.2
},
"charts": {
"revenue": [
{ "label": "2024-10-01", "total": 2400 },
{ "label": "2024-10-02", "total": 1800 }
],
"topClients": [
{ "clientId": "uuid-1", "company": "Alpha SARL", "total": 6500 }
],
"topProducts": [
{ "label": "Maintenance serveur", "total": 3200, "quantity": 4 }
]
},
"meta": {
"period": "month",
"startDate": "2024-10-01T00:00:00.000Z",
"endDate": "2024-10-31T23:59:59.999Z"
}
}Génère automatiquement une facture à partir d’un texte libre.
Cette route attend le champ texte, applique une limite de taille côté serveur et peut être soumise à un rate limit.
Body JSON :
{
"texte": "Créer une facture pour Kivu Coffee : 3 sacs de café à 25 USD et 1 machine à 100 USD"
}Réponse :
{
"client_id": null,
"issue_date": null,
"due_date": null,
"status": "draft",
"notes": "",
"items": [
{"description": "Sac de café", "quantity": 3, "unitPrice": 25, "currency": "USD"},
{"description": "Machine", "quantity": 1, "unitPrice": 100, "currency": "USD"}
],
"currency": "USD"
}Permet de vérifier l’état du backend.
Réponse :
{"status": "ok", "uptime": 12345}| Code | Signification |
|---|---|
| 400 | Requête invalide |
| 401 | Token manquant ou invalide |
| 403 | Accès non autorisé |
| 404 | Ressource non trouvée |
| 500 | Erreur interne du serveur |
Auteur : Eric Kay (@EricayStudio)
Dernière mise à jour : Octobre 2025