DM Champ Docs

API pour les agences

En tant qu’agence, vous pouvez utiliser la même API REST que vos clients, mais en dirigeant les requêtes individuelles vers l’un de vos sous-comptes gérés au lieu de votre propre compte. Cela vous permet de créer des outils qui intègrent un client de bout en bout — création de ses agents IA, entraînement de son IA sur une base de connaissances, importation de ses contacts, connexion de ses canaux de messagerie et achat de numéros de téléphone — le tout sans avoir à vous connecter manuellement à chaque sous-compte.

Cette page couvre uniquement le comportement spécifique aux agences : comment agir au nom d’un sous-compte avec le paramètre sub_account_id. Pour les bases (génération de clé, authentification, URL de base, format d’erreur, limites de débit), commencez par le guide Accès API. Tout ce qui y est décrit s’applique également ici : vous vous authentifiez avec la clé API de votre compte d’agence.

Remarque : Cette page est technique. Si vous n’êtes pas développeur, partagez-la avec la personne en charge de votre intégration.


Comment fonctionne l’action « au nom de »

Par défaut, chaque requête API agit sur le compte qui possède la clé API, c’est-à-dire votre compte d’agence. Pour agir sur un compte client géré à la place, ajoutez le paramètre optionnel sub_account_id à la requête, défini sur l’identifiant de compte de ce client.

  • Omettre sub_account_id → la requête agit sur votre propre compte d’agence.
  • Inclure sub_account_id → la requête agit sur ce sous-compte, mais seulement après que la plateforme a confirmé que le sous-compte vous appartient réellement.

Vous vous authentifiez toujours avec la clé API de votre compte d’agence. Vous n’avez jamais besoin de la clé propre au sous-compte et vous ne gérez jamais les identifiants du sous-compte.

Où l’insérer

  • Points de terminaison GET / DELETE → passez-le en tant que paramètre de requête : ?sub_account_id=THE_SUB_ACCOUNT_ID (en plus de votre apiKey, si vous vous authentifiez par requête).
  • Points de terminaison POST / PUT / PATCH → incluez-le dans le corps de la requête JSON en tant que "sub_account_id": "THE_SUB_ACCOUNT_ID".
  • Assistants IA → rien à configurer. Le serveur MCP applique le même paramètre à ses outils, de sorte qu’une seule connexion avec votre clé d’agence peut générer des rapports sur chaque client : il suffit de nommer le client dans votre requête (« combien de contacts Bella’s Bistro possède-t-il ? »). Les actions d’écriture sont également disponibles : chaque point de terminaison qui accepte sub_account_id est exposé en tant qu’outil, vous pouvez donc créer, modifier et envoyer pour le compte d’un client à partir de la même connexion.

Trouver l’identifiant d’un sous-compte

Le sub_account_id est l’identifiant unique du compte client. Vous pouvez obtenir la liste de vos sous-comptes et leurs identifiants à partir des points de terminaison de l’API SubAccounts (voir le guide Sous-comptes) ou depuis la page Sous-comptes dans la barre latérale.


La propriété est toujours vérifiée

Lorsque vous passez un sub_account_id, la plateforme vérifie que le compte est un sous-compte réel et qu’il appartient à votre agence. Ce n’est qu’à cette condition que la requête est traitée.

Si l’identifiant est inconnu, n’est pas un sous-compte ou appartient à une autre agence, la requête échoue avec une réponse 404 :

{
  "success": false,
  "error_code": 404,
  "error": "Sub-account not found."
}

Pourquoi 404 et non 403 ? Une réponse « forbidden » indiquerait à un tiers que l’identifiant existe mais ne lui appartient pas. Renvoyer la même 404 pour « n’existe pas » et « ne vous appartient pas » signifie que le point de terminaison ne peut pas être utilisé pour découvrir quels identifiants de compte appartiennent à d’autres agences. Considérez une 404 ici comme « ce n’est pas un sous-compte que vous gérez. »


Où sub_account_id est pris en charge

sub_account_id est accepté sur pratiquement tous les points de terminaison de ressource — tout appel qui crée, lit, met à jour ou supprime les données propres à un compte. En pratique, vous pouvez provisionner et exécuter toute la configuration d’un sous-compte avec votre clé d’agence :

  • Configuration de l’IA — campagnes, agents, FAQ, sources de base de connaissances (exploration de site web et téléchargement de documents), groupes de base de connaissances, diffusions, fonctions personnalisées, serveurs MCP
  • Contacts et CRM — contacts (y compris l’importation), listes, étiquettes, tâches, transactions, rendez-vous, événements
  • Canaux et numéros — connexion WhatsApp / WhatsApp Web / Telegram / Instagram & Messenger / LINE, recherche / achat / gestion de numéros de téléphone, modèles WhatsApp, routage des canaux
  • Messagerie et contenu — envoi de messages, sessions de chat, exportations de chat, résumés quotidiens
  • Paramètres et intégrations — webhooks, configuration du widget de chat, configuration de marque blanche, SMS BYOK et autres paramètres de compte, analytique, journal des erreurs

Sur chacun d’entre eux, le paramètre est optionnel — si vous l’omettez, l’appel s’effectue sur votre propre compte d’agence, permettant ainsi à une seule intégration de servir aux deux cas. Les crédits et l’utilisation proviennent toujours du compte ciblé : les frais liés aux réponses IA, aux messages, aux tags et aux numéros d’un sous-compte sont débités du solde du sous-compte.

Où cela ne s’applique PAS

Quelques points de terminaison sont au niveau de l’agence ou auto-adressés et ignorent sub_account_id :

  • Gestion des sous-comptes eux-mêmes — les points de terminaison SubAccounts (créer / lister / mettre à jour un sous-compte) et le point de terminaison de limite de dépenses BYOK nomment déjà le sous-compte dans leur propre chemin d’URL. Les points de terminaison de tarification et de politique et les points de terminaison de surveillance de chat suivent le même modèle.
  • Copie d’un agent entre comptes — POST /v1/subaccounts/agents/copy nomme lui-même les deux comptes, en prenant la destination comme targetUserId. Voir l’exemple concret ci-dessous. (L’ancien POST /v1/subaccounts/campaigns/copy fonctionne de la même manière mais est obsolète avec le reste de l’API Campaigns.)
  • Ajustement des crédits et les deux cumuls à l’échelle de l’agence — POST /v1/subaccounts/credits identifie le sous-compte par email à la place ; GET /v1/subaccounts/credit-usage et GET /v1/subaccounts/campaign-status génèrent des rapports sur chaque sous-compte à la fois, il n’y a donc aucun compte unique à cibler.
  • Le propre compte de votre agence — la gestion des clés API, les rapports d’utilisation de l’agence, la gestion d’équipe et vos niveaux de tarification agissent toujours sur votre compte d’agence.
  • Ajout de contacts à une liste ou suppression de ceux-ci : POST / DELETE /v1/contacts/lists et POST /v1/contacts/lists/batch agissent sur le compte qui possède la clé. La création, la modification et la suppression des listes elles-mêmes (/v1/lists) nécessitent sub_account_id.
  • Webhooks de messages entrants — les points de terminaison vers lesquels les systèmes externes publient des données sont liés au compte dont les identifiants les ont configurés, il n’y a donc rien à rediriger.

La liste toujours à jour et lisible par machine des paramètres acceptés par chaque point de terminaison se trouve dans la référence de l’API de votre tableau de bord (Paramètres → Intégrations → Clé API) et dans la spécification OpenAPI à l’adresse GET /v1/docs/openapi.yaml. Nous publions fréquemment des modifications de l’API ; considérez-les comme la source de vérité.

Page des paramètres de clé API avec clé masquée et contrôle de régénération

Paramètres → Intégrations → Clé API — la clé de votre agence se trouve ici, ainsi que le lien vers la référence complète de l'API.


Listez vos sous-comptes ou vérifiez une adresse e-mail

GET /v1/subaccounts

Appelé sans paramètre, il renvoie tous les sous-comptes de votre agence dans un tableau data. Ajoutez le paramètre de requête optionnel email pour rechercher un client spécifique :

curl "https://api.dmchamp.com/v1/[email protected]&apiKey=YOUR_API_KEY"
  • Cet e-mail appartient à l’un de vos sous-comptes actifs → HTTP 200, avec uniquement ce compte : { "success": true, "data": { ... } }.
  • Ce n’est pas le cas → HTTP 404, Agency Sub Account not found.

Il n’existe aucun paramètre permettant d’obtenir une réponse par oui ou par non, vous devez donc lire le code de statut : 200 signifie que l’e-mail appartient à l’un de vos clients, 404 signifie que ce n’est pas le cas. Les sous-comptes supprimés sont exclus, donc un compte que vous avez supprimé renverra également 404.

Chaque compte est renvoyé avec son profil, ses paramètres, ses limites d’utilisation et les fonctionnalités activées, ce qui correspond à tout ce dont vous avez besoin pour afficher une ligne client dans votre propre tableau de bord.

La réponse ne contient jamais d’identifiants. Les clés API, mots de passe, jetons de connexion et les détails des canaux qu’un client a connectés (Twilio, Google, Meta et « bring-your-own-key ») sont supprimés avant l’envoi. Il n’existe aucun paramètre pour choisir les champs que vous recevez, lisez donc les champs dont vous avez besoin et ignorez le reste.

Nécessite un accès API et un compte d’agence.


Créer un compte client

POST /v1/subaccounts

La création du compte se fait en un seul appel avec l’e-mail, le nom et le nom de l’entreprise du client. Quelques points méritent d’être connus avant de construire votre flux d’inscription.

Vous ne pouvez pas choisir le mot de passe. Il n’y a pas de champ de mot de passe : un mot de passe est généré pour vous et renvoyé une seule fois, en tant que temporary_password dans la réponse 201. Stockez-le ou transmettez-le immédiatement, car rien ne vous le montrera à nouveau. Le client peut le modifier depuis son profil ou le réinitialiser depuis l’écran de connexion.

curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "first_name": "Alex",
    "last_name": "Client",
    "business_name": "Client Co",
    "send_account_info_to_sub_account": true
  }'

Rien n’est envoyé par e-mail au client, sauf si vous le demandez. Par défaut, le compte est créé discrètement, et c’est à vous d’en informer le client. Envoyez send_account_info_to_sub_account: true et il recevra un e-mail de bienvenue avec son adresse e-mail, ce mot de passe temporaire et un lien pour se connecter, le tout sur votre propre domaine en marque blanche et sous votre marque.

Le drapeau ne couvre que l’e-mail du client. Votre agence reçoit toujours une notification Nouveau sous-compte créé, mais elle ne contient jamais le mot de passe : pour des raisons de sécurité, la réponse 201 est le seul endroit où vous l’obtenez. S’il est perdu, le client définit le sien via Mot de passe oublié sur l’écran de connexion.

Les crédits d’ouverture sont à définir par vos soins. usage_limits.credits correspond à la limite de dépenses initiale du client et usage_limits.monthly_credits à l’allocation mensuelle récurrente. Envoyez "credits": 0 et le compte commence sans aucun crédit à dépenser ; omettez credits et il commence avec un solde unique de 100 crédits afin que l’IA puisse répondre immédiatement. Aucun de ces éléments ne prélève quoi que ce soit de votre réserve d’agence lors de la création : votre réserve n’est débitée qu’au fur et à mesure que le client utilise réellement ses crédits.

Les noms d’entreprise doivent être uniques au sein de votre agence. Deux de vos clients ne peuvent pas s’appeler « Client Co », car ce nom identifie le compte dans votre tableau de bord et vos rapports. Les noms des autres agences n’entrent pas en ligne de compte.

Lorsque l’appel échoue :

Statut Ce qui s’est passé
400 Un champ est manquant ou incorrect, l’e-mail n’est pas une adresse valide, ou la clé utilisée n’appartient pas à un compte d’agence.
401 La clé API est incorrecte, expirée ou révoquée.
402 Votre propre abonnement n’est pas actif, donc aucun nouveau compte client ne peut être créé tant que votre facturation n’est pas régularisée.
403 Vous avez atteint le nombre de comptes clients autorisé par votre forfait.
409 Ce nom d’entreprise est déjà utilisé par l’un de vos clients, ou cet e-mail appartient déjà à un compte.

Supprimer un compte client

DELETE /v1/[email protected] (ou ?uid=SUB_ACCOUNT_UID)

curl -X DELETE "https://api.dmchamp.com/v1/[email protected]" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"

Ceci est identique au bouton de suppression sur la page des sous-comptes, et cette action est irréversible. Le client est immédiatement bloqué et n’est plus comptabilisé dans votre total de clients ; ses conversations, contacts, agents et canaux connectés sont effacés en arrière-plan dans les minutes qui suivent. Tout forfait acheté par le client via votre page de paiement est annulé.

{
  "success": true,
  "message": "Sub-account deletion started",
  "data": { "uid": "SUB_ACCOUNT_UID", "email": "[email protected]", "status": "deletion_started" }
}
  • Passez email ou uid. Si vous passez les deux, ils doivent désigner le même client.
  • Seuls vos propres clients peuvent être supprimés. Tout autre e-mail ou uid, ainsi qu’un client déjà supprimé, renvoie 404.
  • Appeler à nouveau cette fonction alors que la suppression est en cours renvoie 200 avec "status": "already_in_progress".
  • Les assistants IA connectés via le serveur MCP disposent de cet outil sous le nom delete_subaccount lorsqu’ils sont connectés à l’adresse MCP standard (les outils d’agence sont exclus d’une adresse MCP en marque blanche).
  • Pour suspendre un client pendant un certain temps sans rien perdre, mettez-le en pause plutôt : il est verrouillé, tout est conservé, et un seul appel permet de le rétablir.

Exemple concret : connecter Instagram et Messenger pour un sous-compte

La connexion à Instagram et Messenger est un flux basé sur le navigateur. Vous le démarrez avec l’API, transmettez l’URL de consentement renvoyée au client (ou ouvrez-la pour lui), attendez qu’il s’autorise dans son navigateur, puis choisissez la page à connecter — tout en ciblant son sous-compte avec sub_account_id.

Étape 1 — Démarrer la connexion

Appelez le point de terminaison de connexion avec le sub_account_id du client dans le corps. Aucune information d’identification n’est envoyée ici ; la plateforme renvoie une URL de consentement que le client doit ouvrir dans un navigateur, ainsi qu’un jeton de corrélation à usage unique.

cURL

curl -X POST "https://api.dmchamp.com/v1/channels/meta/connect?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sub_account_id": "abc123def456"
  }'

JavaScript

const res = await fetch("https://api.dmchamp.com/v1/channels/meta/connect", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sub_account_id: "abc123def456",
  }),
});

const data = await res.json();
// data.oauth_url -> open this in the client's browser

Python

import requests

res = requests.post(
    "https://api.dmchamp.com/v1/channels/meta/connect",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "sub_account_id": "abc123def456",
    },
)

data = res.json()
# data["oauth_url"] -> open this in the client's browser

Réponse :

{
  "success": true,
  "oauth_url": "https://www.facebook.com/v21.0/dialog/oauth?client_id=...&state=...",
  "state_token": "8sFq2yV0kQ7m4n1pZr3tWb6cXe9hJl2aD5gK7uN0oI",
  "expires_at": "2026-06-10T12:30:00.000Z"
}

Envoyez le client vers oauth_url dans un navigateur pour autoriser. Le state_token corrèle cette tentative et est un secret à courte durée de vie — ne le consignez pas dans les journaux. La tentative expire à expires_at ; si elle expire, recommencez.

Étape 2 — Interroger jusqu’au chargement des pages

Une fois l’autorisation du client obtenue, interrogez le point de terminaison de statut (avec le même sub_account_id, cette fois en tant que paramètre de requête) jusqu’à ce que les pages connectables apparaissent.

cURL

curl "https://api.dmchamp.com/v1/channels/meta/status?apiKey=YOUR_API_KEY&sub_account_id=abc123def456"

JavaScript

const res = await fetch(
  "https://api.dmchamp.com/v1/channels/meta/status?sub_account_id=abc123def456",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);

const data = await res.json();
// Wait until data.status === "pages_loaded", then read data.pages

Python

import requests

res = requests.get(
    "https://api.dmchamp.com/v1/channels/meta/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"sub_account_id": "abc123def456"},
)

data = res.json()
# Wait until data["status"] == "pages_loaded", then read data["pages"]

Réponse :

{
  "success": true,
  "status": "pages_loaded",
  "pages": [
    {
      "id": "1098765432101234",
      "name": "Acme Studio",
      "category": "Hair Salon",
      "instagram_business_account": {
        "id": "17841400000000000",
        "username": "acme.studio"
      }
    }
  ],
  "selected_page": null
}

Le champ status progresse via pending → token_received → pages_loaded → connected. Attendez pages_loaded avant de sélectionner une page. Deux états d’erreur terminaux peuvent également apparaître au lieu de progresser : failed et expired (le client a refusé le consentement, ou la fenêtre d’environ 30 minutes du jeton d’état a expiré) — un champ reason est inclus lorsque l’un ou l’autre se produit. Arrêtez l’interrogation et recommencez à l’étape 1 si vous en voyez un ; n’attendez pas indéfiniment sur pending. Les jetons d’accès aux pages ne sont jamais renvoyés.

Étape 3 — Sélectionner la page à connecter

Choisissez l’un des identifiants de page de l’étape 2 et sélectionnez-le. La sélection d’une page connecte à la fois Instagram et Messenger pour cette page. Incluez à nouveau sub_account_id dans le corps de la requête.

cURL

curl -X POST "https://api.dmchamp.com/v1/channels/meta/select-page?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "page_id": "1098765432101234",
    "sub_account_id": "abc123def456"
  }'

JavaScript

const res = await fetch("https://api.dmchamp.com/v1/channels/meta/select-page", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    page_id: "1098765432101234",
    sub_account_id: "abc123def456",
  }),
});

const data = await res.json();

Python

import requests

res = requests.post(
    "https://api.dmchamp.com/v1/channels/meta/select-page",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "page_id": "1098765432101234",
        "sub_account_id": "abc123def456",
    },
)

data = res.json()

Réponse :

{
  "success": true,
  "page_id": "1098765432101234",
  "instagram_business_account_id": "17841400000000000"
}

C’est tout — Instagram et Messenger sont maintenant connectés sur le sous-compte du client. Vous n’avez fourni que le page_id ; l’identifiant sous-jacent est résolu sur le serveur et ne transite jamais par votre intégration.


Exemple pratique : acheter un numéro pour un sous-compte

L’achat d’un numéro fonctionne de la même manière : effectuez une recherche avec sub_account_id dans la requête, puis achetez-le en l’incluant dans le corps. Les crédits sont déduits du solde du sous-compte, et le numéro est provisionné sur ce sous-compte.

Recherche (cURL) :

curl "https://api.dmchamp.com/v1/phone-numbers/available?apiKey=YOUR_API_KEY&country_code=US&sub_account_id=abc123def456"

Achat (JavaScript) :

const res = await fetch("https://api.dmchamp.com/v1/phone-numbers", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phone_number: "+14155551234",
    country_code: "US",
    display_name: "Support line",
    sub_account_id: "abc123def456",
  }),
});

const data = await res.json();

Achat (Python) :

import requests

res = requests.post(
    "https://api.dmchamp.com/v1/phone-numbers",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "phone_number": "+14155551234",
        "country_code": "US",
        "display_name": "Support line",
        "sub_account_id": "abc123def456",
    },
)

data = res.json()

Réponse :

{
  "success": true,
  "phone_number": "+14155551234",
  "channel": "whatsapp",
  "whatsapp_status": "PURCHASED",
  "outgoing_status": "PURCHASED",
  "status": "PURCHASED",
  "purchase_credits": 11.5,
  "monthly_credits": 11.5
}

Le numéro est provisionné dans l’état PURCHASED et l’enregistrement de l’expéditeur WhatsApp se poursuit en arrière-plan. Interrogez GET /v1/phone-numbers/{phoneNumber}/status?sub_account_id=abc123def456 jusqu’à ce que le statut atteigne ONLINE avant d’envoyer.


Exemple concret : déployer un agent modèle dans chaque nouveau client

Le modèle d’agence habituel consiste à conserver un agent maître sur votre compte d’agence, configuré comme vous souhaitez que chaque client commence, et à en copier une instance dans chaque nouveau sous-compte au moment du provisionnement. Cela représente trois appels, et rien n’a besoin d’être répété par la suite : la copie conserve ses paramètres jusqu’à ce que vous les modifiiez.

Étape 1 — Copier l’agent

POST /v1/subaccounts/agents/copy

curl -X POST "https://api.dmchamp.com/v1/subaccounts/agents/copy?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "YOUR_TEMPLATE_AGENT_ID",
    "targetUserId": "abc123def456",
    "newName": "Inbound Instagram Leads",
    "copyFaqs": true
  }'

La réponse contient l’identifiant du nouvel agent dans data.agent_id. La FAQ, la base de connaissances et la médiathèque sont incluses ; les modèles WhatsApp, les publications sociales connectées et les contacts du compte source ne le sont délibérément pas. Liste complète des champs dans l’API AI Agents.

Notez que ce point de terminaison utilise targetUserId plutôt que sub_account_id — il nomme les deux comptes lui-même. Les deux appels ci-dessous utilisent le paramètre sub_account_id habituel.

Étape 2 — L’activer

La copie arrive toujours en pause, elle ne peut donc envoyer de messages à personne tant que vous ne l’avez pas autorisé. C’est également le moment de définir le niveau d’IA que vous souhaitez attribuer au client ; il y reste, il n’est donc pas nécessaire de le réappliquer selon un calendrier.

curl -X PATCH "https://api.dmchamp.com/v1/agents/NEW_AGENT_ID/active?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
  -H "Content-Type: application/json" \
  -d '{ "active": true }'

curl -X PUT "https://api.dmchamp.com/v1/agents/NEW_AGENT_ID?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
  -H "Content-Type: application/json" \
  -d '{ "anthropic_model": "max" }'

Pour empêcher le client de modifier le niveau par la suite, verrouillez les niveaux autorisés sur le sous-compte au lieu de renvoyer la valeur.

Étape 3 — Diriger les canaux du client vers celle-ci

La copie arrive également sans routage, donc rien ne l’atteint tant que vous ne l’avez pas désigné comme répondant sur les canaux que le client a connectés. Un appel par canal :

curl -X PUT "https://api.dmchamp.com/v1/entry-points/channel-defaults?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "instagram", "agent_id": "NEW_AGENT_ID" }'

À partir de là, un premier message provenant d’un contact inconnu sur ce canal est automatiquement pris en charge par l’agent copié. Voir Pointer un canal vers un agent pour les autres canaux et le routage par numéro.

Définissez le fuseau horaire du client lors de la création du sous-compte. Transmettez time_zone_id sur POST /v1/subaccounts. Les heures d’activité d’un agent sont évaluées selon le fuseau horaire propre au sous-compte ; ainsi, un client créé sans fuseau horaire verra son planning lu par rapport à l’UTC — ce qui décale silencieusement les périodes durant lesquelles l’assistant est autorisé à répondre.


Ignorer l’assistant de configuration pour un client que vous configurez vous-même

POST /v1/subaccounts

Par défaut, lors de sa première connexion, le propriétaire d’un nouveau sous-compte est guidé par l’assistant de configuration (Setup Wizard). Pour les clients « clés en main » — où vous créez l’agent IA et connectez les canaux avant même que le client ne se connecte — transmettez guided_onboarding: false lors de la création du compte. Ils accèdent alors directement à l’écran d’accueil normal — le tableau de bord sur ordinateur, leurs discussions sur téléphone — et l’entrée Setup Wizard est masquée dans leur barre latérale.

curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "first_name": "Alex",
    "last_name": "Client",
    "business_name": "Client Co",
    "guided_onboarding": false,
    "usage_limits": { "monthly_credits": 500 }
  }'

Omettez le champ (ou envoyez true) et l’assistant se comportera exactement comme il l’a toujours fait, de sorte que les intégrations existantes n’ont besoin d’aucune modification. Pour redonner l’assistant à un client plus tard, réaffichez l’élément guided_onboarding avec PUT /v1/subaccounts/{subAccountUid}/menu-visibility (ci-dessous) — la visibilité du menu contrôle si l’assistant est accessible, guided_onboarding contrôle uniquement la redirection lors de la première connexion.


Désactiver les Tâches, les Résumés quotidiens ou la Bibliothèque multimédia pour un client

POST /v1/subaccounts

Ces trois fonctionnalités sont activées pour chaque nouveau client, sauf indication contraire de votre part, et elles se comportent différemment de toutes les autres fonctionnalités de ce guide : elles sont en opt-out (désactivation volontaire) et non en opt-in. Les omettre de features ne suffit pas en soi, car la liste features d’une intégration plus ancienne ne les mentionnait tout simplement pas — nous ne pouvons pas distinguer si « l’agence a désactivé ceci » ou si « cette liste a été rédigée avant que l’option n’existe ».

Indiquez-le donc explicitement avec feature_settings :

curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "first_name": "Alex",
    "last_name": "Client",
    "business_name": "Client Co",
    "feature_settings": {
      "tasks": false,
      "daily_summaries": false,
      "ai_media_library": true
    }
  }'

Chaque clé est facultative ; tout ce que vous omettez reste activé. Avec tasks: false, l’IA cesse de créer des tâches pour ce client et aucun e-mail de type « Nouvelle tâche créée » n’est envoyé ; avec daily_summaries: false, le résumé nocturne n’est jamais généré ni envoyé par e-mail.

feature_settings est le seul moyen de désactiver ces trois éléments lors de la création. Les omettre de features ne produit aucun effet en soi, quel que soit le reste de votre liste — c’est intentionnel, afin qu’une intégration plus ancienne ne perde pas silencieusement ces trois fonctionnalités.

Pour modifier l’un de ces paramètres par la suite, envoyez la liste complète features à PUT /v1/subaccounts/{subAccountUid}/features — ici, la présence dans la liste active une fonctionnalité et son absence la désactive.


Connectez automatiquement vos clients à leur sous-compte (SSO)

POST /v1/subaccounts/{subAccountUid}/sso-link

Un seul appel avec votre clé API d’agence renvoie une URL prête à l’emploi qui connecte directement le client à son propre sous-compte — aucun écran de connexion, aucune étape de mot de passe, rien à développer en plus. Ouvrez-la dans un nouvel onglet, via une redirection ou dans une iframe au sein de votre propre produit.

Champ Requis Description
redirect Non Page intégrée à l’application sur laquelle vous souhaitez que le client aboutisse, par ex. "/chats" ou "/agents". Renvoyé sous le nom deep_link_url dans la réponse.
app_base_url Non Hôte du tableau de bord pour le lien. Utilise par défaut votre domaine d’application en marque blanche (ou le domaine de la plateforme si vous n’en avez pas). Doit être https.

cURL

curl -X POST "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/sso-link" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "redirect": "/chats" }'

Réponse

{
  "success": true,
  "url": "https://app.yourdomain.com/auth?redirect=%2Fchats#token=eyJhbGciOi…",
  "deep_link_url": "https://app.yourdomain.com/chats",
  "expires_at": "2026-07-22T15:04:05.000Z",
  "sub_account_uid": "SUB_ACCOUNT_UID"
}

Comment bien l’utiliser :

  • Un seul saut. L’ouverture de url connecte le client et l’envoie directement sur la page redirect du tableau de bord — pas d’écran de connexion, pas de page intermédiaire. deep_link_url désigne la même destination, pour les intégrateurs qui préfèrent naviguer explicitement dans un cadre après la connexion ; une fois la session établie, n’importe quel chemin du tableau de bord fonctionne dans ce contexte de navigateur.
  • Création à la demande, ouverture immédiate. Le lien contient un identifiant de connexion et expire après environ une heure. Demandez-le côté serveur au moment où le client clique, et ne le stockez ni ne l’envoyez jamais par e-mail.
  • Le jeton de connexion transite dans le fragment d’URL (#…), que les navigateurs n’envoient jamais aux serveurs, et il est supprimé de la barre d’adresse dès qu’il est consommé.
  • Uniquement vos propres sous-comptes. Le point de terminaison refuse tout compte qui n’appartient pas à votre agence.
  • Un lien expiré affiche une erreur claire avec un chemin de réessai — générez-en un nouveau.

Masquer des éléments de navigation sur un sous-compte

PUT /v1/subaccounts/{subAccountUid}/menu-visibility

Contrôle les éléments de la barre latérale et des paramètres visibles par un sous-compte — utile lorsque vous intégrez le tableau de bord et que vous souhaitez uniquement afficher les surfaces que votre produit ne couvre pas déjà. Tout ce qui n’est pas listé reste visible ; envoyez null comme valeur entière de menuVisibility pour tout réinitialiser en mode visible. Masquer un élément masque l’entrée du menu — associez cela aux fonctionnalités que vous accordez au sous-compte pour un contrôle strict.

cURL

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/menu-visibility" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "menuVisibility": {
      "side_nav": { "Dashboard": false, "Deals": false, "Automations": false },
      "settings_nav": { "team": false }
    }
  }'

Réponse

{
  "success": true,
  "data": {
    "subAccountUid": "SUB_ACCOUNT_UID",
    "menuVisibility": {
      "side_nav": { "Dashboard": false, "Deals": false, "Automations": false },
      "settings_nav": { "team": false }
    }
  }
}

side_nav accepte ces 13 clés, qui correspondent aux noms des éléments de la barre latérale : Dashboard, DailySummaries, Chats, Contacts, Deals, Tasks, Automations, Campaigns, Appointments, Settings, Help, CreditsCounter (le solde de crédits affiché dans la barre latérale) et guided_onboarding (l’assistant de configuration). Campaigns masque uniquement la page obsolète des Campagnes ; les pages Agents IA et Diffusions n’ont pas de clé et ne peuvent pas être masquées de cette manière. Trois autres clés — AiInsights, Sub Accounts et Agency Reselling — sont acceptées mais n’ont aucun effet : elles ne s’appliquaient qu’à l’ancien tableau de bord classique, leur configuration n’a donc aucun impact sur vos sous-comptes. Les clés manquantes signifient que l’élément est visible ; lorsque vous vous connectez vous-même au sous-compte, les éléments masqués sont temporairement affichés afin que vous puissiez toujours revenir en arrière.

Le même objet menuVisibility accepte également deux champs optionnels pour le tableau de bord principal du client. dashboard_widgets associe un identifiant de widget à true (affiché) ou false (masqué), et dashboard_order est une liste d’identifiants de widgets dans l’ordre dans lequel ils doivent apparaître. Les identifiants, dans leur ordre par défaut, sont kpis, performance, credits (Utilisation des crédits), funnel, inbox, outcomes, channel_health, ai_cost, ai_human, heatmap (Heures les plus actives), top_campaigns (Meilleurs agents), contacts_by_country, activity et tasks_deals. Les identifiants manquants restent visibles, et les identifiants omis dans dashboard_order suivent l’ordre par défaut. Par exemple, "dashboard_widgets": { "credits": false } masque le panneau des crédits au client.

Masquer une page du menu n’en accorde jamais l’accès. Automations nécessite que la fonctionnalité automations soit accordée sur le sous-compte — définissez la clé sur true sans cela et la page n’apparaîtra toujours pas. Tasks et DailySummaries fonctionnent à l’inverse : elles sont activées pour chaque client à moins que vous ne les désactiviez (voir Désactiver les Tâches, les Résumés quotidiens ou la Bibliothèque multimédia pour un client).


Choisir les types de canaux auxquels un client peut se connecter

PUT /v1/subaccounts/{subAccountUid}/features

Les commutateurs Types de canaux que vous voyez sur un niveau de plan sont des identifiants de fonctionnalité ordinaires. Vous pouvez donc les définir par client depuis l’API au lieu du tableau de bord. Il s’agit de l’un des points de terminaison qui nomme le sous-compte dans sa propre URL, il ne nécessite donc aucun sub_account_id.

ID de fonctionnalité Canal
channel_chat_widget Widget de chat sur site web
channel_whatsapp_api API WhatsApp Business
channel_whatsapp_web WhatsApp Web (numéro lié par QR)
channel_instagram Instagram
channel_messenger Facebook Messenger
channel_telegram Telegram
channel_line LINE
channel_viber Viber
channel_email Boîte de réception e-mail
channel_sms SMS
channel_imessage iMessage
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/features" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "features": [
      "channels_3",
      "channel_chat_widget",
      "channel_whatsapp_web",
      "channel_instagram",
      "image_understanding",
      "contact_tagging",
      "incoming_campaigns",
      "webhooks"
    ]
  }'

Ce qu’il faut retenir :

  • L’appel remplace toute la liste des fonctionnalités. Envoyez toutes les fonctionnalités que le client doit conserver, pas seulement celles que vous modifiez. Les mêmes ID fonctionnent comme features sur POST /v1/subaccounts lors de la création du compte.
  • Les types de canaux et le nombre de canaux sont des verrous distincts, et les deux s’appliquent. channels_1 / channels_3 / channels_unlimited contrôlent combien de connexions ; les ID channel_* contrôlent quels types. L’exemple ci-dessus signifie « jusqu’à 3 connexions, et uniquement Chat Widget, WhatsApp Web ou Instagram ».
  • automations_edit, broadcasts_send et smart_lists_create permettent au client de créer, modifier et supprimer ses propres automatisations, diffusions et listes intelligentes. Une liste qui ne mentionne aucun des trois les laisse tels quels (sur un nouveau sous-compte : les trois sont activés), afin qu’une intégration plus ancienne continue de fonctionner. Nommez-en au moins un et la liste définit les trois : ceux que vous omettez sont désactivés. Le client peut toujours utiliser ce que vous avez configuré pour lui dans les deux cas, et votre clé API d’agence ainsi que vos propres sessions dans le compte du client ne sont jamais restreintes par ces trois éléments.
  • Toute autre fonctionnalité correspond exactement à ce que dit la liste, lors de la création et de la mise à jour. Un client créé ou mis à jour avec une liste features obtient ces fonctionnalités et rien d’autre. Cela inclut crm_erp_integrations (la section des intégrations CRM & ERP, où un client connecte Odoo) : elle n’est activée que lorsque votre liste l’inclut, donc ajoutez-la si le client doit connecter un CRM ou un ERP. Un client créé sans aucune liste features obtient l’ensemble par défaut, qui l’inclut.
  • Ne pas envoyer d’ID channel_* signifie aucune restriction de canal. C’est le comportement d’origine, c’est pourquoi les clients existants n’ont pas été affectés lors de la mise en service de cette fonctionnalité. Envoyez-en un ou plusieurs et tout le reste apparaîtra comme verrouillé sur la page Canaux du client avec une note de mise à niveau au lieu d’un bouton Connecter. Les canaux que le client a déjà connectés continuent de fonctionner.

La définition de la liste des canaux sur un niveau de plan, afin que chaque client qui achète ce niveau en hérite, s’effectue dans le tableau de bord sous les paramètres de votre plan d’agence. Ce point de terminaison la définit pour un sous-compte spécifique.


Définir une limite exacte de membres d’équipe pour un client

PUT /v1/subaccounts/{subAccountUid}/limits

Les fonctionnalités team_seats_* ne proposent que des paliers prédéfinis (3 / 5 / 10 / illimité). Pour attribuer à un client un nombre exact de sièges d’équipe — 2, 7, 15, ou tout autre nombre — définissez plutôt usage_limits.team_seats_limit. Cette valeur prévaut sur les paliers prédéfinis et la plateforme l’applique à chaque invitation, ajout direct et acceptation d’invitation : une fois la limite atteinte, les invitations supplémentaires sont refusées côté serveur.

  • Un entier positif correspond au plafond exact.
  • 0 signifie que les membres d’équipe ne sont pas inclus — le client ne peut inviter personne.
  • -1 signifie illimité.
  • null efface la limite personnalisée et revient au palier team_seats_* défini dans la liste des fonctionnalités.

Réduire la limite ne supprime jamais les membres d’équipe existants ; cela empêche seulement l’ajout de nouveaux membres.

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/limits" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "usageLimits": { "team_seats_limit": 7 }
  }'

Vous pouvez également le définir lors de la création : POST /v1/subaccounts accepte usage_limits.team_seats_limit avec la même sémantique. Pour lire la valeur actuelle, récupérez le sous-compte avec GET /v1/subaccounts?email=... et consultez usage_limits.team_seats_limit (absent/null = les préréglages décident). Le même point de terminaison met également à jour credits, monthly_credits, roll_over_to_next_month, rollover_cap_months, rollover_expiry_days et byok_monthly_limit_usd — envoyez uniquement les clés que vous souhaitez modifier. Un creditManagementMode de haut niveau ("manual" ou "reselling") bascule le mode de crédit du client ; un sous-compte créé via l’API démarre en mode manuel, vous devez donc le basculer sur "reselling" avant que le client ne paie via votre paiement en mode SaaS (voir Sous-comptes, exécution d’un essai gratuit).

Comment cela interagit avec les limites de sièges des plans SaaS. Vos plans SaaS peuvent comporter leur propre allocation de sièges (définie dans l’éditeur de plan — voir Sièges d’équipe sur un plan), qui est appliquée automatiquement lorsqu’un client s’abonne. Une limite que vous définissez via ce point de terminaison compte comme une attribution manuelle : l’achat d’un plan la remplace par l’allocation de sièges propre au plan (cet achat étant un choix de plan explicite), mais les renouvellements mensuels automatiques ne remplacent jamais une limite manuelle — ainsi, une exception ponctuelle que vous accordez à un client survit à son cycle de facturation. Supprimer la limite manuelle avec null redonne la main au plan lors de son prochain renouvellement.

Limitez ce qu’un client conserve entre deux renouvellements. Deux clés usage_limits supplémentaires se trouvent à côté de roll_over_to_next_month. Toutes deux sont également acceptées par POST /v1/subaccounts lors de la création, et null efface l’une ou l’autre.

Clé Action
rollover_cap_months Nombre de mois d’allocation que le client peut conserver. Un nombre de 0 à 120, fractions autorisées (0.5 = un demi-mois). À chaque renouvellement, le solde inutilisé est réduit au maximum à ce nombre de fois l’allocation accordée par ce renouvellement, avant que les nouveaux crédits ne soient ajoutés ; 0 ne reporte rien.
rollover_expiry_days Un nombre entier de jours, de 1 à 3650. Les crédits inutilisés pendant cette durée sont supprimés lors du premier renouvellement après avoir atteint cet âge. La consommation est toujours déduite des crédits les plus anciens en premier, donc un client qui utilise son allocation chaque mois n’en perd jamais.

S’ils ne sont pas définis, les deux reviennent au plan du client ; une valeur envoyée ici prévaut sur celle du plan. Seuls les crédits récurrents (l’allocation mensuelle et les crédits du plan) y sont soumis : les recharges, les recharges automatiques et les ajouts ponctuels ne sont jamais plafonnés ni expirés. Chaque réduction est inscrite dans l’historique des crédits du client en tant qu’Ajustement de crédit de plafond de report ou Ajustement de crédit de crédits expirés et ne compte jamais comme une utilisation. Les équivalents au niveau du plan sont rollover_cap_months et rollover_expiry_days sur un niveau de tarification — voir Les champs sur un niveau et Plafonner ce qui est reporté.


Définir la tarification et la politique IA par client

PUT /v1/subaccounts/{subAccountUid}/max-tier · /ai-tiers · /max-rate · /action-pricing · /insider-rate · /locked-bot-fields · /notifications · /zero-credit-reply

Huit commutateurs supplémentaires par client, en plus de /limits, /features et /menu-visibility ci-dessus. Chacun prend l’uid du sous-compte dans l’URL (aucun paramètre de corps/requête sub_account_id — la cible est déjà nommée dans le chemin) et est limité de la même manière : votre clé d’agence, et le sous-compte doit appartenir à votre agence.

Quels modèles d’IA un client peut utiliser

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/max-tier" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'

{ "enabled": boolean } permet au client d’opter pour (ou de se désinscrire de) l’offre Max AI, au prix catalogue de la plateforme. L’activation de cette option pour un client BYOK fait passer son coût lié à l’IA de « 0 crédit, payé via ma propre clé » à « débité de mon solde de crédits ». Il s’agit donc d’une décision délibérée prise client par client plutôt que d’une valeur par défaut à l’échelle de l’agence.

Pour restreindre les niveaux (tiers) parmi lesquels les agents d’un client peuvent choisir (plutôt que de simplement limiter le niveau Max), utilisez ai-tiers :

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/ai-tiers" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "allowed_ai_tiers": ["standard", "economy"] }'

allowed_ai_tiers est un tableau extrait de standard, economy, max, mini — il REMPLACE la liste d’autorisation du client. Envoyez null (ou []) pour supprimer la restriction et lui permettre de choisir n’importe quel niveau. Une liste définie ici compte comme un verrouillage manuel : le allowed_ai_tiers propre à un forfait (voir Gérer vos niveaux de tarification via l’API) n’affecte plus ce client lors du renouvellement. C’est important car un sous-compte choisissant son propre niveau d’IA utilise votre réserve de crédits. C’est donc le levier pour déterminer quels modèles un client revendeur peut utiliser à vos frais.

Une réponse d’attente lorsque le client n’a plus de crédits

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/zero-credit-reply" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "message": "Thanks for your message, we will get back to you shortly." }'

Lorsque le solde du client (ou votre réserve) est vide, l’IA ne peut pas répondre et le contact n’entend rien. Avec enabled: true, chaque contact qui écrit pendant la panne reçoit message une fois (max 500 caractères, envoyé tel quel sur chaque canal), et l’IA répond réellement à ces conversations une fois que les crédits sont de retour. enabled: false conserve le texte enregistré pour plus tard ; enabled: false sans message supprime le paramètre. Même commutateur que Réponse d’attente en cas de manque de crédits dans la fenêtre modale de modification du sous-compte — voir Une réponse d’attente lorsqu’un client n’a plus de crédits.

Ce qu’un client paie par action IA, et la majoration des frais WhatsApp

Deux façons de définir votre tarif client, du plus simple au plus granulaire :

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/max-rate" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "rate": 0.35 }'

rate est le prix en crédits que le solde PROPRE du sous-compte brûle par action IA de modèle Max — votre majoration côté client en plus de ce que votre pool paie réellement. null réinitialise la surcharge au prix catalogue de la plateforme. Le taux doit être au moins égal au coût d’une action Max pour votre propre pool (vous ne pouvez donc jamais facturer un client en dessous de votre coût) et ne pas dépasser 10 crédits ; une requête en dehors de cette fenêtre est rejetée avec le plancher calculé dans le message d’erreur.

Pour une tarification par type d’action au lieu d’un tarif Max forfaitaire, utilisez action-pricing :

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/action-pricing" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "actionPricing": {
      "AI_MESSAGE": 0.6,
      "CHAT_SUMMARY": 0.15,
      "wa_carrier_multiplier": null
    }
  }'

actionPricing est une FUSION sur la carte existante du client — une clé que vous ne mentionnez pas est laissée telle quelle, et null réinitialise cette clé à sa valeur par défaut. Les clés reconnues :

Clé Prix
AI_MESSAGE Une réponse IA
AI_TOOL_USE Un appel d’outil IA
EVALUATION_CALL Une passe d’évaluation de chat
INTERRUPTION_HANDLING Gestion d’une interruption en milieu de réponse
CONTACT_TAG Une étiquette de contact attribuée par l’IA
CHAT_SUMMARY Un résumé de chat
wa_carrier_multiplier Un multiplicateur de majoration appliqué à chaque frais WhatsApp non-IA que le client paie : location mensuelle de numéro, frais de livraison sur voie gérée et coûts de transfert des modèles Meta/Twilio.

Les tarifs par action doivent être un nombre supérieur à 0 et allant jusqu’à 10 ; wa_carrier_multiplier doit être d’au moins 1 (pas de remise en dessous du coût) et jusqu’à 10. L’envoi d’une clé non reconnue, ou d’une valeur hors limites, rejette la TOTALITÉ de la requête et nomme chaque clé fautive, afin qu’une faute de frappe ne puisse jamais enregistrer silencieusement un prix qui n’est pas réellement appliqué.

Si vous êtes membre du Champions Circle, insider-rate applique votre tarif Insider (20 % de réduction sur les actions Max et Mini, les leads et automatisations Lead Finder) à un seul client au lieu de l’appliquer à l’ensemble de l’agence :

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/insider-rate" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'

L’activation nécessite que votre propre compte d’agence détienne réellement une adhésion au Circle ; la désactivation ne le nécessite jamais, donc un membre dont l’adhésion a expiré peut toujours revenir en arrière pour un client.

Verrouiller des sections du playbook d’un client

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/locked-bot-fields" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "locked_bot_fields": ["instructions", "rules"] }'

locked_bot_fields est une liste des sections du playbook à verrouiller, et elle REMPLACE la liste verrouillée du client. Envoyez null (ou []) pour tout déverrouiller. Utile pour les clients « clé en main » dont vous gérez le playbook et pour lesquels vous êtes évalué sur les résultats.

Les agents créés dans l’éditeur actuel conservent leur playbook dans ces sections ; ce sont donc celles qu’il faut verrouiller :

Section dans l’éditeur d’agent Clé API
Flux de conversation conversation_flow
Informations sur l’entreprise company_info
Offre offer
Source de prospects lead_source
Arguments de vente uniques unique_selling_points
Positionnement sur le marché market_positioning
Tarification pricing_info
Gestion des objections objection_handling
Questions à poser questions
Alerter un membre de l’équipe quand alert_human_when
Autre other
Ressources resources
Instructions par e-mail email_instructions
Personnalité personality
Objectif goal
Règles rules
Conditions de conclusion conclude_unless
Instructions (anciens agents uniquement) instructions

Les agents actuels ne lisent jamais instructions, donc le verrouiller seul ne protège rien : verrouillez conversation_flow, rules et les autres sections que le client ne doit pas modifier.

Une section verrouillée ne peut être modifiée par personne étant connecté en tant que client : ni par le compte du client lui-même, ni par les membres de son équipe, ni par sa propre clé API, ni même par vous lorsque vous accédez au tableau de bord du client depuis votre compte d’agence. La modification est refusée sur l’agent en ligne, sur un brouillon non publié et lors de la publication d’un brouillon. Pour modifier vous-même une section verrouillée, utilisez l’API avec votre clé d’agence et sub_account_id, ou déverrouillez-la, effectuez la modification, puis verrouillez-la à nouveau. Les sections que vous n’avez pas verrouillées restent entièrement modifiables.

Définir les préférences de notification d’un client en son nom

curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/notifications" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "notifications": {
      "settings": {
        "credit_alerts": { "enabled": true, "channels": ["email", "in_app"] },
        "new_contacts": { "enabled": false }
      }
    }
  }'

Seules les catégories que vous envoyez sont modifiées : chacune est fusionnée avec le paramètre actuel du client, et chaque catégorie que vous omettez conserve sa valeur. Chaque catégorie sous settings accepte enabled (booléen) et jusqu’à trois channels parmi email, in_app, webhook. Envoyez null pour réinitialiser aux valeurs par défaut de la plateforme.

Les sept points de terminaison répondent { "success": true, "data": { "subAccountUid": "...", ...the field(s) you set... } } et sont consignés dans le journal d’audit avec la valeur avant/après. Erreurs courantes : 403 si votre compte n’est pas de type Agence/Dev ou si le sous-compte n’est pas sous votre gestion, 400 s’il ne s’agit pas d’un sous-compte d’agence ou si une valeur est hors limites.


Suspendre un client ayant interrompu son abonnement

POST /v1/subaccounts/{subAccountUid}/pause · POST /v1/subaccounts/{subAccountUid}/unpause

Lorsqu’un client suspend son abonnement auprès de vous, mettez son compte en pause au lieu de le supprimer : tout ce qu’il envoie s’arrête immédiatement — messages sortants, diffusions, réponses IA sur tous les canaux — et lorsqu’il se connecte, il voit un écran de verrouillage Compte suspendu (avec votre message optionnel) au lieu de l’application. Rien n’est supprimé ou déconnecté : les agents, les diffusions, les canaux connectés, les contacts et l’historique des discussions restent exactement tels quels. Ainsi, la réactivation remet le client exactement là où il s’était arrêté — aucune configuration à refaire.

Champ Requis Description
message Non Affiché au client sur son écran de verrouillage. Laissez vide pour utiliser le libellé par défaut.
reason Non Note interne à l’agence stockée avec la mise en pause et dans le journal d’audit — jamais montrée au client.

cURL

curl -X POST "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/pause" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Your account is on hold — contact us to reactivate it.", "reason": "Subscription suspended per client email" }'

Réponse

{
  "success": true,
  "data": {
    "subAccountUid": "SUB_ACCOUNT_UID",
    "paused": true,
    "level": "hard_blocked"
  }
}

Lorsque le client revient, POST /v1/subaccounts/SUB_ACCOUNT_UID/unpause (sans corps) lève le verrouillage — l’envoi et les réponses IA reprennent immédiatement.

Bon à savoir :

  • Il s’agit du même état que le bouton bascule « Hard blocked » du tableau de bord (Bloquer / Mettre en pause un sous-compte) — un client mis en pause via l’API apparaît comme bloqué dans le tableau de bord et vice versa, et la reprise annule un blocage effectué de l’un ou l’autre côté. L’état actuel est lisible depuis le champ agency_block sur GET /v1/subaccounts (level de "none", "soft_blocked" ou "hard_blocked").
  • Les deux appels sont idempotents. Mettre en pause un client déjà en pause ne fait que rafraîchir le message, le motif et l’horodatage ; reprendre un client actif ne change rien.
  • Le client n’est pas informé automatiquement par e-mail — de nombreuses agences utilisent la marque blanche, il vous appartient donc d’en informer le client.
  • Votre propre facturation DM Champ reste inchangée. Mettre un client en pause n’affecte que votre relation avec lui.
  • Les assistants IA peuvent également effectuer cette opération : le serveur MCP expose ces points de terminaison en tant qu’outils pause_subaccount et unpause_subaccount sur l’adresse MCP standard (les outils d’agence sont exclus d’une adresse MCP en marque blanche).

Accorder ou déduire des crédits directement

POST /v1/subaccounts/credits

Ajoute ou supprime un montant exact de crédits du solde d’un sous-compte — l’équivalent API de l’ajustement manuel des crédits du tableau de bord. Il s’agit d’une modification de solde ponctuelle, distincte des paramètres récurrents monthly_credits, roll_over_to_next_month, rollover_cap_months et rollover_expiry_days sur PUT /v1/subaccounts/{subAccountUid}/limits.

C’est le seul point de terminaison sur cette page qui identifie le sous-compte par e-mail plutôt que par sub_account_id.

Champ Requis Description
email Oui L’adresse e-mail du sous-compte, telle qu’elle existe sous votre agence.
amount Oui Nombre entier non nul de crédits, au maximum 100 000 par appel. Les valeurs positives ajoutent, les valeurs négatives déduisent.
description Non Affiché en regard de l’ajustement dans l’historique des crédits du client. Par défaut, une ligne générique “Ajusté par l’agence via API” est utilisée.
idempotency_key Non Toute chaîne unique (jusqu’à 255 caractères, sans espaces) que vous choisissez pour cet ajustement. Vous pouvez l’envoyer en tant qu’en-tête Idempotency-Key.

Nouvelle tentative en toute sécurité. Envoyez la même clé d’idempotence lorsque vous relancez un appel, par exemple après un délai d’attente, afin que les crédits ne soient ajoutés ou supprimés qu’une seule fois. Pendant 24 heures, une répétition avec la même clé et les mêmes détails renvoie à nouveau la première réponse (avec un en-tête Idempotent-Replayed: true) au lieu de modifier le solde une seconde fois. La même clé avec une adresse e-mail, un montant ou une description différente est refusée (422), et une répétition qui arrive alors que le premier appel est toujours en cours reçoit une erreur 409 : attendez un instant et réessayez. Les appels sans clé fonctionnent comme auparavant.

cURL

curl -X POST "https://api.dmchamp.com/v1/subaccounts/credits" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: q3-bonus-client-example-com" \
  -d '{ "email": "[email protected]", "amount": 500, "description": "Q3 bonus credits" }'

Réponse

{
  "success": true,
  "data": {
    "email": "[email protected]",
    "previous_balance": 1200,
    "adjustment": 500,
    "new_balance": 1700
  }
}

Une valeur amount négative qui ferait passer le solde en dessous de zéro est refusée avec 400, vous indiquant le solde disponible et le montant que vous avez tenté de déduire. Si le client est en mode revendeur, un montant ajouté compte comme des crédits qu’il a achetés : il est prélevé de votre réserve de crédits d’agence à ce moment-là, exactement comme un achat via votre processus de paiement, et il est conservé après leur prochaine réinitialisation mensuelle de la même manière qu’un vrai rechargement. Lorsque votre réserve ne peut pas couvrir le montant, l’appel est refusé avec 402 et rien ne change ; rechargez donc d’abord votre solde d’agence. Une déduction sur un client revendeur retire les crédits uniquement au client ; rien n’est retourné à votre réserve. Sur un client standard avec allocation, un ajout est traité comme faisant partie de son allocation récurrente et ne prélève rien de votre réserve tant que le client ne les dépense pas. Dans les deux cas, il s’agit d’un ajout ponctuel, donc un plafond de report ou une date d’expiration définie sur le compte (ou son forfait) ne les réduit jamais — seuls l’allocation récurrente et les crédits du forfait y sont soumis.


Lire les conversations d’un sous-compte

GET /v1/subaccounts/{subAccountUid}/chats · GET /v1/subaccounts/{subAccountUid}/chats/{contactId}/messages

Vous permet de créer une vue de surveillance ou de support des conversations d’un client sans vous connecter à son compte. Listez d’abord ses contacts avec un aperçu du dernier message, puis lisez l’historique complet des messages d’un contact.

Lister les contacts

curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats?apiKey=YOUR_AGENCY_API_KEY&pageSize=25"
Paramètre de requête Requis Description
pageSize Non Contacts par page. 25 par défaut, 50 maximum.
lastActivityAt Non Curseur de pagination — transmettez le lastActivityAt de la page précédente pour continuer.
searchQuery Non Filtrer par nom de contact ou numéro de téléphone.

Réponse

{
  "success": true,
  "data": {
    "contacts": [
      {
        "contactId": "contact456",
        "firstName": "Jamie",
        "lastName": "Lee",
        "phoneNumber": "+14155551234",
        "email": "[email protected]",
        "channel": "whatsapp",
        "lastActivityAt": "2026-08-30T14:22:00.000Z",
        "lastMessage": { "body": "Thanks, that fixed it!", "direction": "inbound", "timestamp": "2026-08-30T14:22:00.000Z" },
        "isBotActive": true,
        "markChatClosed": false
      }
    ],
    "subAccountName": "Client Co",
    "subAccountEmail": "[email protected]",
    "hasMore": true,
    "lastActivityAt": "2026-08-30T14:22:00.000Z"
  }
}

Les contacts sont triés par activité la plus récente en premier. Continuez la pagination avec lastActivityAt tant que hasMore est true.

Lire les messages d’un contact

curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats/contact456/messages?apiKey=YOUR_AGENCY_API_KEY&pageSize=30"
Paramètre de requête Requis Description
pageSize Non Messages par page. 30 par défaut, 100 maximum.
beforeTimestamp Non Curseur de pagination — récupérez les messages antérieurs à cet horodatage ISO.

Réponse

{
  "success": true,
  "data": {
    "messages": [
      {
        "messageId": "msg789",
        "body": "Thanks, that fixed it!",
        "direction": "inbound",
        "timestamp": "2026-08-30T14:22:00.000Z",
        "status": "received",
        "channel": "whatsapp",
        "botReply": false,
        "mediaUrl": null,
        "mediaContentType": null,
        "name": "Jamie Lee",
        "role": null
      }
    ],
    "contactInfo": { "firstName": "Jamie", "lastName": "Lee", "phoneNumber": "+14155551234", "channel": "whatsapp" },
    "hasMore": false,
    "oldestTimestamp": "2026-08-30T14:22:00.000Z"
  }
}

Les messages sont renvoyés du plus récent au plus ancien ; parcourez l’historique page par page avec beforeTimestamp.


Lire l’utilisation des crédits et l’état des campagnes pour l’ensemble de votre portefeuille

GET /v1/subaccounts/credit-usage · GET /v1/subaccounts/campaign-status

Deux synthèses de type tableau de bord pour tous les sous-comptes que vous gérez, afin de créer vos propres rapports d’agence au lieu de cliquer sur chaque client un par un.

Utilisation des crédits

curl "https://api.dmchamp.com/v1/subaccounts/credit-usage?apiKey=YOUR_AGENCY_API_KEY&from=2026-08-01&to=2026-08-31"
Paramètre de requête Requis Description
from / to Oui Plage de dates ISO.
subAccountId Non Omettez pour un résumé à l’échelle de l’agence, une ligne par sous-compte. Incluez pour passer en mode détail : le résumé de ce sous-compte ainsi que ses enregistrements d’utilisation bruts et paginés.
limitCount Non Mode détail uniquement. 500 par défaut, 2000 maximum.
startAfterTimestamp Non Mode détail uniquement — curseur de pagination.
{
  "success": true,
  "data": {
    "subAccounts": [
      {
        "subAccountId": "abc123def456",
        "subAccountName": "Client Co",
        "subAccountEmail": "[email protected]",
        "totalCreditsUsed": 842,
        "totalCostUsd": 3.15,
        "byReason": { "AI reply": 620, "Chat summary": 80 },
        "topCampaigns": [{ "campaignName": "Inbound Leads", "creditsUsed": 500 }]
      }
    ],
    "totals": { "totalCreditsUsed": 842, "totalCostUsd": 3.15, "totalRecords": 214 },
    "dateRange": { "from": "2026-08-01", "to": "2026-08-31" },
    "hasMore": false,
    "lastTimestamp": null
  }
}

Transmettez subAccountId et la réponse contiendra également records : les frais individuels avec amount, reason, campaignName, contactName et timestamp. Un client utilisant sa propre clé BYOK plutôt que vos crédits verra ses chiffres de coût/jeton masqués (costsRedacted: true) — il s’agit de télémétrie des coûts de la plateforme, et non d’informations à afficher à un revendeur. |

État de la campagne

curl "https://api.dmchamp.com/v1/subaccounts/campaign-status?apiKey=YOUR_AGENCY_API_KEY&pageSize=20"
Paramètre de requête Requis Description
pageSize Non Sous-comptes par page. Par défaut 10, maximum 50.
lastDocumentId Non Curseur de pagination.
searchQuery Non Filtrer par nom ou e-mail de sous-compte.
{
  "success": true,
  "data": {
    "totalSubAccounts": 34,
    "subAccountsWithIssues": 3,
    "totalLiveCampaigns": 51,
    "totalPausedCampaigns": 6,
    "subAccounts": [
      {
        "userId": "abc123def456",
        "email": "[email protected]",
        "displayName": "Jamie Lee",
        "businessName": "Client Co",
        "totalCampaigns": 2,
        "liveCampaigns": 1,
        "pausedCampaigns": 1,
        "hasIssues": true,
        "issueDetails": ["1 campaign paused"],
        "lastCampaignActivity": "2026-08-29T09:00:00.000Z"
      }
    ],
    "hasMore": true,
    "lastDocumentId": "abc123def456",
    "pageSize": 20
  }
}

Chaque ligne contient également les nombres d’agents IA du client (totalAgents, activeAgents, pausedAgents, draftAgents), et le niveau supérieur ajoute totalActiveAgents et totalPausedAgents pour la page. Les champs de campagne ne couvrent que les campagnes classiques. hasIssues / issueDetails signalent les sous-comptes qui méritent une attention particulière. Sur un compte avec des agents, ils proviennent du score de préparation des agents activés (par exemple "WhatsApp Web is disconnected" ou "Agent \"Front desk\": Routed on a channel that is not connected") ; les agents désactivés ne sont jamais signalés. Sur un compte sans agent, ils signalent les campagnes classiques, comme une campagne en pause. Utilisez ceci pour créer un tableau de bord de contrôle de santé pour l’ensemble du portefeuille plutôt que d’ouvrir chaque client pour voir quels agents sont désactivés.

Pour la messagerie chronologique et l’activité de crédit pour chaque client (une série prête à être mise en graphique plutôt qu’un instantané ponctuel), voir GET /analytics/agency-rollup dans le guide de l’API Analytics.


Déployez un compte client déjà configuré

PUT /v1/snapshots/default · POST /v1/snapshots/{snapshotId}/apply

Un instantané est un modèle réutilisable : un ou plusieurs agents IA ainsi que leur base de connaissances, leurs outils et leurs médias, capturés depuis votre propre compte. Deux points de terminaison permettent de l’intégrer à votre flux de provisionnement.

Automatique — chaque nouveau client en est doté dès sa création. Marquez un instantané comme étant votre modèle par défaut une seule fois, et chaque compte que vous créerez par la suite sera installé avec celui-ci. Cela couvre les comptes créés via POST /v1/subaccounts, les comptes que vous créez dans le tableau de bord, et les comptes créés automatiquement lorsqu’un client paie via votre lien de paiement.

Tout d’abord, trouvez l’identifiant de l’instantané :

curl "https://api.dmchamp.com/v1/snapshots" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"

Ensuite, définissez-le comme étant le modèle par défaut :

curl -X PUT "https://api.dmchamp.com/v1/snapshots/default" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "snapshot_id": "SNAPSHOT_ID" }'

C’est tout pour l’intégration. Envoyez {"snapshot_id": null} pour le désactiver à nouveau. Vous pouvez faire la même chose depuis le tableau de bord en cliquant sur l’étoile sur la page Instantanés.

Pour lire ce qui est actuellement mis en favori (par exemple, avant qu’un script de provisionnement ne décide s’il faut en définir un), GET /v1/snapshots/default renvoie { "success": true, "data": { "default_snapshot_id": "SNAPSHOT_ID" } } — null quand rien n’est mis en favori. GET /v1/snapshots (utilisé pour trouver l’id ci-dessus) renvoie le même default_snapshot_id avec le tableau complet snapshots, donc la plupart des intégrations n’ont besoin que de cet appel. Les champs complets de l’objet instantané se trouvent dans le guide Snapshots.

À la demande — installation dans un compte spécifique. Utile pour l’intégration d’un client existant, ou pour fournir un second modèle à un client ultérieurement.

curl -X POST "https://api.dmchamp.com/v1/snapshots/SNAPSHOT_ID/apply" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "sub_account_id": "SUB_ACCOUNT_UID" }'

Omettez sub_account_id et il s’installera dans votre propre compte d’agence à la place. Comme pour les points de terminaison /subaccounts, ceux-ci nomment le compte cible dans le chemin ou le corps de la requête plutôt que via le paramètre ambiant sub_account_id.

Bon à savoir avant de construire dessus :

  • Les agents installés démarrent en pause. Connectez d’abord les canaux du client, puis activez l’agent. Cela est vrai pour le chemin automatique comme pour le chemin à la demande.
  • Le provisionnement n’échoue jamais à cause d’un instantané. Si l’installation ne peut pas aboutir, le compte client est tout de même créé et utilisable — il arrive simplement vide et vous pouvez appliquer l’instantané par la suite.
  • Les canaux, calendriers et connexions OAuth ne sont jamais copiés. Chaque compte connecte les siens. Les outils utilisant une clé API simple continuent de fonctionner immédiatement.
  • Appliquer deux fois crée une seconde copie. Rien n’est écrasé.

Créer le modèle lui-même via l’API

POST /v1/snapshots · agents, fonctions personnalisées et médias via l’API

La section ci-dessus distribue un instantané créé par quelqu’un dans le tableau de bord. La partie création est également exposée, de sorte que la boucle complète — assembler la configuration principale une fois, la capturer, la transmettre à chaque client — peut être exécutée à partir du code.

Les éléments, dans l’ordre où un script de provisionnement les utilise :

  1. Créez vos fonctions personnalisées. POST /v1/custom-functions en crée une ; GET /v1/custom-functions liste celles que vous avez, et GET, PUT et DELETE sur /v1/custom-functions/{customFunctionId} permettent de lire, mettre à jour et supprimer une fonction. POST /v1/custom-functions/test effectue un test à blanc d’une définition avant que vous ne l’enregistriez.
  2. Créez et configurez l’agent. POST /v1/agents le crée, PUT /v1/agents/{agentId} le met à jour, et PATCH /v1/agents/{agentId}/active avec { "active": false } le maintient en pause pendant que vous travaillez (le même appel avec true le met en ligne). GET /v1/agents les liste.
  3. Donnez ses capacités à l’agent. POST /v1/agents/{agentId}/custom-functions avec { "custom_function_id": "..." } attache une fonction à l’agent ; le DELETE /v1/agents/{agentId}/custom-functions/{customFunctionId} correspondant la détache.
  4. Remplissez la bibliothèque multimédia. POST /v1/agents/{agentId}/media-library téléverse un élément (JSON avec base64Data, mimeType, title, description) ; GET liste les éléments de l’agent, et PATCH/DELETE sur /{itemId} permettent de mettre à jour ou de supprimer un élément.
  5. Capturez-le en tant qu’instantané.
curl -X POST "https://api.dmchamp.com/v1/snapshots" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Master setup v1",
    "agent_ids": ["AGENT_ID"],
    "include_knowledge": true,
    "include_tools": true,
    "include_media": true
  }'

À partir de là, il s’agit de la section précédente : définissez-le comme favori par défaut afin que chaque nouveau client en soit doté dès sa création, ou appliquez-le à la demande. La gestion courante se trouve à côté : PATCH /v1/snapshots/{snapshotId} avec { "name": "..." } en renomme un, DELETE /v1/snapshots/{snapshotId} en supprime un (et retire le statut de favori s’il s’agissait du défaut), et GET /v1/snapshots/apply-targets liste tous les comptes sur lesquels vous pourriez effectuer une installation.

Les points de terminaison pour les agents, les fonctions personnalisées et les médias acceptent tous sub_account_id, de sorte que les mêmes appels peuvent également gérer un agent directement dans le compte d’un client. Les appels d’instantané agissent toujours sur votre compte d’agence — le modèle reste avec vous. Les schémas complets de requête et de réponse pour tous ces éléments se trouvent dans la Référence de l’API.


Gérer vos niveaux de tarification via l’API

GET /v1/agency/pricing-tiers · POST /v1/agency/pricing-tiers · PATCH /v1/agency/pricing-tiers/{tierIndex} · DELETE /v1/agency/pricing-tiers/{tierIndex}

Les plans que vous vendez dans Mode SaaS → Niveaux de tarification peuvent être lus et modifiés par code, afin que votre propre panneau d’administration ou script de provisionnement puisse ajouter un plan, ajuster un prix ou distribuer un lien de paiement sans que personne n’ait à ouvrir le tableau de bord. Authentifiez-vous avec votre clé API d’agence comme pour tout autre appel sur cette page ; ces points de terminaison sont au niveau de l’agence, ils ne prennent donc aucun sub_account_id. Chaque écriture exécute la même validation et la même synchronisation produit-et-prix Stripe que l’enregistrement dans le tableau de bord, de sorte qu’un plan créé ici est indiscernable de celui que vous avez configuré manuellement.

Lister vos niveaux

curl "https://api.dmchamp.com/v1/agency/pricing-tiers" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"

Réponse

{
  "success": true,
  "data": {
    "tiers": [
      {
        "tierIndex": 0,
        "credits": 1000,
        "price_cents": 2900,
        "currency": "usd",
        "label": "Starter",
        "billing_interval": "month",
        "trial_days": 14,
        "trial_credits": 250,
        "trial_card_required": false,
        "trial_hard_expiry": true,
        "stripe_price_id": "price_1PxAbC…",
        "stripe_product_id": "prod_QxAbC…",
        "checkout_url": "https://app.yourdomain.com/v1/checkout?id=YOUR_AGENCY_UID&tierIndex=0"
      }
    ],
    "count": 1,
    "max_tiers": 20
  }
}

Chaque niveau est renvoyé avec son tierIndex — sa position dans votre liste de Plans, qui est la manière dont les trois autres appels le désignent — et un checkout_url prêt à être partagé, le même lien que l’onglet Paiements vous donne, pointant déjà vers le domaine en marque blanche sur lequel ce plan est vendu.

Ajouter un niveau

Le corps est un objet de niveau ; il est ajouté à la fin de votre liste.

curl -X POST "https://api.dmchamp.com/v1/agency/pricing-tiers" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Starter",
    "credits": 1000,
    "price_cents": 2900,
    "currency": "usd",
    "billing_interval": "month",
    "trial_days": 14,
    "trial_credits": 250,
    "trial_card_required": false,
    "trial_hard_expiry": true,
    "features": ["channels_3", "channel_whatsapp_web", "webhooks"]
  }'

La réponse contient le niveau créé, y compris le tierIndex sur lequel il a atterri et son checkout_url.

Modifier un niveau

Envoyez uniquement les champs que vous souhaitez modifier ; tout le reste du plan est laissé tel quel.

curl -X PATCH "https://api.dmchamp.com/v1/agency/pricing-tiers/0" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "price_cents": 3900, "trial_hard_expiry": true }'

Un champ que l’API ne reconnaît pas est refusé plutôt qu’ignoré, et l’erreur le nomme — ainsi, une faute de frappe ne peut jamais modifier silencieusement un paramètre qui semble actif mais ne fait rien. La modification du prix, des crédits, de la devise ou de la fréquence de facturation crée un nouveau prix dans votre Stripe ; les clients qui ont déjà souscrit restent sur ce pour quoi ils se sont inscrits.

Supprimer un niveau

curl -X DELETE "https://api.dmchamp.com/v1/agency/pricing-tiers/2" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"

Même règle que pour le tableau de bord : un plan qui a encore des abonnés actifs ne peut pas être supprimé. La demande est refusée, vous indiquant combien d’abonnés y sont inscrits — annulez ou migrez-les d’abord. Une suppression réussie répond avec vos niveaux restants, déjà renumérotés.

Les champs d’un niveau

Champ Description
label / description Le nom du plan et la ligne optionnelle affichée sur votre page de paiement.
credits Crédits que le client reçoit par mois sur un plan mensuel ou annuel, et par période de facturation sur un plan hebdomadaire. Un nombre entier d’au moins 1, ou 0 sur un plan dont les features incluent byok (le client utilise l’IA avec sa propre clé API, donc le plan n’accorde aucun crédit et ne prélève rien sur votre réserve).
price_cents Prix par intervalle de facturation, dans la plus petite unité monétaire (2900 = 29,00 $). Sur un plan annuel, il s’agit du prix pour l’année entière.
currency Code ISO en minuscules — usd, eur, gbp, etc.
billing_interval / billing_interval_count month (par défaut), year, ou week avec un nombre de 1 à 52 pour « toutes les N semaines ».
trial_days Durée de l’essai gratuit, de 0 à 90. 0 (ou laisser vide) signifie aucun essai.
trial_credits Crédits avec lesquels le client commence l’essai. Par défaut, ceux du credits du plan.
trial_card_required false permet au client de commencer l’essai sans entrer de carte bancaire. Par défaut true.
trial_hard_expiry true renvoie les crédits d’essai inutilisés à votre réserve et verrouille le compte du client lorsqu’un essai se termine sans mise à niveau. Par défaut false — voir Expiration stricte après l’essai.
rollover_cap_months Nombre de mois d’allocation que les clients sur ce plan peuvent reporter entre les renouvellements — un nombre de 0 à 120, fractions autorisées. 0 ne reporte rien ; null (par défaut) signifie aucun plafond. Voir Plafonner les reports.
rollover_expiry_days Jours après lesquels les crédits inutilisés sont supprimés au renouvellement suivant — un nombre entier de 1 à 3650. null (par défaut) signifie qu’ils n’expirent jamais.
features / feature_settings Ce que les clients sur ce plan obtiennent — les mêmes identifiants de fonctionnalité que Choisir les types de canaux qu’un client peut connecter.
team_seats_limit Sièges d’équipe accordés par le plan : un nombre exact, 0 pour aucun, -1 pour illimité.
allowed_ai_tiers Modèles d’IA que les clients sur le plan peuvent utiliser, tirés de standard (Pro), economy, max, mini. Appliqué lorsqu’un client s’abonne et à chaque renouvellement. null ou [] (par défaut) signifie que le plan ne gère pas les modèles. Un verrouillage défini manuellement sur un sous-compte avec PUT /v1/subaccounts/:uid/ai-tiers n’est jamais écrasé par le plan.
white_label_config Sur lequel de vos domaines en marque blanche le plan est vendu.

Les champs d’essai n’ont de sens que pour un plan qui inclut un essai : enregistrez un niveau avec trial_days: 0 et ils seront supprimés. Les identifiants de produit et de prix Stripe du plan sont gérés pour vous et ne peuvent pas être définis manuellement.

Trois points à bien comprendre :

  • Les index de niveau sont des positions, pas des identifiants permanents. La suppression d’un plan décale tous les plans suivants d’un rang vers le bas. Récupérez donc la liste après toute modification — et copiez à nouveau les liens de paiement que vous avez publiés, exactement comme vous le feriez après avoir supprimé un plan dans le tableau de bord.
  • Le mode SaaS doit être configuré en premier. Ces points de terminaison nécessitent un compte d’agence avec marque blanche et une clé Stripe déjà enregistrée ; sans cela, il n’y a pas de compte Stripe sur lequel le produit et le prix du plan peuvent exister.
  • Vingt plans est la limite, tout comme dans le tableau de bord. Le champ max_tiers dans la réponse de la liste vous indique la limite actuelle.

Les schémas complets de requête et de réponse se trouvent dans la Référence de l’API, sous Agence.


Définissez votre prix par crédit via l’API

GET /v1/agency/credit-price · PATCH /v1/agency/credit-price

Le prix que les clients paient pour les recharges ponctuelles (Mode SaaS → Tarification par crédit) peut également être lu et modifié par le code. Cette fonctionnalité est conçue pour les cas où le prix doit évoluer de manière autonome : une agence qui vend des crédits dans une devise mais facture dans une autre peut laisser une tâche planifiée réviser le prix en fonction des variations du taux de change, plutôt que de demander à quelqu’un de le modifier manuellement chaque semaine.

Lire le prix actuel

curl "https://api.dmchamp.com/v1/agency/credit-price" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY"

Réponse

{
  "success": true,
  "data": {
    "price_per_credit_cents": 125,
    "price_per_credit_currency": "brl",
    "note": "USD 0.25 per credit at our reference rate",
    "minimum_cents": 60
  }
}

minimum_cents est le prix le plus bas autorisé par la plateforme dans cette devise, afin qu’une tâche puisse vérifier un nouveau prix avant de l’envoyer. Les trois valeurs sont null tant qu’aucun prix n’a été défini.

Le modifier

curl -X PATCH "https://api.dmchamp.com/v1/agency/credit-price" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "price_per_credit_cents": 130, "currency": "brl" }'

Envoyez uniquement ce que vous souhaitez modifier. price_per_credit_cents est le prix dans la plus petite unité monétaire (130 = 1,30 R$) ; currency est un code ISO en minuscules ; note est une ligne optionnelle de 200 caractères maximum affichée aux clients directement sous le prix par crédit sur leur page de facturation — pratique pour un prix de référence dans une autre devise, tel que “0,25 USD par crédit à notre taux de référence”. Envoyez "note": "" pour le supprimer. La réponse a la même forme que la lecture ci-dessus, ce qui permet à une tâche de comparer et d’ignorer l’écriture si rien n’a changé.

Les mêmes règles que dans le tableau de bord s’appliquent : le prix ne peut pas être inférieur au minimum de la plateforme pour cette devise, et le compte doit disposer de la marque blanche (white labeling). Contrairement aux points de terminaison des niveaux de tarification, aucune clé Stripe n’est requise pour lire ou modifier cette valeur.

Donnez à une tâche une clé qui ne peut rien faire d’autre

Placer votre clé d’agence complète dans un planificateur donne plus d’accès qu’une mise à jour de prix ne le nécessite. À la place, créez une clé à portée limitée restreinte à la zone Prix du crédit d’agence : cette clé peut lire et modifier le prix par crédit et rien d’autre — elle ne peut pas toucher aux sous-comptes, aux plans, aux crédits ou à votre connexion Stripe.

curl -X POST "https://api.dmchamp.com/v1/api-keys" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "label": "FX price updater", "scopes": { "read_only": false, "tags": ["Agency Credit Price"] } }'

La réponse contient la nouvelle clé dans api_key une seule fois — elle n’est plus jamais affichée, alors enregistrez-la immédiatement. Définissez "read_only": true pour une clé qui a seulement besoin de lire le prix, et ajoutez "expires_at" (une date ISO) si vous souhaitez qu’elle cesse de fonctionner d’elle-même. Seule la clé du propriétaire du compte peut créer des clés à portée limitée ; listez-les ou révoquez-les avec GET /v1/api-keys et DELETE /v1/api-keys/{id}.


Laisser un sous-compte lire votre tarification

GET /v1/subaccounts/agency-pricing

Tous les autres points de terminaison sur cette page sont appelés avec votre clé d’agence, ciblant éventuellement un client via sub_account_id. Celui-ci est l’opposé : il est appelé avec la propre clé API du sous-compte, sans sub_account_id, afin que la propre page de recharge d’un client (ou une intégration que vous construisez pour lui) puisse afficher ce que vous lui facturez sans jamais voir votre compte d’agence.

curl "https://api.dmchamp.com/v1/subaccounts/agency-pricing" \
  -H "X-API-Key: THE_SUB_ACCOUNTS_OWN_API_KEY"

Réponse

{
  "success": true,
  "data": {
    "tiers": [{ "credits": 1000, "price_cents": 2900, "currency": "usd" }],
    "price_per_credit_cents": 125,
    "price_per_credit_currency": "brl",
    "price_per_credit_note": "USD 0.25 per credit at our reference rate",
    "agency_display_name": "Client Co's Growth Partner"
  }
}

Ceci reflète exactement ce que GET /v1/agency/pricing-tiers et GET /v1/agency/credit-price vous renvoient en tant qu’agence, moins tout ce que le client n’a pas besoin de voir (identifiants Stripe, max_tiers, etc.). Cela ne fonctionne que pour un compte qui est réellement un sous-compte avec une agence liée — l’appeler depuis votre propre compte d’agence renvoie une erreur de permission.


Points à garder à l’esprit

  • Utilisez votre clé d’agence. Authentifiez chaque appel avec la clé API de votre compte d’agence — et non celle du sous-compte. Le paramètre sub_account_id est ce qui redirige l’action.
  • Les crédits proviennent du sous-compte. Les achats et les frais récurrents sont débités du solde de crédit du sous-compte ciblé, et non du vôtre.
  • Une erreur 404 signifie « ce n’est pas votre sous-compte ». Vérifiez l’identifiant et assurez-vous que le compte est bien l’un de ceux que vous gérez.
  • Le paramètre est facultatif partout où il est accepté. Omettez-le et le même point de terminaison agira sur votre compte d’agence, vous permettant ainsi de réutiliser une seule intégration pour les deux.

Connexe

  • Accès API — authentification, URL de base, erreurs, limites de débit.
  • Sous-comptes — lister et gérer les comptes que vous pouvez cibler.
  • Rechargement automatique des sous-comptes — accorder des crédits à un sous-compte via webhook + API.
  • API Agents IA : créer et configurer des agents IA.
  • API Campagnes : la ressource obsolète des campagnes classiques, incluant la référence complète des champs.
  • API Connexion de canaux — connecter les canaux d’un client.
  • API Points d’entrée : décider quel agent prend en charge une nouvelle conversation.
  • Guide de l’API Analytics (dans la section API) — le cumul des sous-comptes de l’agence et tous les autres points de terminaison de rapport.
  • Snapshots — ce qu’un snapshot capture et comment en créer un dans le tableau de bord.