API fournisseur et sous-comptes
Gérez vos propres clients depuis votre plateforme : créez un sous-compte par client, donnez-lui des SMS depuis votre solde, créez ses clés d’envoi et suivez sa consommation au prix que vous lui facturez.
Deux types de clés
- →Votre clé fournisseur (compte fournisseur actif) gère vos sous-comptes. Elle n’envoie pas de SMS pour eux.
- →Chaque sous-compte a ses propres clés API. Elles envoient avec le solde et les Sender IDs de ce sous-compte, comme une clé ordinaire, via
POST /v1/sms/send. - →Une clé de sous-compte ne peut jamais gérer d’autres sous-comptes : une clé divulguée n’expose qu’un seul de vos clients.
- →Les comptes partenaires (non fournisseurs) n’ont pas accès à ces routes.
Endpoints
| Méthode | Chemin | Rôle |
|---|---|---|
| GET | /v1/sub-accounts | Sous-comptes, soldes, consommation et montant au prix de revente sur une période (30 jours par défaut, 400 au plus). |
| POST | /v1/sub-accounts | Créer un sous-compte ; la référence rend l’appel idempotent. |
| PATCH | /v1/sub-accounts/{id} | Suspendre, réactiver, changer le prix de revente ou l’alerte de solde (un seul changement par appel). |
| POST | /v1/sub-accounts/{id}/transfers | Donner (allocation) ou reprendre (reclaim) des SMS ; Idempotency-Key obligatoire. |
| GET | /v1/sub-accounts/{id}/statement | Relevé jour par jour (fuseau Africa/Kinshasa). |
| GET | /v1/sub-accounts/{id}/api-keys | Clés actives du sous-compte (masquées). |
| POST | /v1/sub-accounts/{id}/api-keys | Créer une clé d’envoi pour le sous-compte ; le secret est affiché une fois. |
| DELETE | /v1/sub-accounts/{id}/api-keys/{apiKeyId} | Révoquer une clé du sous-compte. |
| GET | /v1/sub-accounts/{id}/messages | SMS du sous-compte avec leur statut de livraison, filtres from et to (période), status et phone (numéro). |
| GET | /v1/sub-accounts/{id}/sender-ids | Sender IDs du sous-compte. |
| POST | /v1/sub-accounts/{id}/sender-ids | Demander un Sender ID pour le client final ; validé par CUTUMA. |
Créer un sous-compte
Appelez cet endpoint depuis votre serveur, jamais depuis un navigateur. Le prix de revente sert à vos relevés ; il ne change pas ce que vous payez à CUTUMA.
const resellerKey = process.env.CUTUMA_RESELLER_API_KEY ?? '';
const response = await fetch('https://cutuma.com/api/v1/sub-accounts', {
method: 'POST',
headers: {
Authorization: `Bearer ${resellerKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Client A',
reference: 'client-a', // votre identifiant : sert aussi de clé d'idempotence
resale_price_usd: 0.035,
}),
});
const { outcome, sub_account_id } = await response.json();
// outcome = 'created' (201) ou 'existing' (200) si la référence existe déjà
Donner ou reprendre des SMS
Un transfert déplace des SMS entre votre solde et celui d’un sous-compte, sans création ni perte. Vous ne pouvez reprendre que des SMS que vous lui avez donnés et qu’il n’a pas utilisés. Réutilisez la même Idempotency-Key si la réponse ne vous parvient pas : le transfert ne sera jamais appliqué deux fois.
const response = await fetch(`https://cutuma.com/api/v1/sub-accounts/${subAccountId}/transfers`, {
method: 'POST',
headers: {
Authorization: `Bearer ${resellerKey}`,
'Content-Type': 'application/json',
'Idempotency-Key': `allocation-${invoiceId}`, // obligatoire, stable entre deux essais
},
body: JSON.stringify({ kind: 'allocation', units: 10000 }),
});
const transfer = await response.json();
// 201 : transfert appliqué ; 200 : rejeu du même transfert, rien n'est appliqué deux fois
console.log(transfer.reseller_remaining_units, transfer.sub_account_remaining_units);
Créer la clé d’envoi d’un client
Le sous-compte envoie uniquement avec ses propres Sender IDs approuvés et ne peut pas envoyer si son solde est vide.
curl -X POST "https://cutuma.com/api/v1/sub-accounts/$SUB_ACCOUNT_ID/api-keys" \
-H "Authorization: Bearer $CUTUMA_RESELLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Production"}'
# apiKey.plainTextKey n'est affichée qu'une fois : stockez-la côté serveur pour ce client.
Alertes de solde
Fixez un seuil en SMS pour chaque sous-compte avec PATCH /v1/sub-accounts/{id} et le champ low_balance_threshold_units (null pour désactiver). Le seuil apparaît dans la liste des sous-comptes.
curl -X PATCH "https://cutuma.com/api/v1/sub-accounts/$SUB_ACCOUNT_ID" \
-H "Authorization: Bearer $CUTUMA_RESELLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"low_balance_threshold_units":1000}'
Sender IDs des clients
- →Chaque sous-compte envoie uniquement avec ses propres Sender IDs approuvés ; ceux du fournisseur ne sont pas partagés.
- →Demandez le Sender ID au nom du client final avec
POST /v1/sub-accounts/{id}/sender-ids. Seul l’administrateur CUTUMA approuve chaque demande. - →Le sous-compte doit avoir un solde : transférez-lui des SMS avant la demande.
Relevé d’un sous-compte
Chaque SMS est valorisé au prix de revente en vigueur. Les SMS consommés avant que vous fixiez un prix apparaissent en unpriced_units.
curl "https://cutuma.com/api/v1/sub-accounts/$SUB_ACCOUNT_ID/statement?from=2026-10-01&to=2026-11-01" \
-H "Authorization: Bearer $CUTUMA_RESELLER_API_KEY"
Erreurs propres aux fournisseurs
| HTTP | Code | Signification |
|---|---|---|
| 403 | reseller_required | La clé n’appartient pas à un compte fournisseur. |
| 403 | reseller_not_active | Votre compte fournisseur est suspendu ou non activé. |
| 404 | sub_account_not_found | Ce sous-compte n’existe pas ou ne vous appartient pas. |
| 409 | insufficient_reseller_balance | Votre solde ne couvre pas ce transfert. |
| 409 | insufficient_sub_account_balance | Le sous-compte n’a pas assez de SMS que vous lui avez donnés et qu’il n’a pas utilisés. |
| 409 | sub_account_unfunded | Le sous-compte doit avoir un solde avant une demande de Sender ID. |
| 409 | idempotency_key_conflict | Cette Idempotency-Key a déjà servi pour un autre transfert. |
| 422 | idempotency_key_required | L’en-tête Idempotency-Key est obligatoire pour un transfert. |
| 422 | single_change_required | Un seul changement par appel PATCH. |