Référence API · Fournisseurs

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éthodeCheminRô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

HTTPCodeSignification
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.