DM Champ Docs

API voor bureaus

Als bureau kun je dezelfde REST API gebruiken als je klanten, maar individuele verzoeken richten op een van je beheerde sub-accounts in plaats van op je eigen account. Hiermee kun je tools bouwen die een klant volledig onboarden — hun AI-agents aanmaken, hun AI trainen op een kennisbank, hun contacten importeren, hun berichtenkanalen verbinden en telefoonnummers kopen — allemaal zonder handmatig in te loggen op elk sub-account.

Deze pagina behandelt alleen het bureau-specifieke gedrag: hoe je namens een sub-account handelt met de sub_account_id parameter. Voor de basis (het genereren van een sleutel, authenticatie, basis-URL, foutopmaak, tarieflimieten), begin met de API-toegang gids. Alles wat daar staat, is hier ook van toepassing — je authenticeert met de API-sleutel van jouw bureau-account.

Let op: Deze pagina is technisch. Als je geen ontwikkelaar bent, deel deze dan met de persoon die je integratie bouwt.


Hoe “handelen namens” werkt

Standaard handelt elk API-verzoek namens het account dat de API-sleutel bezit — jouw bureau-account. Om in plaats daarvan namens een beheerd klantaccount te handelen, voeg je de optionele sub_account_id parameter toe aan het verzoek, ingesteld op het account-id van die klant.

  • Laat sub_account_id weg → het verzoek wordt uitgevoerd namens je eigen bureau-account.
  • Voeg sub_account_id toe → het verzoek wordt uitgevoerd namens dat sub-account, maar pas nadat het platform heeft bevestigd dat het sub-account daadwerkelijk van jou is.

Je authenticeert altijd met de API-sleutel van je bureau-account. Je hebt nooit de eigen sleutel van het sub-account nodig en je beheert nooit de inloggegevens van het sub-account.

Waar je het plaatst

  • GET / DELETE-eindpunten → geef het door als queryparameter: ?sub_account_id=THE_SUB_ACCOUNT_ID (naast je apiKey, als je via query authenticeert).
  • POST / PUT / PATCH-eindpunten → voeg het toe aan de JSON-requestbody als "sub_account_id": "THE_SUB_ACCOUNT_ID".
  • AI-assistenten → niets te configureren. De MCP-server voert dezelfde instelling uit op zijn tools, dus één verbinding met je agency-sleutel kan rapporteren over elke klant: noem de klant simpelweg in je verzoek (“hoeveel contacten heeft Bella’s Bistro?”). Schrijfacties zijn ook beschikbaar: elk eindpunt dat sub_account_id accepteert, wordt beschikbaar gesteld als tool, zodat je namens een klant kunt aanmaken, wijzigen en verzenden vanuit dezelfde verbinding.

Het id van een sub-account vinden

De sub_account_id is het unieke id van het klantaccount. U kunt de lijst met uw subaccounts en hun id’s verkrijgen via de SubAccounts API-endpoints (zie de Sub-Accounts handleiding) of via de pagina Sub Accounts in de zijbalk.


Eigendom wordt altijd gecontroleerd

Wanneer je een sub_account_id doorgeeft, controleert het platform of het account een echt sub-account is en of het bij jouw bureau hoort. Pas dan wordt het verzoek verwerkt.

Als het id onbekend is, geen sub-account is of bij een ander bureau hoort, mislukt het verzoek met een 404 respons:

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

Waarom 404 en geen 403? Een “forbidden”-antwoord zou een buitenstaander vertellen dat het id bestaat, maar niet van hen is. Het retourneren van dezelfde 404 voor “bestaat niet” en “is niet van jou” betekent dat het eindpunt niet kan worden gebruikt om te ontdekken welke account-id’s bij andere bureaus horen. Behandel een 404 hier als “dit is geen sub-account dat jij beheert.”


Waar sub_account_id wordt ondersteund

sub_account_id wordt geaccepteerd op vrijwel elk resource-endpoint — elke aanroep die gegevens van een account aanmaakt, leest, bijwerkt of verwijdert. In de praktijk kun je de volledige configuratie van een sub-account inrichten en uitvoeren met je bureausleutel:

  • AI-instellingen — campagnes, agents, veelgestelde vragen, bronnen voor de kennisbank (website-crawl en document-upload), kennisbankgroepen, uitzendingen, aangepaste functies, MCP-servers
  • Contacten & CRM — contacten (inclusief import), lijsten, tags, taken, deals, afspraken, evenementen
  • Kanalen & nummers — WhatsApp / WhatsApp Web / Telegram / Instagram & Messenger / LINE koppelen, telefoonnummers zoeken / kopen / beheren, WhatsApp-sjablonen, kanaalroutering
  • Berichten & inhoud — berichten verzenden, chatsessies, chat-exports, dagelijkse samenvattingen
  • Instellingen & integraties — webhooks, configuratie van de chat-widget, white-label configuratie, BYOK SMS en andere accountinstellingen, analyses, het foutenlogboek

Bij elk van deze is de parameter optioneel — laat deze weg en de aanroep wordt uitgevoerd op je eigen bureau-account, zodat één integratie voor beide dient. Credits en verbruik komen altijd van het account waarop je je richt: kosten voor AI-antwoorden, berichten, tags en nummers van een sub-account worden verrekend met het saldo van het sub-account.

Waar het NIET van toepassing is

Een paar endpoints zijn op bureauniveau of zelfgericht en negeren sub_account_id:

  • Het beheren van de subaccounts zelf — de SubAccounts-eindpunten (aanmaken / weergeven / bijwerken van een subaccount) en het BYOK-bestedingslimiet-eindpunt benoemen het subaccount al in hun eigen URL-pad. De prijs- en beleidseindpunten en chat-monitoring-eindpunten volgen hetzelfde patroon.
  • Een Agent kopiëren tussen accounts — POST /v1/subaccounts/agents/copy benoemt beide accounts zelf, waarbij de bestemming wordt genomen als targetUserId. Zie het uitgewerkte voorbeeld hieronder. (De oudere POST /v1/subaccounts/campaigns/copy werkt op dezelfde manier, maar is verouderd samen met de rest van de Campaigns API.)
  • Credits aanpassen, en de twee agency-brede rollups — POST /v1/subaccounts/credits identificeert het subaccount in plaats daarvan via email; GET /v1/subaccounts/credit-usage en GET /v1/subaccounts/campaign-status rapporteren over elk subaccount tegelijk, dus er is geen enkel account om op te richten.
  • Het eigen account van je agency — API-sleutelbeheer, rapportage over agency-gebruik, teambeheer en je prijscategorieën hebben altijd betrekking op je agency-account.
  • Contacten toevoegen aan of verwijderen uit een lijst: POST / DELETE /v1/contacts/lists en POST /v1/contacts/lists/batch werken op het account dat de sleutel bezit. Het aanmaken, bewerken en verwijderen van de lijsten zelf (/v1/lists) vereist wel sub_account_id.
  • Inkomende bericht-webhooks — eindpunten waar externe systemen naar posten, zijn gekoppeld aan het account wiens inloggegevens ze hebben geconfigureerd, dus er valt niets om te leiden.

De altijd actuele, machineleesbare lijst van welke parameters elk endpoint accepteert, vindt u in de API-referentie van uw dashboard (Instellingen → Integraties → API-sleutel) en de OpenAPI-specificatie op GET /v1/docs/openapi.yaml. We brengen vaak API-wijzigingen door — beschouw die als de bron van waarheid.

Pagina met API-sleutelinstellingen met gemaskeerde sleutel en de knop Opnieuw genereren

Instellingen → Integraties → API-sleutel — de sleutel van uw bureau staat hier, naast de link naar de volledige API-referentie.


Vermeld uw subaccounts, of controleer één e-mailadres

GET /v1/subaccounts

Wanneer aangeroepen zonder parameters, retourneert het alle subaccounts onder uw bureau in een data-array. Voeg de optionele email-queryparameter toe om een enkele klant op te zoeken:

curl "https://api.dmchamp.com/v1/[email protected]&apiKey=YOUR_API_KEY"
  • Dat e-mailadres hoort bij een van uw actieve subaccounts → HTTP 200, met alleen dat account: { "success": true, "data": { ... } }.
  • Dat is niet het geval → HTTP 404, Agency Sub Account not found.

Er is geen parameter die antwoordt met een simpel ja of nee, dus lees de statuscode: 200 betekent dat het e-mailadres een van uw klanten is, 404 betekent van niet. Verwijderde subaccounts worden weggelaten, dus een account dat u heeft verwijderd, wordt ook gelezen als 404.

Elk account wordt geretourneerd met het profiel, de instellingen, de gebruikslimieten en de ingeschakelde functies; dit is alles wat u nodig heeft om een klantrij in uw eigen dashboard weer te geven.

Het antwoord bevat nooit inloggegevens. API-sleutels, wachtwoorden, inlogtokens en de details van de kanalen die een klant heeft gekoppeld (Twilio, Google, Meta en bring-your-own-key) worden verwijderd voordat het wordt verzonden. Er is geen parameter om te kiezen welke velden u terugkrijgt, dus lees de velden die u nodig heeft en negeer de rest.

Vereist API-toegang en een bureau-account.


Een klantaccount aanmaken

POST /v1/subaccounts

Het aanmaken van het account is één aanroep met het e-mailadres, de naam en de bedrijfsnaam van de klant. Er zijn een paar dingen die de moeite waard zijn om te weten voordat u uw aanmeldingsproces hierop bouwt.

U kunt het wachtwoord niet kiezen. Er is geen wachtwoordveld: er wordt er een voor u gegenereerd en eenmalig teruggegeven als temporary_password in het 201-antwoord. Sla het op of geef het direct door, want u zult het daarna nooit meer kunnen zien. De klant kan het wijzigen via zijn profiel of opnieuw instellen vanaf het inlogscherm.

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
  }'

Er wordt niets naar de klant gemaild tenzij u daarom vraagt. Standaard wordt het account geruisloos aangemaakt en is het uw taak om de klant erover te informeren. Stuur send_account_info_to_sub_account: true en zij ontvangen een welkomstmail met hun e-mailadres, dat tijdelijke wachtwoord en een link om in te loggen, allemaal op uw eigen white-label domein en onder uw merknaam.

De vlag heeft alleen betrekking op het e-mailadres van de klant. Uw bureau ontvangt altijd een Nieuwe sub-account aangemaakt-melding, maar deze bevat nooit het wachtwoord: om veiligheidsredenen is het 201-antwoord de enige plek waar u dit krijgt. Als het verloren gaat, stelt de klant zelf een nieuw wachtwoord in via Wachtwoord vergeten op het inlogscherm.

U bepaalt zelf de starttegoeden. usage_limits.credits is de initiële bestedingslimiet van de klant en usage_limits.monthly_credits de terugkerende maandelijkse toelage. Stuur "credits": 0 en het account begint met niets om uit te geven; laat credits weg en het account begint met een eenmalig tegoed van 100 credits zodat de AI direct kan antwoorden. Bij het aanmaken wordt er niets uit uw bureau-pool gehaald: uw pool wordt pas belast zodra de klant daadwerkelijk credits verbruikt.

Bedrijfsnamen moeten uniek zijn binnen uw bureau. Twee van uw klanten kunnen niet allebei “Client Co” heten, omdat die naam het account identificeert in uw dashboard en uw rapporten. De namen van andere bureaus spelen hierbij geen rol.

Wanneer de aanroep mislukt:

Status Wat is er gebeurd
400 Een veld ontbreekt of is onjuist, het e-mailadres is geen geldig adres, of de sleutel die u heeft gebruikt hoort niet bij een bureau-account.
401 De API-sleutel is onjuist, verlopen of ingetrokken.
402 Uw eigen abonnement is niet actief, dus nieuwe klantaccounts kunnen niet worden aangemaakt totdat uw facturering is geregeld.
403 U heeft het aantal klantaccounts bereikt dat uw abonnement toestaat.
409 Die bedrijfsnaam wordt al gebruikt door een van uw klanten, of dat e-mailadres hoort al bij een account.

Een klantaccount verwijderen

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

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

Dit is hetzelfde als de verwijderknop op de pagina Sub-accounts en dit kan niet ongedaan worden gemaakt. De klant wordt direct geblokkeerd en telt niet langer mee voor je totaal aantal klanten; hun gesprekken, contacten, agents en gekoppelde kanalen worden de komende minuten op de achtergrond gewist. Een abonnement dat de klant via jouw checkout heeft gekocht, wordt geannuleerd.

{
  "success": true,
  "message": "Sub-account deletion started",
  "data": { "uid": "SUB_ACCOUNT_UID", "email": "[email protected]", "status": "deletion_started" }
}
  • Geef email of uid door. Als je beide doorgeeft, moeten ze naar dezelfde client verwijzen.
  • Alleen je eigen clients kunnen worden verwijderd. Elk ander e-mailadres of uid, en een client die al is verwijderd, resulteert in 404.
  • Het opnieuw aanroepen terwijl de verwijdering nog bezig is, resulteert in 200 met "status": "already_in_progress".
  • AI-assistenten die zijn verbonden via de MCP-server hebben dit als de delete_subaccount-tool wanneer ze verbonden zijn met het standaard MCP-adres (agency-tools worden weggelaten uit een white-label MCP-adres).
  • Om een client tijdelijk te stoppen zonder gegevens te verliezen, kun je ze pauzeren: ze worden buitengesloten, alles blijft bewaard en met één aanroep zijn ze weer actief.

Uitgewerkt voorbeeld: Instagram & Messenger verbinden voor een sub-account

Het verbinden van Instagram & Messenger is een browsergebaseerd proces. Je start dit met de API, geeft de geretourneerde toestemmings-URL aan de klant (of opent deze voor hen), wacht tot ze autoriseren in hun browser en kiest vervolgens welke pagina moet worden verbonden — dit alles terwijl je hun sub-account target met sub_account_id.

Stap 1 — De verbinding starten

Roep het verbindings-eindpunt aan met de sub_account_id van de klant in de body. Hier worden geen inloggegevens verzonden; het platform retourneert een toestemmings-URL die de klant in een browser moet openen, plus een eenmalig correlatietoken.

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

Antwoord:

{
  "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"
}

Stuur de klant naar oauth_url in een browser om te autoriseren. De state_token correleert deze poging en is een kortstondig geheim — log deze niet. De poging verloopt op expires_at; als deze verloopt, begin dan opnieuw.

Stap 2 — Pollen totdat de pagina’s zijn geladen

Nadat de client toestemming heeft gegeven, pols je het status-eindpunt (met dezelfde sub_account_id, ditmaal als queryparameter) totdat de verbindbare pagina’s verschijnen.

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"]

Antwoord:

{
  "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
}

Het status-veld doorloopt pending → token_received → pages_loaded → connected. Wacht op pages_loaded voordat u een pagina selecteert. Er kunnen ook twee terminale foutstatussen verschijnen in plaats van dat het proces vordert: failed en expired (de client heeft toestemming geweigerd, of het venster van ~30 minuten van het state-token is verstreken) — een reason-veld is inbegrepen wanneer een van beide optreedt. Stop met pollen en begin opnieuw bij stap 1 als u er een ziet; wacht niet eeuwig op pending. Pagina-toegangstokens worden nooit geretourneerd.

Stap 3 — Selecteer de pagina om te verbinden

Kies een van de pagina-id’s uit Stap 2 en selecteer deze. Het selecteren van een pagina verbindt zowel Instagram als Messenger voor die pagina. Voeg sub_account_id opnieuw toe aan de body.

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()

Antwoord:

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

Dat is alles — Instagram en Messenger zijn nu verbonden met het sub-account van de client. Je hebt alleen de page_id verstrekt; de onderliggende inloggegevens worden op de server opgelost en gaan nooit door je integratie heen.


Uitgewerkt voorbeeld: een nummer kopen voor een sub-account

Het kopen van een nummer werkt op dezelfde manier: zoek met sub_account_id in de query en koop het vervolgens met diezelfde waarde in de body. Credits worden afgeschreven van het saldo van het sub-account en het nummer wordt ingericht op het sub-account.

Zoeken (cURL):

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

Kopen (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();

Aankoop (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()

Antwoord:

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

Het nummer wordt ingericht in de PURCHASED-status en de registratie van de WhatsApp-afzender gaat op de achtergrond door. Pol GET /v1/phone-numbers/{phoneNumber}/status?sub_account_id=abc123def456 totdat de status ONLINE bereikt voordat u gaat verzenden.


Uitgewerkt voorbeeld: een sjabloon-Agent naar elke nieuwe klant sturen

Het gebruikelijke agency-patroon is om één master-Agent op uw agency-account te houden, afgesteld zoals u wilt dat elke klant begint, en bij het inrichten een kopie ervan in elk nieuw sub-account te plaatsen. Dat zijn drie aanroepen en daarna hoeft er niets meer herhaald te worden: de kopie behoudt zijn instellingen totdat u ze wijzigt.

Stap 1 — De Agent kopiëren

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
  }'

Het antwoord bevat het id van de nieuwe Agent op data.agent_id. De veelgestelde vragen, kennisbank en mediabibliotheek worden meegekopieerd; de WhatsApp-sjablonen, gekoppelde sociale berichten en contacten van het bronaccount worden bewust niet meegekopieerd. Volledige veldenlijst in de AI Agents API.

Let op: dit endpoint gebruikt targetUserId in plaats van sub_account_id — het benoemt beide accounts zelf. De twee aanroepen hieronder gebruiken de normale sub_account_id-parameter.

Stap 2 — Inschakelen

De kopie komt altijd gepauzeerd aan, dus hij kan niemand berichten sturen totdat u dat aangeeft. Dit is ook het moment om de AI-laag vast te leggen waarop u de klant wilt hebben; deze blijft daar staan, dus het is niet nodig om deze volgens een schema opnieuw toe te passen.

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" }'

Om te voorkomen dat de klant de laag daarna wijzigt, kunt u de toegestane lagen vergrendelen op het sub-account in plaats van de waarde opnieuw te verzenden.

Stap 3 — De kanalen van de klant hieraan koppelen

De kopie komt ook zonder routering aan, dus niets bereikt de Agent totdat u deze instelt als de beantwoorder op de kanalen die de klant heeft verbonden. Eén aanroep per kanaal:

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" }'

Vanaf hier wordt een eerste bericht van een onbekend contact op dat kanaal automatisch opgepikt door de gekopieerde Agent. Zie Een kanaal naar een Agent wijzen voor de andere kanalen en routering per nummer.

Stel de tijdzone van de klant in wanneer je het sub-account aanmaakt. Geef time_zone_id door op POST /v1/subaccounts. De actieve uren van een agent worden geëvalueerd in de eigen tijdzone van het sub-account, dus een klant die zonder tijdzone is aangemaakt, krijgt een schema dat wordt gelezen ten opzichte van UTC — wat ongemerkt verschuift wanneer de assistent mag antwoorden.


Sla de setup wizard over voor een klant die u zelf configureert

POST /v1/subaccounts

Standaard wordt de eigenaar van een nieuw sub-account de eerste keer dat hij inlogt door de begeleide Setup Wizard geleid. Voor ‘done-for-you’-klanten — waarbij jij de AI-agent bouwt en de kanalen verbindt voordat de klant ooit inlogt — geef je guided_onboarding: false door wanneer je het account aanmaakt. Zij komen in plaats daarvan op het normale startscherm terecht — het dashboard op een computer, hun chats op een telefoon — en het item Setup Wizard is verborgen in hun zijbalk.

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 }
  }'

Laat het veld weg (of stuur true) en de wizard gedraagt zich precies zoals altijd, dus bestaande integraties hoeven niet te worden gewijzigd. Om een klant later de wizard terug te geven, laat u het guided_onboarding-item opnieuw zien met PUT /v1/subaccounts/{subAccountUid}/menu-visibility (hieronder) — menu-zichtbaarheid bepaalt of de wizard bereikbaar is, guided_onboarding regelt alleen de omleiding bij de eerste aanmelding.


Taken, dagelijkse samenvattingen of de mediabibliotheek uitschakelen voor een klant

POST /v1/subaccounts

Deze drie staan standaard aan voor elke nieuwe klant, tenzij je anders aangeeft, en ze gedragen zich anders dan alle andere functies in deze handleiding: ze zijn opt-out, niet opt-in. Ze weglaten uit features is op zichzelf niet genoeg, omdat de features-lijst van een oudere integratie ze simpelweg nooit vermeldde — we kunnen niet zien of “het bureau dit heeft uitgeschakeld” of dat “deze lijst is geschreven voordat de optie bestond”.

Geef het dus expliciet aan met 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
    }
  }'

Elke sleutel is optioneel; alles wat je weglaat, blijft aanstaan. Met tasks: false stopt de AI met het aanmaken van taken voor die klant en worden er geen “Nieuwe taak aangemaakt”-e-mails verzonden; met daily_summaries: false wordt de dagelijkse samenvatting nooit gegenereerd of gemaild.

feature_settings is het enige dat deze drie uitschakelt bij aanmaak. Ze weglaten uit features doet op zichzelf niets, ongeacht hoe de rest van je lijst eruitziet — dat is bewust gedaan, zodat een oudere integratie niet stilletjes alle drie verliest.

Om dit achteraf te wijzigen, stuur je de volledige features-lijst naar PUT /v1/subaccounts/{subAccountUid}/features — daar zorgt aanwezigheid in de lijst ervoor dat een functie wordt ingeschakeld en afwezigheid dat deze wordt uitgeschakeld.


Automatisch inloggen van uw klanten in hun sub-account (SSO)

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

Eén aanroep met uw agency API-sleutel levert een URL op die direct klaar is voor gebruik en de klant rechtstreeks in zijn eigen sub-account inlogt — geen inlogscherm, geen wachtwoordstap, niets om zelf te bouwen. Open het in een nieuw tabblad, via een redirect of in een iframe binnen uw eigen product.

Veld Vereist Beschrijving
redirect Nee In-app pagina waar de client moet eindigen, bijv. "/chats" of "/agents". Wordt geretourneerd als deep_link_url in het antwoord.
app_base_url Nee Dashboard-host voor de link. Standaard ingesteld op uw white-label app-domein (of het platformdomein als u er geen heeft). Moet https zijn.

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" }'

Antwoord

{
  "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"
}

Hoe u dit goed gebruikt:

  • Eén stap. Het openen van url logt de klant in en brengt hen direct naar de redirect pagina van het dashboard — geen inlogscherm, geen tussenliggende pagina. deep_link_url benoemt dezelfde bestemming, voor integrators die er de voorkeur aan geven om na het inloggen expliciet naar een frame te navigeren; zodra de sessie bestaat, werkt elk dashboardpad in die browsercontext.
  • Op aanvraag aanmaken, direct openen. De link bevat inloggegevens en verloopt na ongeveer een uur. Vraag deze aan de serverzijde aan op het moment dat de klant klikt, en sla deze nooit op en verstuur deze nooit per e-mail.
  • Het inlogtoken reist mee in het URL-fragment (#…), dat browsers nooit naar servers sturen, en het wordt uit de adresbalk verwijderd zodra het is verbruikt.
  • Alleen uw eigen subaccounts. Het eindpunt weigert elk account dat niet van uw bureau is.
  • Een verlopen link toont een duidelijke foutmelding met een pad om het opnieuw te proberen — maak een nieuwe aan.

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

Bepaalt welke zijbalk- en instellingsitems een sub-account ziet — handig wanneer u het dashboard insluit en alleen de onderdelen wilt tonen die uw product nog niet dekt. Alles wat niet wordt vermeld, blijft zichtbaar; stuur null als de volledige menuVisibility waarde om alles weer zichtbaar te maken. Het verbergen van een item verbergt het menu-item — combineer dit met de functies die u aan het sub-account verleent voor strikte toegangsbepaling.

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 }
    }
  }'

Antwoord

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

side_nav accepteert deze 13 sleutels, die overeenkomen met de namen van de zijbalkitems: Dashboard, DailySummaries, Chats, Contacts, Deals, Tasks, Automations, Campaigns, Appointments, Settings, Help, CreditsCounter (het creditsaldo dat in de zijbalk wordt getoond) en guided_onboarding (de Setup Wizard). Campaigns verbergt alleen de verouderde Campagnes-pagina; de pagina’s AI Agents en Broadcasts hebben geen sleutel en kunnen op deze manier niet worden verborgen. Drie verdere sleutels — AiInsights, Sub Accounts en Agency Reselling — worden geaccepteerd maar doen niets: ze waren alleen van toepassing op het verouderde klassieke dashboard, dus het instellen ervan heeft geen effect op je sub-accounts. Ontbrekende sleutels betekenen zichtbaar; wanneer je zelf inlogt op het sub-account, worden verborgen items tijdelijk getoond zodat je dingen altijd weer kunt terugdraaien.

Hetzelfde menuVisibility object accepteert ook twee optionele velden voor het hoofddashboard van de klant. dashboard_widgets koppelt een widget-id aan true (getoond) of false (verborgen), en dashboard_order is een lijst met widget-ids in de volgorde waarin ze moeten verschijnen. De ids, in hun standaardvolgorde, zijn kpis, performance, credits (Kredietgebruik), funnel, inbox, outcomes, channel_health, ai_cost, ai_human, heatmap (Meest actieve tijden), top_campaigns (Topagenten), contacts_by_country, activity en tasks_deals. Ontbrekende ids blijven zichtbaar, en ids die worden weggelaten uit dashboard_order volgen in de standaardvolgorde. Bijvoorbeeld, "dashboard_widgets": { "credits": false } verbergt het kredietpaneel voor de klant.

Een pagina verbergen in het menu geeft nooit toegang tot de pagina. Automations vereist dat de automations-functie is verleend op het subaccount — zet de sleutel op true zonder deze functie en de pagina zal nog steeds niet verschijnen. Tasks en DailySummaries werken andersom: ze staan aan voor elke klant tenzij je ze uitschakelt (zie Taken, dagelijkse samenvattingen of de mediabibliotheek uitschakelen voor een klant).


Kies welke kanaaltypen een klant kan verbinden

PUT /v1/subaccounts/{subAccountUid}/features

De Kanaaltypen-schakelaars die je ziet op een abonnementsniveau zijn gewone functie-ID’s, dus je kunt ze per klant instellen via de API in plaats van via het dashboard. Dit is een van de eindpunten die het sub-account in zijn eigen URL benoemt, dus het vereist geen sub_account_id.

Functie-ID Kanaal
channel_chat_widget Website Chat Widget
channel_whatsapp_api WhatsApp Business API
channel_whatsapp_web WhatsApp Web (QR-gekoppeld nummer)
channel_instagram Instagram
channel_messenger Facebook Messenger
channel_telegram Telegram
channel_line LINE
channel_viber Viber
channel_email E-mail mailbox
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"
    ]
  }'

Waar u op moet letten:

  • De aanroep vervangt de volledige lijst met functies. Stuur elke functie die de klant moet behouden, niet alleen de functies die u wijzigt. Dezelfde ID’s werken als features op POST /v1/subaccounts wanneer u het account aanmaakt.
  • Kanaaltypen en het aantal kanalen zijn afzonderlijke beperkingen en beide zijn van toepassing. channels_1 / channels_3 / channels_unlimited bepalen hoeveel verbindingen er zijn; de channel_* ID’s bepalen welke typen. Het bovenstaande voorbeeld betekent “maximaal 3 verbindingen, en alleen Chat Widget, WhatsApp Web of Instagram”.
  • automations_edit, broadcasts_send en smart_lists_create laten de klant hun eigen automatiseringen, uitzendingen en slimme lijsten maken, bewerken en verwijderen. Een lijst waarin geen van de drie wordt genoemd, laat ze zoals ze zijn (op een nieuw sub-account: alle drie aan), zodat een oudere integratie blijft werken. Benoem er ten minste één en de lijst stelt alle drie in: degenen die u weglaat, worden uitgeschakeld. De klant kan hoe dan ook gebruiken wat u voor hen hebt ingesteld, en uw bureau-API-sleutel en uw eigen sessies in het account van de klant worden nooit beperkt door deze drie.
  • Elke andere functie is precies wat de lijst zegt, bij aanmaken en bijwerken. Een klant die is aangemaakt of bijgewerkt met een features lijst krijgt die functies en niets anders. Dat is inclusief crm_erp_integrations (de sectie CRM & ERP-integraties, waar een klant Odoo verbindt): deze staat alleen aan wanneer uw lijst deze bevat, dus voeg deze toe als de klant een CRM of ERP moet verbinden. Een klant die is aangemaakt zonder enige features lijst krijgt de standaardset, die deze bevat.
  • Het sturen van helemaal geen channel_* ID’s betekent geen kanaalbeperking. Dat is het oorspronkelijke gedrag, en daarom werden bestaande klanten niet beïnvloed toen dit werd uitgebracht. Stuur er een of meer en al het andere wordt als vergrendeld weergegeven op de Kanalen-pagina van de klant met een upgrade-notitie in plaats van een Verbind-knop. Kanalen die de klant al heeft verbonden, blijven werken.

Het instellen van de kanaallijst op een abonnementsniveau, zodat elke klant die dat niveau koopt het overneemt, gebeurt in het dashboard onder je agency-abonnementinstellingen. Dit eindpunt stelt het in op één specifiek sub-account.


Stel een exact limiet voor teamleden in voor een klant

PUT /v1/subaccounts/{subAccountUid}/limits

De team_seats_*-functies bieden alleen vooraf ingestelde stappen (3 / 5 / 10 / onbeperkt). Om een klant een exact aantal teamzetels te geven — 2, 7, 15, wat dan ook — stel in plaats daarvan usage_limits.team_seats_limit in. Dit heeft voorrang op de voorinstellingen en het platform dwingt dit af bij elke uitnodiging, directe toevoeging en acceptatie van een uitnodiging: zodra de limiet is bereikt, worden verdere uitnodigingen aan de serverzijde geweigerd.

  • Een positief geheel getal is het exacte maximum.
  • 0 betekent dat teamleden niet zijn inbegrepen — de klant kan niemand uitnodigen.
  • -1 betekent onbeperkt.
  • null wist de aangepaste limiet en valt terug op welke team_seats_*-voorinstelling dan ook in de functielijst staat.

Het verlagen van de limiet verwijdert nooit bestaande teamleden; het stopt alleen het toevoegen van nieuwe leden.

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 }
  }'

Je kunt dit ook instellen tijdens het aanmaken: POST /v1/subaccounts accepteert usage_limits.team_seats_limit met dezelfde semantiek. Om de huidige waarde te lezen, haal je het sub-account op met GET /v1/subaccounts?email=... en kijk je naar usage_limits.team_seats_limit (afwezig/null = de voorinstellingen bepalen het). Hetzelfde eindpunt werkt ook credits, monthly_credits, roll_over_to_next_month, rollover_cap_months, rollover_expiry_days en byok_monthly_limit_usd bij — stuur alleen de sleutels die je wilt wijzigen. Een creditManagementMode op het hoogste niveau ("manual" of "reselling") schakelt de kredietmodus van de klant; een sub-account dat via de API is aangemaakt, start in de handmatige modus, dus schakel het over naar "reselling" voordat de klant betaalt via je SaaS Mode-checkout (zie Sub-Accounts, Een gratis proefperiode uitvoeren).

Hoe dit samenwerkt met de stoellimieten van SaaS-abonnementen. Uw SaaS-abonnementen kunnen hun eigen stoeltoewijzing hebben (in te stellen in de abonnementeneditor — zie Teamstoelen in een abonnement), die automatisch wordt toegepast wanneer een klant een abonnement afsluit. Een limiet die u via dit eindpunt instelt, telt als een handmatige toekenning: bij het kopen van een abonnement wordt deze vervangen door de eigen stoeltoewijzing van het abonnement (die aankoop is een expliciete keuze voor een abonnement), maar onbeheerde maandelijkse verlengingen overschrijven nooit een handmatige limiet — een eenmalige uitzondering die u aan een klant verleent, blijft dus behouden gedurende de factureringscyclus. Het wissen van de handmatige limiet met null geeft het veld bij de volgende verlenging weer terug aan het abonnement.

Beperk wat een klant meeneemt tussen verlengingen. Twee extra usage_limits sleutels staan naast roll_over_to_next_month. Beide worden ook geaccepteerd door POST /v1/subaccounts bij het aanmaken, en null wist beide.

Sleutel Wat het doet
rollover_cap_months Aantal maanden aan tegoed dat de klant mag behouden. Een getal van 0 tot 120, breuken toegestaan (0.5 = een halve maand). Bij elke verlenging wordt het ongebruikte saldo ingekort tot maximaal dit aantal keer het tegoed dat die verlenging toekent, voordat de nieuwe tegoeden worden toegevoegd; 0 neemt niets mee.
rollover_expiry_days Een geheel aantal dagen, 1 tot 3650. Tegoeden die zo lang ongebruikt blijven, vervallen bij de eerste verlenging nadat ze die leeftijd bereiken. Uitgaven worden altijd eerst van de oudste tegoeden afgetrokken, dus een klant die elke maand zijn tegoed opmaakt, verliest nooit iets.

Indien niet ingesteld, vallen beide terug op het abonnement van de klant; een waarde die hier wordt verzonden, gaat voor op die van het abonnement. Alleen terugkerende tegoeden (het maandelijkse tegoed en abonnementstegoeden) zijn hieraan onderhevig: opwaarderingen, automatische opwaarderingen en eenmalige toevoegingen worden nooit beperkt of laten vervallen. Elke inkorting wordt naar de tegoedgeschiedenis van de klant geschreven als een Rollover Cap Credit Adjustment of een Expired Credits Credit Adjustment en telt nooit als verbruik. De equivalenten op abonnementsniveau zijn rollover_cap_months en rollover_expiry_days op een prijscategorie — zie De velden op een categorie en Beperken wat wordt meegenomen.


AI-prijzen en -beleid per klant instellen

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

Acht extra schakelaars per klant, naast /limits, /features en /menu-visibility hierboven. Elk gebruikt de uid van het sub-account in de URL (geen sub_account_id body/query-parameter — het doel is al benoemd in het pad) en heeft hetzelfde bereik: jouw agentschap-sleutel, en het sub-account moet bij jouw agentschap horen.

Welke AI-modellen een klant kan gebruiken

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 } meldt de client aan voor (of af van) de Max AI-laag, tegen de catalogusprijs van het platform. Het inschakelen hiervan voor een BYOK-client verandert hun AI-kosten van “0 credits, betaald via mijn eigen sleutel” naar “in rekening gebracht via mijn creditpool”, dus het is een bewuste beslissing per client in plaats van een standaardinstelling voor het hele bureau.

Om te beperken VAN WELKE niveaus een klant zijn Agents mag kiezen (in plaats van alleen Max te beperken), gebruik je 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 is een array afkomstig van standard, economy, max, mini — het VERVANGT de toegestane lijst van de klant. Stuur null (of []) om de beperking op te heffen en de klant toe te staan elk niveau te kiezen. Een lijst die hier wordt ingesteld, telt als een handmatige vergrendeling: de eigen allowed_ai_tiers van een abonnement (zie Beheer je prijscategorieën via de API) heeft bij verlenging geen invloed meer op deze klant. Dit is belangrijk omdat een sub-account dat zijn eigen AI-niveau kiest, verbruikt uit jouw tegoedpool; het is dus de knop waarmee je bepaalt welke modellen een reseller-klant mag gebruiken op jouw kosten.

Een antwoordbericht terwijl de klant geen tegoed meer heeft

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." }'

Wanneer het saldo van de klant (of jouw pool) leeg is, kan de AI niet antwoorden en hoort de contactpersoon niets. Met enabled: true krijgt elke contactpersoon die tijdens de uitval schrijft één keer message (maximaal 500 tekens, verzonden zoals het is op elk kanaal), en de AI beantwoordt die gesprekken echt zodra er weer tegoed is. enabled: false bewaart de opgeslagen tekst voor later; enabled: false zonder message verwijdert de instelling. Dezelfde schakelaar als Antwoordbericht bij geen tegoed in de bewerkingsmodal van het sub-account — zie Een antwoordbericht terwijl een klant geen tegoed meer heeft.

Wat een klant betaalt per AI-actie en de WhatsApp-toeslag

Twee manieren om je tarief voor klanten in te stellen, van eenvoudigst naar meest gedetailleerd:

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 is de prijs in credits die het EIGEN saldo van het sub-account verbruikt per AI-actie van het Max-model — jouw toeslag voor de klant bovenop wat jouw pool daadwerkelijk betaalt. null wist de overschrijving terug naar de catalogusprijs van het platform. Het tarief moet ten minste gelijk zijn aan wat een Max-actie jouw eigen pool kost (zodat je een klant nooit onder je eigen kostprijs kunt prijzen) en maximaal 10 credits; een verzoek buiten dat venster wordt afgewezen met de berekende ondergrens in het foutbericht.

Gebruik action-pricing voor prijzen per actietype in plaats van één vast Max-tarief:

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 is een SAMENVOEGING met de bestaande kaart van de klant — een sleutel die je niet noemt, blijft zoals hij was, en null zet die sleutel terug naar de standaardwaarde. De herkende sleutels:

Sleutel Prijzen
AI_MESSAGE Een AI-antwoord
AI_TOOL_USE Een AI-tool-aanroep
EVALUATION_CALL Een chat-evaluatieronde
INTERRUPTION_HANDLING Een onderbreking tijdens het antwoorden afhandelen
CONTACT_TAG Een door AI toegewezen contactlabel
CHAT_SUMMARY Een chatsamenvatting
wa_carrier_multiplier Een toeslagvermenigvuldiger toegepast op elke niet-AI WhatsApp-vergoeding die de klant betaalt: maandelijkse nummerhuur, bezorgkosten voor beheerde banen en Meta/Twilio-template-doorgiftekosten.

Tarieven per actie moeten een getal groter dan 0 en tot 10 zijn; wa_carrier_multiplier moet ten minste 1 zijn (geen korting onder de kostprijs) en tot 10. Het verzenden van een niet-herkende sleutel, of een waarde buiten het bereik, wijst de HELE aanvraag af en benoemt elke foutieve sleutel, zodat een typefout nooit stilletjes een prijs kan opslaan die in werkelijkheid niet wordt toegepast.

Als je lid bent van de Champions Circle, geeft insider-rate je Insider-tarief (20% korting op Max- en Mini-acties, Lead Finder-leads en automatiseringen) door aan één klant in plaats van dit toe te passen op het hele bureau:

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 }'

Het inschakelen vereist dat je eigen bureau-account daadwerkelijk een Circle-lidmaatschap heeft; het uitschakelen vereist dit nooit, dus een verlopen lid kan altijd een klant terugzetten.

Vergrendel secties van het draaiboek van een klant

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 is een array getrokken uit instructions, goal, rules, personality, conclude_unless — het VERVANGT de vergrendelde lijst van de klant. Een vergrendelde sectie wordt aan de serverzijde geweigerd als de SUB-ACCOUNT zelf probeert deze te wijzigen (direct of via API-sleutel), terwijl jij (via sub_account_id) en de eigen dashboard-beheerdersweergave van de klant nog steeds alles kunnen bewerken. Stuur null (of []) om alles te ontgrendelen. Handig voor ‘done-for-you’-klanten waarbij jij het draaiboek bezit en wordt beoordeeld op het resultaat.

Stel namens een klant diens meldingsvoorkeuren in

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 }
      }
    }
  }'

Alleen de categorieën die u verstuurt, worden gewijzigd: elke categorie wordt samengevoegd met de huidige instelling van de client, en elke categorie die u weglaat, behoudt zijn waarde. Elke categorie onder settings accepteert enabled (boolean) en maximaal drie channels uit email, in_app, webhook. Verstuur null om terug te keren naar de standaardinstellingen van het platform.

Alle zeven eindpunten reageren met { "success": true, "data": { "subAccountUid": "...", ...the field(s) you set... } } en worden in het auditlogboek bijgehouden met de waarde voor/na. Veelvoorkomende fouten: 403 als je account geen Agency/Dev is of de sub-account niet van jou is om te beheren, 400 als het geen bureau-sub-account is of een waarde buiten het bereik valt.


Pauzeer een klant die zijn abonnement heeft opgeschort

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

Wanneer een klant zijn abonnement bij jou opschort, pauzeer dan zijn account in plaats van het te verwijderen: alles wat ze versturen stopt onmiddellijk — uitgaande berichten, broadcasts, AI-antwoorden op elk kanaal — en wanneer ze inloggen zien ze een Account gepauzeerd-schermvullend slot (met jouw optionele bericht) in plaats van de app. Niets wordt verwijderd of losgekoppeld: agents, broadcasts, verbonden kanalen, contacten en chatgeschiedenis blijven precies zoals ze zijn, dus het opheffen van de pauze brengt de klant precies terug waar hij gebleven was — geen installatie die opnieuw moet worden gedaan.

Veld Vereist Beschrijving
message Nee Wordt getoond aan de klant op hun vergrendelscherm. Laat leeg voor de standaardtekst.
reason Nee Interne notitie voor het bureau, opgeslagen bij de pauze en in het auditlogboek — wordt nooit aan de klant getoond.

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" }'

Antwoord

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

Wanneer de klant terugkomt, heft POST /v1/subaccounts/SUB_ACCOUNT_UID/unpause (geen body) de blokkering op — het versturen van berichten en AI-antwoorden wordt direct hervat.

Goed om te weten:

  • Dit is dezelfde status als de ‘Hard blocked’-schakelaar in het dashboard (Een sub-account blokkeren / pauzeren) — een client die via de API is gepauzeerd, wordt als geblokkeerd weergegeven in het dashboard en vice versa, en het opheffen van de pauze verwijdert een blokkering die vanaf beide kanten is geplaatst. De huidige status is afleesbaar uit het agency_block-veld op GET /v1/subaccounts (level van "none", "soft_blocked" of "hard_blocked").
  • Beide aanroepen zijn idempotent. Het pauzeren van een al gepauzeerde client ververst alleen het bericht, de reden en de tijdstempel; het opheffen van de pauze bij een actieve client verandert niets.
  • De client krijgt niet automatisch een e-mail — veel bureaus gebruiken white-labeling, dus het informeren van de client laten we aan jou over.
  • Je eigen DM Champ-facturering blijft onaangetast. Het pauzeren van een client heeft alleen invloed op jouw relatie met hen.
  • AI-assistenten kunnen dit ook: de MCP-server stelt deze endpoints beschikbaar als de pause_subaccount- en unpause_subaccount-tools op het standaard MCP-adres (agency-tools worden weggelaten uit een white-label MCP-adres).

Direct credits toekennen of aftrekken

POST /v1/subaccounts/credits

Voegt een exact bedrag aan tegoed toe aan of verwijdert dit van het saldo van een sub-account — het API-equivalent van de handmatige tegoedcorrectie in het dashboard. Dit is een eenmalige saldowijziging, anders dan de terugkerende monthly_credits, roll_over_to_next_month, rollover_cap_months en rollover_expiry_days instellingen op PUT /v1/subaccounts/{subAccountUid}/limits.

Dit is het enige eindpunt op deze pagina dat de sub-account identificeert op e-mailadres in plaats van sub_account_id.

Veld Verplicht Beschrijving
email Ja Het e-mailadres van de sub-account, zoals dit bekend is bij uw bureau.
amount Ja Een geheel getal ongelijk aan nul voor het aantal credits, maximaal 100.000 per aanroep. Positief voegt toe, negatief trekt af.
description Nee Wordt getoond bij de aanpassing in de kredietgeschiedenis van de klant. Standaard wordt de algemene regel “Aangepast door bureau via API” gebruikt.
idempotency_key Nee Elke unieke tekenreeks (maximaal 255 tekens, geen spaties) die u kiest voor deze aanpassing. U kunt deze ook als Idempotency-Key header meesturen.

Veilig opnieuw proberen. Stuur dezelfde idempotentie-sleutel mee wanneer u een aanroep opnieuw probeert, bijvoorbeeld na een time-out, zodat de credits slechts één keer worden toegevoegd of verwijderd. Gedurende 24 uur zal een herhaling met dezelfde sleutel en dezelfde details opnieuw het eerste antwoord geven (met een Idempotent-Replayed: true header) in plaats van het saldo een tweede keer te wijzigen. Dezelfde sleutel met een ander e-mailadres, bedrag of beschrijving wordt geweigerd (422), en een herhaling die binnenkomt terwijl de eerste aanroep nog wordt uitgevoerd, krijgt een 409: wacht even en probeer het opnieuw. Aanroepen zonder sleutel werken zoals voorheen.

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" }'

Antwoord

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

Een negatieve amount die het saldo onder nul zou brengen, wordt geweigerd met 400, waarbij het beschikbare saldo en het bedrag dat u probeerde af te trekken worden vermeld. Als de klant in de wederverkoopmodus staat, telt een toegevoegd bedrag als credits die zij hebben gekocht: het wordt op dat moment uit uw bureau-creditpool gehaald, precies zoals bij een aankoop via uw kassa, en het blijft na hun volgende maandelijkse reset behouden, net zoals bij een echte opwaardering. Wanneer uw pool het bedrag niet kan dekken, wordt de aanroep geweigerd met 402 en verandert er niets; zorg er dus voor dat u eerst uw bureausaldo opwaardeert. Een aftrekking bij een wederverkoopklant verwijdert de credits alleen bij de klant; er wordt niets teruggestort in uw pool. Bij een standaard toegewezen klant wordt een toevoeging behandeld als onderdeel van hun periodieke toelage en wordt er niets uit uw pool gehaald totdat de klant het uitgeeft. Hoe dan ook zijn het eenmalige toevoegingen, dus een limiet voor overdracht of een vervaldatum die op het account (of het abonnement) is ingesteld, zal deze nooit inkorten — alleen de periodieke toelage en abonnementscredits zijn daaraan onderhevig.


Gesprekken van een sub-account lezen

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

Hiermee kunt u een monitoring- of ondersteuningsweergave van de gesprekken van een klant opbouwen zonder in te loggen op hun account. Vermeld eerst hun contacten met een voorbeeld van het laatste bericht en lees vervolgens de volledige berichtgeschiedenis van één contact.

Contacten vermelden

curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats?apiKey=YOUR_AGENCY_API_KEY&pageSize=25"
Query-parameter Vereist Beschrijving
pageSize Nee Contacten per pagina. Standaard 25, maximaal 50.
lastActivityAt Nee Paginering-cursor — geef de lastActivityAt van de vorige pagina door om door te gaan.
searchQuery Nee Filteren op contactnaam of telefoonnummer.

Antwoord

{
  "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"
  }
}

Contacten worden gesorteerd op meest recente activiteit eerst. Blijf pagineren met lastActivityAt zolang hasMore gelijk is aan true.

Berichten van één contact lezen

curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats/contact456/messages?apiKey=YOUR_AGENCY_API_KEY&pageSize=30"
Query-parameter Vereist Beschrijving
pageSize Nee Berichten per pagina. Standaard 30, maximaal 100.
beforeTimestamp Nee Paginering-cursor — haal berichten op die ouder zijn dan deze ISO-tijdstempel.

Antwoord

{
  "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"
  }
}

Berichten worden geretourneerd met de nieuwste eerst; blader achteruit door de geschiedenis met beforeTimestamp.


Kredietgebruik en campagnestatus voor uw hele portfolio lezen

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

Twee overzichten in dashboardstijl voor elk subaccount dat u beheert, voor het opbouwen van uw eigen bureau-rapportage in plaats van dat u per klant moet doorklikken.

Kredietgebruik

curl "https://api.dmchamp.com/v1/subaccounts/credit-usage?apiKey=YOUR_AGENCY_API_KEY&from=2026-08-01&to=2026-08-31"
Query-parameter Vereist Beschrijving
from / to Ja ISO-datumbereik.
subAccountId Nee Weglaten voor een overzicht voor het hele bureau, één rij per subaccount. Voeg toe om over te schakelen naar de detailmodus: het overzicht van dat subaccount plus de onbewerkte, gepagineerde gebruiksrecords.
limitCount Nee Alleen detailmodus. Standaard 500, maximaal 2000.
startAfterTimestamp Nee Alleen detailmodus — paginering-cursor.
{
  "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
  }
}

Geef subAccountId door en hetzelfde antwoord bevat ook records: individuele kosten met amount, reason, campaignName, contactName en timestamp. Een klant die uitgeeft via zijn eigen BYOK-sleutel in plaats van via uw tegoeden, heeft geen kosten/token-cijfers (costsRedacted: true) — dat is telemetrie over platformkosten, niet iets om te tonen aan een wederverkoper.

Campagnestatus

curl "https://api.dmchamp.com/v1/subaccounts/campaign-status?apiKey=YOUR_AGENCY_API_KEY&pageSize=20"
Query-parameter Vereist Beschrijving
pageSize Nee Sub-accounts per pagina. Standaard 10, maximaal 50.
lastDocumentId Nee Paginering-cursor.
searchQuery Nee Filteren op sub-accountnaam of e-mailadres.
{
  "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
  }
}

Elke rij bevat ook de AI Agent-aantallen van de klant (totalAgents, activeAgents, pausedAgents, draftAgents), en het hoogste niveau voegt totalActiveAgents en totalPausedAgents toe voor de pagina. De campagnevelden hebben alleen betrekking op klassieke campagnes. hasIssues / issueDetails markeren subaccounts die de moeite waard zijn om te bekijken. Bij een account met agents zijn deze afkomstig van de gereedheidsscore van de ingeschakelde agents (bijvoorbeeld "WhatsApp Web is disconnected" of "Agent \"Front desk\": Routed on a channel that is not connected"); uitgeschakelde agents worden nooit gemarkeerd. Bij een account zonder agents markeren ze klassieke campagnes, zoals een gepauzeerde campagne. Gebruik dit om een dashboard voor gezondheidscontroles op te bouwen voor het gehele klantenbestand, in plaats van elke klant te openen om te zien welke agents zijn uitgeschakeld.

Zie GET /analytics/agency-rollup in de Analytics API-handleiding voor tijdreeksberichten en kredietactiviteit voor elke klant (een reeks die klaar is voor grafieken in plaats van een momentopname).


Een klantaccount verzenden dat al is ingesteld

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

Een snapshot is een herbruikbaar sjabloon: een of meer AI-agents plus hun kennisbank, tools en media, vastgelegd vanuit je eigen account. Twee eindpunten voegen dit toe aan je provisioning-flow.

Automatisch — elke nieuwe klant krijgt het standaard mee. Markeer een snapshot één keer als je standaard en elk account dat je vanaf dat moment aanmaakt, wordt geleverd met dit sjabloon geïnstalleerd. Dit geldt voor accounts die zijn aangemaakt via POST /v1/subaccounts, accounts die je in het dashboard aanmaakt en accounts die automatisch worden aangemaakt wanneer een klant betaalt via je betaallink.

Zoek eerst het id van de snapshot:

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

Stel het vervolgens in als de standaard:

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" }'

Dat is de volledige integratie. Stuur {"snapshot_id": null} om het weer uit te schakelen. Je kunt hetzelfde doen vanuit het dashboard door op de ster op de pagina Snapshots te klikken.

Om uit te lezen wat er momenteel is gemarkeerd (bijvoorbeeld voordat een provisioning-script beslist of er een moet worden ingesteld), retourneert GET /v1/snapshots/default { "success": true, "data": { "default_snapshot_id": "SNAPSHOT_ID" } } — null wanneer er niets is gemarkeerd. GET /v1/snapshots (gebruikt om de bovenstaande id te vinden) retourneert dezelfde default_snapshot_id naast de volledige snapshots-array, dus de meeste integraties hebben slechts die ene aanroep nodig. De velden van het volledige snapshot-object staan in de Snapshots-handleiding.

Op aanvraag — installeren in één account. Handig voor het onboarden van een bestaande klant, of om een klant later een tweede sjabloon te geven.

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" }'

Laat sub_account_id weg en het wordt in plaats daarvan in je eigen agency-account geïnstalleerd. Net als bij de /subaccounts-eindpunten, benoemen deze het doelaccount in het pad of de body in plaats van via de omgevingsparameter sub_account_id.

Goed om te weten voordat je hiermee aan de slag gaat:

  • Geïnstalleerde agents starten gepauzeerd. Verbind eerst de kanalen van de klant en activeer daarna de agent. Dit geldt voor zowel het automatische als het on-demand pad.
  • Provisioning mislukt nooit door een snapshot. Als de installatie niet kan worden voltooid, wordt het klantaccount nog steeds aangemaakt en is het bruikbaar — het komt alleen leeg aan en je kunt de snapshot achteraf toepassen.
  • Kanalen, agenda’s en OAuth-verbindingen worden nooit gekopieerd. Elk account verbindt zijn eigen kanalen. Tools die een eenvoudige API-sleutel gebruiken, blijven direct werken.
  • Twee keer toepassen creëert een tweede kopie. Er wordt niets overschreven.

Bouw de template zelf via de API

POST /v1/snapshots · agents, aangepaste functies en media via de API

Het bovenstaande gedeelte distribueert een snapshot die iemand in het dashboard heeft gebouwd. Het authoring-gedeelte is ook beschikbaar, zodat de hele cyclus — de master-setup één keer samenstellen, vastleggen en aan elke klant overhandigen — vanuit code kan worden uitgevoerd.

De onderdelen, in de volgorde waarin een provisioning-script ze gebruikt:

  1. Maak uw aangepaste functies. POST /v1/custom-functions maakt er een aan; GET /v1/custom-functions geeft een overzicht van wat u heeft, en GET, PUT en DELETE op /v1/custom-functions/{customFunctionId} lezen, updaten en verwijderen er een. POST /v1/custom-functions/test voert een dry-run uit van een definitie voordat u deze opslaat.
  2. Maak en vorm de agent. POST /v1/agents maakt deze aan, PUT /v1/agents/{agentId} update deze, en PATCH /v1/agents/{agentId}/active met { "active": false } houdt deze gepauzeerd terwijl u werkt (dezelfde aanroep met true zet deze live). GET /v1/agents geeft een overzicht van de agents.
  3. Geef de agent zijn vaardigheden. POST /v1/agents/{agentId}/custom-functions met { "custom_function_id": "..." } koppelt een functie aan de agent; de bijbehorende DELETE /v1/agents/{agentId}/custom-functions/{customFunctionId} ontkoppelt deze.
  4. Vul de mediabibliotheek. POST /v1/agents/{agentId}/media-library uploadt een item (JSON met base64Data, mimeType, title, description); GET geeft een overzicht van de items van de agent, en PATCH/DELETE op /{itemId} updaten of verwijderen er een.
  5. Leg het vast als een snapshot.
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
  }'

Vanaf daar geldt het vorige gedeelte: markeer het als de standaard zodat elke nieuwe klant ermee wordt aangemaakt, of pas het op aanvraag toe. Beheerfuncties zijn ook beschikbaar: PATCH /v1/snapshots/{snapshotId} met { "name": "..." } hernoemt er een, DELETE /v1/snapshots/{snapshotId} verwijdert er een (en haalt de markering als standaard weg indien van toepassing), en GET /v1/snapshots/apply-targets geeft een overzicht van elk account waarin u kunt installeren.

De endpoints voor agents, aangepaste functies en media accepteren allemaal sub_account_id, dus dezelfde aanroepen kunnen ook een agent direct binnen het account van één klant onderhouden. Snapshot-aanroepen werken altijd op uw agency-account — de template blijft bij u. Volledige request- en response-schema’s voor al deze onderdelen staan in de API-referentie.


Beheer uw prijscategorieën via de API

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

De abonnementen die u verkoopt in SaaS-modus → Prijscategorieën kunnen vanuit code worden gelezen en gewijzigd, zodat uw eigen beheerpaneel of provisioning-script een abonnement kan toevoegen, een prijs kan aanpassen of een betaallink kan verstrekken zonder dat iemand het dashboard hoeft te openen. Authenticeer met uw bureau-API-sleutel zoals bij elke andere aanroep op deze pagina; deze endpoints zijn op bureau-niveau, dus ze vereisen geen sub_account_id. Elke schrijfactie voert dezelfde validatie en dezelfde Stripe-product-en-prijs-synchronisatie uit als het opslaan in het dashboard, dus een abonnement dat hier wordt aangemaakt is niet te onderscheiden van een abonnement dat u handmatig hebt ingesteld.

Uw categorieën weergeven

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

Antwoord

{
  "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
  }
}

Elke categorie wordt geretourneerd met zijn tierIndex — zijn positie in uw lijst met abonnementen, wat de manier is waarop de andere drie aanroepen ernaar verwijzen — en een kant-en-klare checkout_url, dezelfde link die het tabblad Betalingen u geeft, die al wijst naar het white label-domein waarop dat abonnement wordt verkocht.

Een categorie toevoegen

De body is één categorie-object; het wordt toegevoegd aan het einde van uw lijst.

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"]
  }'

Het antwoord bevat de aangemaakte categorie, inclusief de tierIndex waarop deze is terechtgekomen en de checkout_url ervan.

Een categorie bewerken

Stuur alleen de velden die u wilt wijzigen; al het andere in het abonnement blijft zoals het was.

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 }'

Een veld dat de API niet herkent, wordt geweigerd in plaats van genegeerd, en de foutmelding benoemt het — zodat een typefout nooit stilletjes een instelling kan schrijven die er live uitziet maar niets doet. Het wijzigen van de prijs, de credits, de valuta of de factureringsfrequentie creëert een nieuwe prijs in uw Stripe; klanten die al geabonneerd zijn, blijven op het abonnement waarvoor ze zich hebben aangemeld.

Een categorie verwijderen

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

Dezelfde regel als in het dashboard: een abonnement met actieve abonnees kan niet worden verwijderd. Het verzoek wordt geweigerd, met de melding hoeveel abonnees er op dat abonnement zitten — annuleer of migreer ze eerst. Een succesvolle verwijdering reageert met uw resterende categorieën, die al opnieuw zijn genummerd.

De velden van een categorie

Veld Wat het is
label / description De naam van het abonnement en de optionele regel die op uw afrekenpagina wordt getoond.
credits Credits die de klant per maand krijgt bij een maandelijks of jaarlijks abonnement, en per factuurperiode bij een wekelijks abonnement. Een geheel getal van minimaal 1, of 0 bij een abonnement waarvan de features byok bevatten (de klant gebruikt AI op hun eigen API-sleutel, dus het abonnement verleent geen credits en verbruikt niets uit uw pool).
price_cents Prijs per factuurinterval, in de kleinste valuta-eenheid (2900 = $29.00). Bij een jaarabonnement is dit de prijs voor het hele jaar.
currency ISO-code in kleine letters — usd, eur, gbp enzovoort.
billing_interval / billing_interval_count month (de standaard), year, of week met een aantal van 1–52 voor “elke N weken”.
trial_days Duur van de gratis proefperiode, 0 tot 90. 0 (of het weglaten ervan) betekent geen proefperiode.
trial_credits Credits waarmee de klant de proefperiode start. Standaard is dit het credits van het abonnement.
trial_card_required Met false kan de klant de proefperiode starten zonder een kaart in te voeren. Standaard is true.
trial_hard_expiry true geeft ongebruikte proef-credits terug aan uw pool en vergrendelt het account van de klant wanneer een proefperiode eindigt zonder upgrade. Standaard is false — zie Hard expiry after trial.
rollover_cap_months Maanden aan tegoed die klanten met dit abonnement mogen meenemen tussen verlengingen — een getal van 0 tot 120, breuken toegestaan. 0 neemt niets mee; null (de standaard) betekent geen limiet. Zie Capping what rolls over.
rollover_expiry_days Dagen waarna ongebruikte credits bij de volgende verlenging komen te vervallen — een geheel getal van 1 tot 3650. null (de standaard) betekent dat ze nooit verlopen.
features / feature_settings Wat klanten met dit abonnement krijgen — dezelfde functie-ID’s als Choose which channel types a client can connect.
team_seats_limit Team-seats die het abonnement verleent: een exact aantal, 0 voor geen, -1 voor onbeperkt.
allowed_ai_tiers AI-modellen die klanten met het abonnement mogen gebruiken, gekozen uit standard (Pro), economy, max, mini. Toegepast wanneer een klant zich abonneert en bij elke verlenging. null of [] (de standaard) betekent dat het abonnement geen modellen beheert. Een handmatige vergrendeling op een sub-account met PUT /v1/subaccounts/:uid/ai-tiers wordt nooit door het abonnement overschreven.
white_label_config Op welk van uw white label-domeinen het abonnement wordt verkocht.

De proefperiode-velden zijn alleen relevant voor een abonnement met een proefperiode: sla een niveau op met trial_days: 0 en ze worden verwijderd. De Stripe-product- en prijs-ID’s van het abonnement worden voor u beheerd en kunnen niet handmatig worden ingesteld.

Drie dingen om goed te krijgen:

  • Tier-indexen zijn posities, geen permanente id’s. Het verwijderen van een abonnement schuift elk volgend abonnement één plek op. Haal de lijst daarom opnieuw op na elke wijziging — en kopieer de checkout-links die je hebt gepubliceerd opnieuw, precies zoals je zou doen na het verwijderen van een abonnement in het dashboard.
  • SaaS-modus moet eerst worden ingesteld. Deze endpoints vereisen een agency-account met white labeling en een reeds opgeslagen Stripe-sleutel; zonder deze is er geen Stripe-account waarop het product en de prijs van het abonnement kunnen worden geplaatst.
  • Twintig abonnementen is het maximum, hetzelfde als in het dashboard. Het max_tiers-veld in het lijstantwoord geeft je de huidige limiet aan.

Volledige schema’s voor aanvragen en antwoorden staan in de API-referentie, onder Agency.


Stel uw prijs per credit in via de API

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

De prijs die klanten betalen voor ad-hoc opwaarderingen (SaaS-modus → Prijs per credit) kan ook vanuit de code worden gelezen en gewijzigd. Dit is gebouwd voor situaties waarin de prijs automatisch moet worden aangepast: een bureau dat credits verkoopt in de ene valuta maar factureert in een andere, kan een geplande taak de prijs laten herzien naarmate de wisselkoers verandert, in plaats van dat iemand deze elke week handmatig moet aanpassen.

De huidige prijs lezen

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

Antwoord

{
  "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 is de laagste prijs die het platform toestaat in die valuta, zodat een taak een nieuwe prijs kan controleren voordat deze wordt verzonden. Alle drie de waarden zijn null totdat er een prijs is ingesteld.

Wijzigen

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" }'

Verzend alleen wat u wilt wijzigen. price_per_credit_cents is de prijs in de kleinste valuta-eenheid (130 = R$1,30); currency is een ISO-code in kleine letters; note is een optionele regel van maximaal 200 tekens die direct onder de prijs per credit op de factuurpagina van de klant wordt getoond — handig voor een referentieprijs in een andere valuta, zoals “USD 0,25 per credit tegen onze referentiekoers”. Stuur "note": "" om deze te verwijderen. Het antwoord heeft dezelfde vorm als het lezen hierboven, zodat een taak kan vergelijken en het schrijven kan overslaan wanneer er niets is veranderd.

Dezelfde regels gelden als in het dashboard: de prijs mag niet onder het platformminimum voor die valuta komen en het account moet white-labeling hebben. In tegenstelling tot de eindpunten voor prijscategorieën is er geen Stripe-sleutel vereist om deze waarde te lezen of te wijzigen.

Geef een taak een sleutel die niets anders kan

Het invoeren van uw volledige agentschapsleutel in een planner geeft meer toegang dan nodig is voor een prijswijziging. Maak in plaats daarvan een scoped key aan die beperkt is tot het gedeelte Agency Credit Price: die sleutel kan alleen de prijs per credit lezen en wijzigen en niets anders — deze heeft geen toegang tot subaccounts, abonnementen, credits of uw Stripe-koppeling.

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"] } }'

Het antwoord bevat de nieuwe sleutel in api_key één keer — deze wordt daarna nooit meer getoond, dus sla deze direct op. Stel "read_only": true in voor een sleutel die alleen de prijs hoeft te lezen, en voeg "expires_at" (een ISO-datum) toe als u wilt dat deze automatisch verloopt. Alleen de sleutel van de accounteigenaar kan scoped keys aanmaken; bekijk of trek ze in met GET /v1/api-keys en DELETE /v1/api-keys/{id}.


Laat een sub-account uw prijzen lezen

GET /v1/subaccounts/agency-pricing

Elk ander eindpunt op deze pagina wordt aangeroepen met uw agency-sleutel, waarbij optioneel een klant wordt getarget via sub_account_id. Dit is het tegenovergestelde: het wordt aangeroepen met de eigen API-sleutel van het sub-account, zonder sub_account_id, zodat de eigen opwaardeerpagina van een klant (of een integratie die u voor hen bouwt) kan weergeven wat u hen in rekening brengt zonder ooit uw agency-account te zien.

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

Antwoord

{
  "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"
  }
}

Dit weerspiegelt precies wat GET /v1/agency/pricing-tiers en GET /v1/agency/credit-price voor u als agency retourneren, minus alles wat de klant niet hoeft te zien (Stripe-ids, max_tiers, enzovoort). Het werkt alleen voor een account dat daadwerkelijk een sub-account is met een gekoppeld agency — het aanroepen hiervan vanuit uw eigen agency-account resulteert in een toestemmingsfout.


Om rekening mee te houden

  • Gebruik uw agency-sleutel. Authenticeer elke aanroep met de API-sleutel van uw agency-account — niet die van het sub-account. De sub_account_id-parameter is wat de actie omleidt.
  • Credits komen van het sub-account. Aankopen en terugkerende kosten worden in mindering gebracht op het kredietsaldo van het betreffende sub-account, niet op dat van u.
  • Een 404 betekent “niet uw sub-account.” Controleer het id dubbel en zorg dat het account er een is die u beheert.
  • De parameter is overal waar deze wordt geaccepteerd optioneel. Laat deze weg en hetzelfde eindpunt werkt op uw agency-account, zodat u één integratie voor beide kunt hergebruiken.

Gerelateerd

  • API-toegang — authenticatie, basis-URL, fouten, snelheidslimieten.
  • Sub-accounts — lijst en beheer de accounts waarop je je kunt richten.
  • Automatisch opwaarderen van sub-accounts — ken credits toe aan een sub-account via webhook + API.
  • AI Agents API: maak en configureer AI Agents.
  • Campagnes API: de verouderde klassieke campagnes-resource, inclusief de volledige veldreferentie.
  • Kanaalverbinding API — verbind de kanalen van een klant.
  • Toegangspunten API: bepaal welke Agent een nieuw gesprek oppakt.
  • Analytics API-gids (in de API-sectie) — de rollup van bureau-sub-accounts en elk ander rapportage-eindpunt.
  • Snapshots — wat een snapshot vastlegt en hoe je er een bouwt in het dashboard.