DM Champ Docs

API para Agências

Como agência, pode utilizar a mesma API REST que os seus clientes utilizam, mas direcionar pedidos individuais para uma das suas subcontas geridas em vez da sua própria conta. Isto permite-lhe criar ferramentas que integram um cliente de ponta a ponta — criando as suas campanhas, treinando a sua IA numa base de conhecimento, importando os seus contactos, ligando os seus canais de mensagens e comprando números de telefone — tudo isto sem ter de iniciar sessão manualmente em cada subconta.

Esta página abrange apenas o comportamento específico da agência: como agir em nome de uma subconta com o parâmetro sub_account_id. Para as noções básicas (geração de chaves, autenticação, URL base, formato de erro, limites de taxa), comece pelo guia de Acesso à API. Tudo o que lá consta aplica-se também aqui — autentica-se com a chave de API da sua conta de agência.

Nota: Esta página é técnica. Se não for um programador, partilhe-a com a pessoa responsável pela criação da sua integração.


Como funciona o “agir em nome de”

Por predefinição, cada pedido de API atua sobre a conta que detém a chave de API — a sua conta de agência. Para atuar sobre uma conta de cliente gerida, adicione o parâmetro opcional sub_account_id ao pedido, definido com o ID da conta desse cliente.

  • Omitir sub_account_id → o pedido atua sobre a sua própria conta de agência.
  • Incluir sub_account_id → o pedido atua sobre essa subconta, mas apenas após a plataforma confirmar que a subconta lhe pertence realmente.

Autentica-se sempre com a chave de API da sua conta de agência. Nunca precisa da chave da própria subconta e nunca gere as credenciais da subconta.

Onde o colocar

  • Endpoints GET / DELETE → passe-o como um parâmetro de consulta: ?sub_account_id=THE_SUB_ACCOUNT_ID (juntamente com o seu apiKey, se autenticar por consulta).
  • Endpoints POST / PUT / PATCH → inclua-o no corpo do pedido JSON como "sub_account_id": "THE_SUB_ACCOUNT_ID".
  • Assistentes de IA → nada a configurar. O servidor MCP transporta a mesma definição nas suas ferramentas de leitura, pelo que uma ligação com a sua chave de agência pode reportar sobre todos os clientes: basta nomear o cliente no seu pedido (“quantos contactos tem o Bella’s Bistro?”). As ações de escrita também estão disponíveis: cada endpoint que aceita sub_account_id é exposto como uma ferramenta, para que possa criar, alterar e enviar em nome de um cliente a partir da mesma ligação.

Encontrar o ID de uma subconta

O sub_account_id é o identificador único da conta de cliente. Pode obter a lista das suas subcontas e os respetivos identificadores através dos endpoints da API SubAccounts (consulte o guia Sub-Accounts) ou a partir da página Sub Accounts na barra lateral.


A titularidade é sempre verificada

Quando passa um sub_account_id, a plataforma verifica se a conta é uma subconta real e se pertence à sua agência. Só então o pedido é processado.

Se o ID for desconhecido, não for uma subconta ou pertencer a uma agência diferente, o pedido falha com uma resposta 404:

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

Porquê 404 e não 403? Uma resposta “proibido” (forbidden) diria a um estranho que o id existe, mas não lhe pertence. Devolver o mesmo 404 para “não existe” e “não é seu” significa que o endpoint não pode ser usado para descobrir que ids de conta pertencem a outras agências. Trate um 404 aqui como “esta não é uma subconta que gere”.


Onde o sub_account_id é suportado

sub_account_id é aceite em praticamente todos os endpoints de recursos — qualquer chamada que crie, leia, atualize ou elimine os dados de uma conta. Na prática, pode provisionar e executar toda a configuração de uma subconta com a sua chave de agência:

  • Configuração de IA — campanhas, agentes, FAQs, fontes da base de conhecimento (rastreio de websites e carregamento de documentos), grupos da base de conhecimento, transmissões, funções personalizadas, servidores MCP
  • Contactos e CRM — contactos (incluindo importação), listas, etiquetas, tarefas, negócios, marcações, eventos
  • Canais e números — ligar WhatsApp / WhatsApp Web / Telegram / Instagram e Messenger / LINE, pesquisar / comprar / gerir números de telefone, modelos de WhatsApp, encaminhamento de canais
  • Mensagens e conteúdo — enviar mensagens, sessões de chat, exportações de chat, resumos diários
  • Definições e integrações — webhooks, configuração do widget de chat, configuração de white-label, SMS BYOK e outras definições de conta, análises

Em cada um destes, o parâmetro é opcional — se o omitir, a chamada atua na sua própria conta de agência, pelo que uma única integração serve para ambos. Os créditos e a utilização provêm sempre da conta que definir como alvo: as cobranças relativas a campanhas, mensagens, etiquetas e números de uma subconta são deduzidas ao saldo da subconta.

Onde NÃO se aplica

Alguns endpoints são de nível de agência ou de autoendereçamento e ignoram o sub_account_id:

  • Gestão das próprias subcontas — os endpoints de SubAccounts (criar / listar / atualizar uma subconta) e o endpoint de limite de gastos BYOK já nomeiam a subconta no seu próprio caminho de URL. Os endpoints de preços e políticas e os endpoints de monitorização de chat seguem o mesmo padrão.
  • Copiar um Agente entre contasPOST /v1/subaccounts/agents/copy nomeia ambas as contas, assumindo o destino como targetUserId. Veja o exemplo prático abaixo. (O POST /v1/subaccounts/campaigns/copy mais antigo funciona da mesma forma, mas está descontinuado juntamente com o resto da API de Campanhas.)
  • Ajustar créditos e os dois rollups de toda a agênciaPOST /v1/subaccounts/credits identifica a subconta através de email; GET /v1/subaccounts/credit-usage e GET /v1/subaccounts/campaign-status reportam sobre todas as subcontas de uma só vez, por isso não existe uma única conta a visar.
  • A conta da sua própria agência — A gestão de chaves de API, relatórios de utilização da agência, gestão de equipas e os seus níveis de preços atuam sempre sobre a conta da sua agência.
  • Webhooks de mensagens recebidas — os endpoints para os quais sistemas externos enviam dados estão ligados à conta cujas credenciais os configuraram, pelo que não há nada a redirecionar.

A lista sempre atualizada e legível por máquina dos parâmetros que cada endpoint aceita encontra-se na referência da API do seu dashboard (Settings → Integrations → API Key) e na especificação OpenAPI em GET /v1/docs/openapi.yaml. Lançamos alterações à API frequentemente — considere-as como a fonte de verdade.

Página de definições da Chave de API com chave mascarada e controlo de Regenerar

Definições → Integrações → Chave de API — a chave da sua agência encontra-se aqui, juntamente com a ligação para a referência completa da API.


Exemplo prático: ligar Instagram e Messenger para uma subconta

Ligar o Instagram e o Messenger é um fluxo baseado no navegador. Inicia-o com a API, entrega o URL de consentimento devolvido ao cliente (ou abre-o por ele), aguarda que este autorize no seu navegador e, em seguida, escolhe a página a ligar — tudo isto enquanto aponta para a sua subconta com sub_account_id.

Passo 1 — Iniciar a ligação

Chame o endpoint de ligação com o sub_account_id do cliente no corpo (body). Não são enviadas credenciais aqui; a plataforma devolve um URL de consentimento que o cliente deve abrir num navegador, além de um token de correlação único.

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

Resposta:

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

Envie o cliente para o oauth_url num navegador para autorizar. O state_token correlaciona esta tentativa e é um segredo de curta duração — não o registe (log). A tentativa expira em expires_at; se caducar, comece de novo.

Passo 2 — Consultar (polling) até as páginas carregarem

Após o cliente autorizar, verifique o estado do endpoint (com o mesmo sub_account_id, desta vez como um parâmetro de consulta) até que as páginas conectáveis apareçam.

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

Resposta:

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

O campo status progride através de pendingtoken_receivedpages_loadedconnected. Aguarde por pages_loaded antes de selecionar uma página. Podem também surgir dois estados de erro terminal em vez de progredir: failed e expired (o cliente recusou o consentimento, ou a janela de ~30 minutos do token de estado expirou) — um campo reason é incluído quando qualquer um destes ocorre. Pare a consulta e reinicie no Passo 1 se vir um destes; não aguarde por pending indefinidamente. Os tokens de acesso à página nunca são devolvidos.

Passo 3 — Selecionar a página a conectar

Escolha um dos IDs de página do Passo 2 e selecione-o. Selecionar uma página conecta tanto o Instagram como o Messenger para essa página. Inclua sub_account_id no corpo novamente.

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

Resposta:

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

É tudo — o Instagram e o Messenger estão agora conectados na subconta do cliente. Apenas forneceu o page_id; a credencial subjacente é resolvida no servidor e nunca passa pela sua integração.


Exemplo prático: comprar um número para uma subconta

A compra de um número funciona da mesma forma: pesquise com sub_account_id na consulta e, em seguida, compre com o mesmo no corpo. Os créditos são deduzidos do saldo da subconta e o número é provisionado na subconta.

Pesquisa (cURL):

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

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

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

Resposta:

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

O número é provisionado no estado PURCHASED e o registo do remetente do WhatsApp continua em segundo plano. Consulte GET /v1/phone-numbers/{phoneNumber}/status?sub_account_id=abc123def456 até que o estado atinja ONLINE antes de enviar.


Exemplo prático: enviar um Agente modelo para cada novo cliente

O padrão habitual das agências é manter um Agente principal na conta da agência, configurado da forma que pretende que cada cliente comece, e criar uma cópia do mesmo em cada nova subconta no momento do aprovisionamento. São três chamadas e nada precisa de ser repetido posteriormente: a cópia mantém as suas definições até que as altere.

Passo 1 — Copiar o Agente

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

A resposta contém o ID do novo Agente em data.agent_id. As FAQs, a base de conhecimento e a biblioteca de multimédia são incluídas; os modelos de WhatsApp, publicações sociais ligadas e contactos da conta de origem, deliberadamente, não o são. Lista completa de campos na API de Agentes de IA.

Note que este endpoint utiliza targetUserId em vez de sub_account_id — ele próprio nomeia ambas as contas. As duas chamadas abaixo utilizam o parâmetro sub_account_id normal.

Passo 2 — Ativar

A cópia chega sempre em pausa, pelo que não pode enviar mensagens a ninguém até que o autorize. Este é também o momento para definir o nível de IA em que pretende colocar o cliente; este permanece lá, pelo que não há necessidade de o voltar a aplicar de forma agendada.

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

Para impedir que o cliente altere o nível posteriormente, bloqueie os níveis permitidos na subconta em vez de reenviar o valor.

Passo 3 — Direcionar os canais do cliente para a mesma

A cópia também chega sem encaminhamento, pelo que nada lhe chega até que o torne o responsável pelas respostas nos canais que o cliente ligou. Uma chamada por 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" }'

A partir daqui, uma primeira mensagem de um contacto desconhecido nesse canal é captada automaticamente pelo Agente copiado. Veja Apontar um canal para um Agente para os outros canais e encaminhamento por número.

Defina o fuso horário do cliente ao criar a subconta. Passe time_zone_id em POST /v1/subaccounts. As horas de atividade da campanha são avaliadas no fuso horário da própria subconta, pelo que um cliente criado sem um terá o seu agendamento lido em relação ao UTC — o que altera silenciosamente o período em que o assistente tem permissão para responder.


Ignorar o assistente de configuração para um cliente que configura pessoalmente

POST /v1/subaccounts

Por predefinição, a primeira vez que o proprietário de uma nova subconta inicia sessão, é guiado através do Assistente de Configuração. Para clientes com serviço completo — onde cria a campanha e liga os canais antes de o cliente iniciar sessão — passe guided_onboarding: false ao criar a conta. Estes serão direcionados para o painel de controlo e a entrada Assistente de Configuração será ocultada da sua barra lateral.

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

Omita o campo (ou envie true) e o assistente comportar-se-á exatamente como sempre fez, pelo que as integrações existentes não necessitam de alterações. Para devolver o assistente a um cliente mais tarde, volte a mostrar o item guided_onboarding com PUT /v1/subaccounts/{subAccountUid}/menu-visibility (abaixo) — a visibilidade do menu controla se o assistente é acessível, guided_onboarding controla apenas o redirecionamento no primeiro início de sessão.


Desativar Tarefas, Resumos Diários ou a Biblioteca de Multimédia para um cliente

POST /v1/subaccounts

Estas três funcionalidades estão ativas para todos os novos clientes, a menos que indique o contrário, e comportam-se de forma diferente de todas as outras funcionalidades neste guia: são de opt-out (desativação voluntária), não de opt-in. Deixá-las de fora de features não é suficiente por si só, porque a lista features de uma integração mais antiga simplesmente nunca as mencionou — não conseguimos distinguir entre “a agência desativou isto” e “esta lista foi escrita antes de a opção existir”.

Portanto, declare-o explicitamente com 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": "client@example.com",
    "first_name": "Alex",
    "last_name": "Client",
    "business_name": "Client Co",
    "feature_settings": {
      "tasks": false,
      "daily_summaries": false,
      "ai_media_library": true
    }
  }'

Cada chave é opcional; tudo o que deixar de fora permanece ativo. Com tasks: false, a IA deixa de criar tarefas para esse cliente e não são enviados e-mails de “Nova Tarefa Criada”; com daily_summaries: false, o resumo noturno nunca é gerado nem enviado por e-mail.

feature_settings é a única forma de desativar estas três funcionalidades no momento da criação. Deixá-las de fora de features não tem qualquer efeito por si só, independentemente do aspeto do resto da sua lista — isto é intencional, para que uma integração mais antiga não perca as três silenciosamente.

Para alterar qualquer uma destas definições posteriormente, envie a lista features completa para PUT /v1/subaccounts/{subAccountUid}/features — aí, a presença na lista ativa uma funcionalidade e a ausência desativa-a.


Inicie sessão automaticamente nos seus clientes na respetiva subconta (SSO)

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

Uma única chamada com a sua chave de API de agência devolve um URL pronto a abrir que inicia a sessão do cliente diretamente na sua própria subconta — sem ecrã de início de sessão, sem passo de palavra-passe, nada para construir. Abra-o num novo separador, num redirecionamento ou numa iframe dentro do seu próprio produto.

Campo Obrigatório Descrição
redirect Não Página na aplicação onde pretende que o cliente termine, p. ex., "/chats" ou "/agents". Devolvido como deep_link_url na resposta.
app_base_url Não Anfitrião do dashboard para a ligação. Predefinição para o seu domínio de aplicação white-label (ou o domínio da plataforma, caso não tenha nenhum). Tem de ser 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" }'

Resposta

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

Como utilizar corretamente:

  • Um salto. Abrir url autentica o cliente e leva-o diretamente para a página redirect do painel de controlo — sem ecrã de início de sessão, sem página intermédia. deep_link_url indica o mesmo destino, para integradores que preferem navegar numa moldura explicitamente após o início de sessão; uma vez que a sessão exista, qualquer caminho do painel de controlo funciona nesse contexto de navegador.
  • Criação a pedido, abertura imediata. A ligação contém uma credencial de início de sessão e expira após cerca de uma hora. Solicite-a do lado do servidor no momento em que o cliente clica e nunca a armazene ou envie por e-mail.
  • O token de início de sessão viaja no fragmento do URL (#…), que os navegadores nunca enviam para os servidores, e é removido da barra de endereços no momento em que é consumido.
  • Apenas as suas próprias subcontas. O endpoint recusa qualquer conta que a sua agência não possua.
  • Uma ligação expirada apresenta um erro claro com um caminho de tentativa — crie uma nova.

Ocultar itens de navegação numa subconta

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

Controla os itens da barra lateral e das definições que uma subconta vê — útil quando incorpora o painel de controlo e pretende apenas as superfícies que o seu produto ainda não cobre. Tudo o que não estiver listado permanece visível; envie null como o valor menuVisibility completo para repor tudo como visível. Ocultar um item oculta a entrada do menu — combine-o com as funcionalidades que concede à subconta para um controlo rigoroso.

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, "Campaigns": false, "Automations": false },
      "settings_nav": { "team": false }
    }
  }'

Resposta

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

side_nav aceita estas 13 chaves, que correspondem aos nomes dos itens da barra lateral: Dashboard, DailySummaries, Chats, Contacts, Deals, Tasks, Automations, Campaigns, Appointments, Settings, Help, CreditsCounter (o saldo de crédito apresentado na barra lateral) e guided_onboarding (o Assistente de Configuração). Três chaves adicionais — AiInsights, Sub Accounts e Agency Reselling — são aceites, mas não realizam qualquer ação: aplicavam-se apenas ao painel clássico descontinuado, pelo que a sua definição não tem qualquer efeito nas suas subcontas. As chaves em falta significam visível; quando inicia sessão na subconta, os itens ocultos são apresentados temporariamente para que possa sempre reverter as alterações.

Ocultar uma página do menu nunca concede acesso à mesma. Automations necessita que a funcionalidade automations esteja concedida na subconta — se definir a chave como true sem a ter, a página continuará a não aparecer. Tasks e DailySummaries funcionam de forma inversa: estão ativas para todos os clientes, a menos que as desative (consulte Desativar Tarefas, Resumos Diários ou a Biblioteca de Multimédia para um cliente).


Escolha os tipos de canal aos quais um cliente pode ligar-se

PUT /v1/subaccounts/{subAccountUid}/features

Os interruptores de Tipos de Canal que vê num nível de plano são IDs de funcionalidade comuns, pelo que pode defini-los por cliente a partir da API em vez do painel de controlo. Este é um dos endpoints que nomeia a subconta no seu próprio URL, pelo que não requer sub_account_id.

ID da Funcionalidade Canal
channel_chat_widget Widget de Chat do Website
channel_whatsapp_api API do WhatsApp Business
channel_whatsapp_web WhatsApp Web (número ligado por QR)
channel_instagram Instagram
channel_messenger Facebook Messenger
channel_telegram Telegram
channel_line LINE
channel_viber Viber
channel_email Caixa de correio eletrónico
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"
    ]
  }'

Três aspetos a ter em conta:

  • A chamada substitui toda a lista de funcionalidades. Envie todas as funcionalidades que o cliente deve manter, não apenas aquelas que está a alterar. Os mesmos IDs funcionam como features em POST /v1/subaccounts quando cria a conta.
  • Os tipos de canal e o número de canais são restrições separadas, e ambas aplicam-se. channels_1 / channels_3 / channels_unlimited controlam quantas ligações; os IDs channel_* controlam quais os tipos. O exemplo acima significa “até 3 ligações, e apenas Widget de Chat, WhatsApp Web ou Instagram”.
  • Não enviar nenhuns IDs channel_* significa que não há restrição de canal. Esse é o comportamento original, razão pela qual os clientes existentes não foram afetados quando isto foi lançado. Envie um ou mais e tudo o resto aparecerá como bloqueado na página de Canais do cliente com uma nota de atualização em vez de um botão Ligar. Os canais que o cliente já ligou continuam a funcionar.

Definir a lista de canais num nível de plano, para que todos os clientes que compram esse nível a herdem, é feito no painel de controlo nas definições do seu plano de agência. Este endpoint define-a numa subconta específica.


Defina um limite exato de membros da equipa para um cliente

PUT /v1/subaccounts/{subAccountUid}/limits

As funcionalidades team_seats_* oferecem apenas escalões predefinidos (3 / 5 / 10 / ilimitado). Para atribuir a um cliente um número exato de lugares na equipa — 2, 7, 15, qualquer número — defina usage_limits.team_seats_limit em alternativa. Esta definição prevalece sobre as predefinições e a plataforma aplica-a em cada convite, adição direta e aceitação de convite: assim que o limite é atingido, novos convites são recusados pelo servidor.

  • Um número inteiro positivo é o limite exato.
  • 0 significa que os membros da equipa não estão incluídos — o cliente não pode convidar ninguém.
  • -1 significa ilimitado.
  • null limpa o limite personalizado e reverte para a predefinição team_seats_* que estiver na lista de funcionalidades.

Reduzir o limite nunca remove membros da equipa existentes; apenas impede que novos sejam adicionados.

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

Também pode defini-lo no momento da criação: POST /v1/subaccounts aceita usage_limits.team_seats_limit com a mesma semântica. Para ler o valor atual, obtenha a subconta com GET /v1/subaccounts?email=... e verifique usage_limits.team_seats_limit (ausente/null = as predefinições decidem). O mesmo endpoint também atualiza credits, monthly_credits, roll_over_to_next_month, rollover_cap_months, rollover_expiry_days e byok_monthly_limit_usd — envie apenas as chaves que pretende alterar.

Como isto interage com os limites de lugares dos planos SaaS. Os seus planos SaaS podem ter a sua própria tolerância de lugares (definida no editor de planos — consulte Lugares de equipa num plano), que é aplicada automaticamente quando um cliente subscreve. Um limite que define através deste endpoint conta como uma concessão manual: a compra de um plano substitui-o pela tolerância de lugares do próprio plano (essa compra é uma escolha explícita de plano), mas as renovações mensais automáticas nunca substituem um limite manual — pelo que uma exceção pontual que conceda a um cliente sobrevive ao seu ciclo de faturação. Limpar o limite manual com null devolve o controlo do campo ao plano na sua próxima renovação.

Limite o que um cliente transporta entre renovações. Duas chaves usage_limits adicionais encontram-se junto a roll_over_to_next_month. Ambas são também aceites por POST /v1/subaccounts no momento da criação, e null limpa qualquer uma delas.

Chave O que faz
rollover_cap_months Meses de plafond que o cliente pode manter. Um número de 0 a 120, frações permitidas (0.5 = meio mês). Em cada renovação, o saldo não utilizado é reduzido para, no máximo, este número de vezes o plafond concedido nessa renovação, antes de os novos créditos serem adicionados; 0 não transporta nada.
rollover_expiry_days Um número inteiro de dias, de 1 a 3650. Os créditos deixados por utilizar durante esse período são removidos na primeira renovação após atingirem essa idade. O consumo é sempre deduzido dos créditos mais antigos primeiro, pelo que um cliente que gasta o seu plafond todos os meses nunca perde nenhum.

Se não forem definidos, ambos recorrem ao plano do cliente; um valor enviado aqui prevalece sobre o do plano. Apenas os créditos recorrentes (o plafond mensal e os créditos do plano) estão sujeitos a estes limites: os carregamentos, as recargas automáticas e as adições pontuais nunca são limitados nem expiram. Cada redução é registada no histórico de créditos do cliente como um Ajuste de Crédito de Limite de Rollover ou um Ajuste de Crédito de Créditos Expirados e nunca conta como utilização. Os equivalentes ao nível do plano são rollover_cap_months e rollover_expiry_days num escalão de preços — consulte Os campos num escalão e Limitar o que é transportado.


Definir preços e políticas de IA por cliente

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

Oito interruptores adicionais por cliente, juntamente com /limits, /features e /menu-visibility acima. Cada um utiliza o uid da subconta no URL (sem sub_account_id parâmetro de corpo/query — o destino já está nomeado no caminho) e tem o mesmo âmbito: a sua chave de agência, e a subconta deve pertencer à sua agência.

Que modelos de IA um cliente pode utilizar

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 } permite que o cliente adira (ou saia) do nível Max AI — a nossa infraestrutura ao preço de tabela da plataforma. Ativar isto para um cliente BYOK altera o seu custo de IA de “gratuito na minha própria chave” para “cobrado contra o meu conjunto de créditos”, pelo que é uma decisão deliberada por cliente em vez de uma predefinição para toda a agência.

Para restringir QUAIS os níveis que as campanhas e Agentes de um cliente podem escolher (em vez de apenas limitar o Max), utilize 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 é uma matriz retirada de standard, economy, max, mini — SUBSTITUI a lista de permissões do cliente. Envie null (ou []) para limpar a restrição e permitir que escolham qualquer nível. Isto é importante porque uma subconta que escolhe o seu próprio nível de IA gasta do seu conjunto de créditos, pelo que é a alavanca para definir quais os modelos que um cliente revendedor pode utilizar para aumentar a sua fatura.

Uma resposta de espera enquanto o cliente não tem créditos

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

Quando o saldo do cliente (ou o seu pool) está vazio, a IA não pode responder e o contacto não ouve nada. Com enabled: true, cada contacto que escreve durante a interrupção recebe message uma vez (máximo de 500 caracteres, enviado tal como está em todos os canais), e a IA responde a essas conversas de facto assim que os créditos regressarem. enabled: false mantém o texto guardado para mais tarde; enabled: false sem message remove a definição. O mesmo interruptor que Resposta de espera quando sem créditos no modal de Edição da subconta — consulte Uma resposta de espera enquanto um cliente não tem créditos.

O que um cliente paga por ação de IA e a margem de lucro da taxa de WhatsApp

Duas formas de definir a sua taxa para o cliente, da mais simples à mais granular:

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 é o preço em créditos que o saldo PRÓPRIO da subconta consome por ação de IA do modelo Max — a sua margem de lucro sobre o que o seu conjunto realmente paga. null limpa a substituição de volta para o preço de tabela da plataforma. A taxa deve ser, pelo menos, o custo de uma ação Max para o seu próprio conjunto (para que nunca possa cobrar a um cliente abaixo do seu custo) e não mais do que 10 créditos; um pedido fora desse intervalo é rejeitado com o valor mínimo calculado na mensagem de erro.

Para preços por tipo de ação em vez de uma taxa Max fixa, utilize 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 é uma FUSÃO no mapa existente do cliente — uma chave que não menciona é deixada como estava, e null repõe essa chave para o seu valor predefinido. As chaves reconhecidas:

Chave Preços
AI_MESSAGE Uma resposta de IA
AI_TOOL_USE Uma chamada de ferramenta de IA
EVALUATION_CALL Um passe de avaliação de chat
INTERRUPTION_HANDLING Lidar com uma interrupção a meio da resposta
CONTACT_TAG Uma etiqueta de contacto atribuída por IA
CHAT_SUMMARY Um resumo de chat
wa_carrier_multiplier Um multiplicador de margem aplicado a cada taxa de WhatsApp não relacionada com IA que o cliente paga: aluguer mensal de número, taxas de entrega em via gerida e custos de passagem de modelos Meta/Twilio.

As taxas por ação devem ser um número superior a 0 e até 10; wa_carrier_multiplier deve ser de, pelo menos, 1 (sem desconto abaixo do custo) e até 10. O envio de uma chave não reconhecida, ou de um valor fora do intervalo, rejeita TODO o pedido e nomeia cada chave em infração, para que um erro de digitação nunca possa guardar silenciosamente um preço que não é, na verdade, aplicado.

Se for membro do Champions Circle, o insider-rate transmite a sua taxa de 20% de desconto no Max/Lead Finder a um cliente, em vez de a aplicar a toda a agência:

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

Ativá-lo requer que a sua própria conta de agência tenha, de facto, uma adesão ao Circle; desativá-lo nunca requer, pelo que um membro com adesão expirada pode sempre reverter a situação de um cliente.

Bloquear secções do manual de procedimentos de um cliente

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 é uma matriz extraída de instructions, goal, rules, personality, conclude_unless — SUBSTITUI a lista bloqueada do cliente. Uma secção bloqueada é rejeitada no lado do servidor se a própria SUB-CONTA tentar alterá-la (diretamente ou por chave API), enquanto o utilizador (via sub_account_id) e a vista de administrador do painel do cliente ainda podem editar qualquer coisa. Envie null (ou []) para desbloquear tudo. Útil para clientes com serviços “chave na mão”, onde detém o manual de procedimentos e é avaliado pelo resultado.

Definir as preferências de notificação de um cliente em seu nome

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

notifications substitui todo o conjunto de preferências de notificação do cliente (não é uma fusão por chave — envie todas as categorias que pretende manter, correspondendo à forma como a página de Definições da própria sub-conta guarda). Cada categoria em settings aceita enabled (booleano) e até três channels de email, in_app, webhook. Envie null para repor as predefinições da plataforma.

Todos os sete endpoints respondem { "success": true, "data": { "subAccountUid": "...", ...the field(s) you set... } } e são registados em auditoria com o valor antes/depois. Erros comuns: 403 se a sua conta não for de Agência/Dev ou se a sub-conta não for da sua gestão, 400 se não for uma sub-conta de agência ou se um valor estiver fora do intervalo.


Suspender um cliente que interrompeu a sua subscrição

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

Quando um cliente suspende a sua subscrição consigo, suspenda a sua conta em vez de a eliminar: tudo o que enviam para imediatamente — mensagens de saída, transmissões, respostas de IA em todos os canais — e, quando iniciam sessão, veem um bloqueio de ecrã inteiro Conta suspensa (com a sua mensagem opcional) em vez da aplicação. Nada é eliminado ou desligado: agentes, campanhas, canais ligados, contactos e histórico de conversas permanecem exatamente como estão, pelo que retomar a conta coloca o cliente precisamente onde parou — sem necessidade de refazer a configuração.

Campo Obrigatório Descrição
message Não Mostrado ao cliente no seu ecrã de bloqueio. Deixe em branco para a redação predefinida.
reason Não Nota interna da agência guardada com a suspensão e no registo de auditoria — nunca mostrada ao cliente.

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

Resposta

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

Quando o cliente regressa, POST /v1/subaccounts/SUB_ACCOUNT_UID/unpause (sem corpo) levanta o bloqueio — o envio e as respostas de IA são retomados imediatamente.

Importante saber:

  • É o mesmo estado que o interruptor de Bloqueio total do painel de controlo (Bloquear / Suspender uma Subconta) — um cliente suspenso através da API aparece como bloqueado no painel de controlo e vice-versa, e retomar a conta limpa um bloqueio efetuado de qualquer um dos lados. O estado atual pode ser lido a partir do campo agency_block em GET /v1/subaccounts (level de "none", "soft_blocked" ou "hard_blocked").
  • Ambas as chamadas são idempotentes. Suspender um cliente já suspenso apenas atualiza a mensagem, o motivo e o carimbo de data/hora; retomar um cliente ativo não altera nada.
  • O cliente não é notificado automaticamente por e-mail — muitas agências utilizam marca branca, pelo que informar o cliente fica ao seu critério.
  • A sua própria faturação DM Champ permanece inalterada. Suspender um cliente apenas afeta a sua relação com ele.
  • Os assistentes de IA também podem fazer isto: o servidor MCP expõe estes endpoints como as ferramentas pause_subaccount e unpause_subaccount.

Conceder ou deduzir créditos diretamente

POST /v1/subaccounts/credits

Adiciona ou remove uma quantidade exata de créditos do saldo de uma subconta — o equivalente na API ao ajuste manual de crédito do painel de controlo. Trata-se de uma alteração de saldo pontual, distinta das definições recorrentes monthly_credits, roll_over_to_next_month, rollover_cap_months e rollover_expiry_days em PUT /v1/subaccounts/{subAccountUid}/limits.

Este é o único endpoint nesta página que identifica a sub-conta pelo e-mail em vez de sub_account_id.

Campo Obrigatório Descrição
email Sim O e-mail da sub-conta, tal como existe na sua agência.
amount Sim Número de créditos diferente de zero. Positivo adiciona, negativo deduz.
description Não Apresentado junto ao ajuste no histórico de créditos do cliente. Predefinição para uma linha genérica “Ajustado pela agência via API”.

cURL

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

Resposta

{
  "success": true,
  "data": {
    "email": "client@example.com",
    "previous_balance": 1200,
    "adjustment": 500,
    "new_balance": 1700
  }
}

Um amount negativo que leve o saldo abaixo de zero é recusado com 400, indicando-lhe o saldo disponível e o montante que tentou deduzir. Se o cliente estiver na sua própria faturação Stripe (modo de revenda), um montante adicionado também conta como créditos que comprou, pelo que sobrevive à sua próxima reposição mensal da mesma forma que um carregamento real; num cliente com alocação padrão, é tratado como parte do seu plafond recorrente. De qualquer forma, são uma adição única, pelo que um limite de rollover ou uma expiração definida na conta (ou no seu plano) nunca os reduz — apenas o plafond recorrente e os créditos do plano estão sujeitos a isso.


Ler as conversas de uma sub-conta

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

Permite-lhe criar uma vista de monitorização ou de suporte das conversas de um cliente sem iniciar sessão na conta dele. Primeiro, liste os contactos com uma pré-visualização da última mensagem e, em seguida, leia o histórico completo de mensagens de um contacto.

Listar contactos

curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats?apiKey=YOUR_AGENCY_API_KEY&pageSize=25"
Parâmetro de consulta Obrigatório Descrição
pageSize Não Contactos por página. Predefinição 25, máximo 50.
lastActivityAt Não Cursor de paginação — indique o lastActivityAt da página anterior para continuar.
searchQuery Não Filtrar por nome de contacto ou número de telefone.

Resposta

{
  "success": true,
  "data": {
    "contacts": [
      {
        "contactId": "contact456",
        "firstName": "Jamie",
        "lastName": "Lee",
        "phoneNumber": "+14155551234",
        "email": "jamie@example.com",
        "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": "client@example.com",
    "hasMore": true,
    "lastActivityAt": "2026-08-30T14:22:00.000Z"
  }
}

Os contactos são ordenados pela atividade mais recente primeiro. Continue a paginar com lastActivityAt enquanto hasMore for true.

Ler as mensagens de um contacto

curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats/contact456/messages?apiKey=YOUR_AGENCY_API_KEY&pageSize=30"
Parâmetro de consulta Obrigatório Descrição
pageSize Não Mensagens por página. Predefinição 30, máximo 100.
beforeTimestamp Não Cursor de paginação — obter mensagens anteriores a este carimbo de data/hora ISO.

Resposta

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

As mensagens são devolvidas da mais recente para a mais antiga; navegue pelo histórico com beforeTimestamp.


Ler a utilização de créditos e o estado das campanhas em toda a sua carteira

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

Dois resumos em estilo de painel sobre todas as subcontas que gere, para criar os seus próprios relatórios de agência em vez de ter de aceder a cada cliente individualmente.

Utilização de créditos

curl "https://api.dmchamp.com/v1/subaccounts/credit-usage?apiKey=YOUR_AGENCY_API_KEY&from=2026-08-01&to=2026-08-31"
Parâmetro de consulta Obrigatório Descrição
from / to Sim Intervalo de datas ISO.
subAccountId Não Omitir para um resumo de toda a agência, uma linha por subconta. Incluir para mudar para o modo de detalhe: o resumo dessa subconta mais os seus registos de utilização brutos e paginados.
limitCount Não Apenas modo de detalhe. Predefinição 500, máximo 2000.
startAfterTimestamp Não Apenas modo de detalhe — cursor de paginação.
{
  "success": true,
  "data": {
    "subAccounts": [
      {
        "subAccountId": "abc123def456",
        "subAccountName": "Client Co",
        "subAccountEmail": "client@example.com",
        "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
  }
}

Ao passar subAccountId, a mesma resposta também inclui records: cobranças individuais com amount, reason, campaignName, contactName e timestamp. Um cliente que gaste através da sua própria chave BYOK, em vez dos seus créditos, terá os valores de custo/token ocultos (costsRedacted: true) — trata-se de telemetria de custos da plataforma, não de algo a apresentar a um revendedor.

Estado da campanha

curl "https://api.dmchamp.com/v1/subaccounts/campaign-status?apiKey=YOUR_AGENCY_API_KEY&pageSize=20"
Parâmetro de consulta Obrigatório Descrição
pageSize Não Subcontas por página. Predefinição 10, máximo 50.
lastDocumentId Não Cursor de paginação.
searchQuery Não Filtrar por nome ou e-mail da subconta.
{
  "success": true,
  "data": {
    "totalSubAccounts": 34,
    "subAccountsWithIssues": 3,
    "totalLiveCampaigns": 51,
    "totalPausedCampaigns": 6,
    "subAccounts": [
      {
        "userId": "abc123def456",
        "email": "client@example.com",
        "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
  }
}

hasIssues / issueDetails sinalizam subcontas que merecem atenção — uma campanha em pausa, ou uma sem nenhum canal encaminhado para ela, por exemplo. Utilize isto para criar um painel de controlo de integridade para toda a carteira, em vez de abrir cada cliente para detetar uma campanha parada.

Para mensagens de séries temporais e atividade de crédito em todos os clientes (uma série pronta para gráficos em vez de um instantâneo de um momento específico), consulte GET /analytics/agency-rollup no guia da API de Analytics.


Envie uma conta de cliente já configurada

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

Um snapshot é um modelo reutilizável: um ou mais agentes de IA, juntamente com a sua base de conhecimento, ferramentas e multimédia, capturados a partir da sua própria conta. Dois endpoints integram-no no seu fluxo de aprovisionamento.

Automático — cada novo cliente nasce com ele. Marque um snapshot como predefinido uma vez e todas as contas que criar a partir daí chegarão com ele instalado. Isto abrange contas criadas através de POST /v1/subaccounts, contas que cria no painel de controlo e contas criadas automaticamente quando um cliente paga através da sua hiperligação de checkout.

Primeiro, encontre o ID do snapshot:

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

Depois, defina-o como predefinido:

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

Essa é toda a integração. Envie {"snapshot_id": null} para o desativar novamente. Pode fazer o mesmo a partir do painel de controlo clicando na estrela na página Snapshots.

Para ler o que está atualmente marcado com estrela (por exemplo, antes de um script de aprovisionamento decidir se deve definir uma), GET /v1/snapshots/default devolve { "success": true, "data": { "default_snapshot_id": "SNAPSHOT_ID" } }null quando nada está marcado com estrela. GET /v1/snapshots (usado para encontrar o id acima) devolve o mesmo default_snapshot_id juntamente com a matriz snapshots completa, pelo que a maioria das integrações só precisa de uma chamada. Os campos do objeto de instantâneo completo encontram-se no guia Snapshots.

A pedido — instalar numa conta. Útil para integrar um cliente existente ou para fornecer a um cliente um segundo modelo mais tarde.

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

Omita sub_account_id e será instalado na sua própria conta de agência. Tal como os endpoints /subaccounts, estes nomeiam a conta de destino no caminho ou no corpo, em vez de através do parâmetro sub_account_id ambiente.

Vale a pena saber antes de construir com base nisto:

  • Os agentes instalados começam em pausa. Ligue primeiro os canais do cliente e, em seguida, ative o agente. Isto aplica-se tanto ao caminho automático como ao caminho a pedido.
  • O aprovisionamento nunca falha devido a um snapshot. Se a instalação não puder ser concluída, a conta do cliente é criada e utilizável na mesma — chega apenas vazia e pode aplicar o snapshot posteriormente.
  • Canais, calendários e ligações OAuth nunca são copiados. Cada conta liga os seus próprios. As ferramentas que utilizam uma chave de API simples continuam a funcionar imediatamente.
  • Aplicar duas vezes cria uma segunda cópia. Nada é substituído.

Crie o próprio modelo através da API

POST /v1/snapshots · agentes, funções personalizadas e multimédia através da API

A secção acima distribui uma “snapshot” criada por alguém no painel de controlo. A parte de autoria também está exposta, pelo que todo o ciclo — montar a configuração principal uma vez, capturá-la, entregá-la a cada cliente — pode ser executado a partir de código.

As peças, pela ordem que um script de aprovisionamento utiliza:

  1. Crie as suas funções personalizadas. POST /v1/custom-functions cria uma; GET /v1/custom-functions lista as que possui, e GET, PUT e DELETE em /v1/custom-functions/{customFunctionId} leem, atualizam e removem uma. POST /v1/custom-functions/test testa uma definição antes de a guardar.
  2. Crie e configure o agente. POST /v1/agents cria-o, PUT /v1/agents/{agentId} atualiza-o, e PATCH /v1/agents/{agentId}/active com { "active": false } mantém-no em pausa enquanto trabalha (a mesma chamada com true coloca-o em funcionamento). GET /v1/agents lista-os.
  3. Dê capacidades ao agente. POST /v1/agents/{agentId}/custom-functions com { "custom_function_id": "..." } associa uma função ao agente; o DELETE /v1/agents/{agentId}/custom-functions/{customFunctionId} correspondente desassocia-a.
  4. Preencha a biblioteca de multimédia. POST /v1/agents/{agentId}/media-library carrega um item (JSON com base64Data, mimeType, title, description); GET lista os itens do agente, e PATCH/DELETE em /{itemId} atualizam ou removem um.
  5. Capture-o como uma “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
  }'

A partir daí, aplica-se a secção anterior: defina-a como predefinida para que cada novo cliente nasça com ela, ou aplique-a a pedido. A gestão existe em paralelo: PATCH /v1/snapshots/{snapshotId} com { "name": "..." } renomeia uma, DELETE /v1/snapshots/{snapshotId} elimina uma (e remove o estado de predefinida se for o caso), e GET /v1/snapshots/apply-targets lista todas as contas nas quais pode instalar.

Os endpoints de agente, função personalizada e multimédia aceitam todos sub_account_id, pelo que as mesmas chamadas também podem manter um agente diretamente na conta de um cliente. As chamadas de “snapshot” atuam sempre na sua conta de agência — o modelo reside consigo. Os esquemas completos de pedido e resposta para todos estes elementos encontram-se na Referência da API.


Gerir os seus níveis de preços através da API

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

Os planos que vende em Modo SaaS → Níveis de Preços podem ser lidos e alterados a partir de código, para que o seu próprio painel de administração ou script de aprovisionamento possa adicionar um plano, ajustar um preço ou fornecer uma ligação de checkout sem que ninguém tenha de abrir o painel de controlo. Autentique-se com a sua chave de API de agência como em qualquer outra chamada nesta página; estes endpoints são ao nível da agência, pelo que não requerem sub_account_id. Cada escrita executa a mesma validação e a mesma sincronização de produto-e-preço do Stripe que o guardar no painel de controlo, pelo que um plano criado aqui é indistinguível de um que tenha configurado manualmente.

Listar os seus níveis

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

Resposta

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

Cada nível é devolvido com o seu tierIndex — a sua posição na sua lista de Planos, que é a forma como as outras três chamadas o identificam — e uma checkout_url pronta a partilhar, a mesma ligação que o separador Pagamentos lhe fornece, já a apontar para o domínio white label em que esse plano é vendido.

Adicionar um nível

O corpo é um objeto de nível; é acrescentado ao fim da sua lista.

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

A resposta contém o nível criado, incluindo o tierIndex em que ficou e a sua checkout_url.

Editar um nível

Envie apenas os campos que pretende alterar; tudo o resto no plano permanece como estava.

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

Um campo que a API não reconheça é recusado em vez de ignorado, e o erro identifica-o — para que um erro de digitação nunca escreva silenciosamente uma definição que parece ativa mas não faz nada. Alterar o preço, os créditos, a moeda ou a cadência de faturação cria um novo preço no seu Stripe; os clientes que já subscreveram permanecem com o que contrataram.

Eliminar um nível

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

A mesma regra do painel de controlo: um plano que ainda tenha subscritores ativos não pode ser eliminado. O pedido é recusado, indicando quantos subscritores estão no plano — cancele ou migre-os primeiro. Uma eliminação bem-sucedida responde com os seus níveis restantes, já renumerados.

Os campos num nível

Campo O que é
label / description O nome do plano e a linha opcional apresentada na sua página de checkout.
credits Créditos que o cliente recebe por mês num plano mensal ou anual, e por período de faturação num semanal.
price_cents Preço por intervalo de faturação, na unidade monetária mais pequena (2900 = $29.00). Num plano anual, este é o preço de todo o ano.
currency Código ISO em minúsculas — usd, eur, gbp, etc.
billing_interval / billing_interval_count month (a predefinição), year, ou week com uma contagem de 1–52 para “a cada N semanas”.
trial_days Duração do período experimental, de 0 a 90. 0 (ou omiti-lo) significa sem período experimental.
trial_credits Créditos com que o cliente inicia o período experimental. Predefinição para o credits do plano.
trial_card_required false permite que o cliente inicie o período experimental sem introduzir um cartão. Predefinição para true.
trial_hard_expiry true devolve os créditos experimentais não utilizados ao seu pool e bloqueia a conta do cliente quando um período experimental termina sem uma atualização. Predefinição para false — consulte Expiração rígida após o período experimental.
rollover_cap_months Meses de plafond que os clientes neste plano podem transportar entre renovações — um número de 0 a 120, frações permitidas. 0 não transporta nada; null (a predefinição) significa sem limite. Consulte Limitar o que é transportado.
rollover_expiry_days Dias após os quais os créditos não utilizados são removidos na renovação seguinte — um número inteiro de 1 a 3650. null (a predefinição) significa que nunca expiram.
features / feature_settings O que os clientes neste plano obtêm — os mesmos IDs de funcionalidade que Escolher que tipos de canal um cliente pode ligar.
team_seats_limit Lugares de equipa que o plano concede: um número exato, 0 para nenhum, -1 para ilimitado.
white_label_config Em qual dos seus domínios white label o plano é vendido.

Os campos de período experimental só têm significado num plano que tenha um período experimental: se guardar um nível com trial_days: 0, estes são descartados. Os IDs de produto e preço do Stripe do plano são geridos por si e não podem ser definidos manualmente.

Três aspetos a ter em conta:

  • Os índices de escalão são posições, não IDs permanentes. Eliminar um plano desloca todos os planos seguintes uma posição para baixo, por isso volte a obter a lista após qualquer alteração — e volte a copiar as hiperligações de checkout que publicou, exatamente como faria após eliminar um plano no painel de controlo.
  • O Modo SaaS tem de ser configurado primeiro. Estes endpoints necessitam de uma conta de agência com white labeling e uma chave Stripe já guardada; sem isto, não existe uma conta Stripe onde o produto e o preço do plano possam residir.
  • Vinte planos é o limite, o mesmo que no painel de controlo. O campo max_tiers na resposta da lista indica-lhe o limite atual.

Os esquemas completos de pedido e resposta encontram-se na Referência da API, em Agência.


Defina o seu preço por crédito através da API

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

O preço que os clientes pagam por carregamentos pontuais (Modo SaaS → Preço por Crédito) também pode ser lido e alterado a partir de código. Isto foi criado para casos em que o preço tem de ser ajustado automaticamente: uma agência que vende créditos numa moeda mas cobra noutra pode permitir que uma tarefa agendada reveja o preço à medida que a taxa de câmbio muda, em vez de alguém o editar manualmente todas as semanas.

Ler o preço atual

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

Resposta

{
  "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 é o preço mais baixo que a plataforma permite nessa moeda, pelo que uma tarefa pode verificar um novo preço antes de o enviar. Todos os três valores são null até que um preço tenha sido definido.

Alterá-lo

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

Envie apenas o que pretende alterar. price_per_credit_cents é o preço na unidade monetária mais pequena (130 = R$1,30); currency é um código ISO em minúsculas; note é uma linha opcional de até 200 caracteres apresentada aos clientes diretamente abaixo do preço por crédito na sua página de Faturação — útil para um preço de referência noutra moeda, como “USD 0,25 por crédito à nossa taxa de referência”. Envie "note": "" para o remover. A resposta tem o mesmo formato que a leitura acima, pelo que uma tarefa pode comparar e ignorar a escrita quando nada mudou.

Aplicam-se as mesmas regras que no painel de controlo: o preço não pode ser inferior ao mínimo da plataforma para essa moeda e a conta necessita de white labeling. Ao contrário dos endpoints de níveis de preços, não é necessária uma chave Stripe para ler ou alterar este valor.

Dê a uma tarefa uma chave que não possa fazer mais nada

Colocar a sua chave de agência completa num agendador é dar mais acesso do que uma atualização de preço necessita. Em vez disso, crie uma chave com âmbito limitado (scoped key) restrita à área de Preço de Crédito da Agência: essa chave pode ler e alterar o preço por crédito e nada mais — não pode aceder a subcontas, planos, créditos ou à sua ligação 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"] } }'

A resposta contém a nova chave em api_key apenas uma vez — nunca mais será apresentada, por isso guarde-a imediatamente. Defina "read_only": true para uma chave que apenas precise de ler o preço e adicione "expires_at" (uma data ISO) se pretender que esta deixe de funcionar automaticamente. Apenas a chave do proprietário da conta pode criar chaves com âmbito limitado; liste-as ou revogue-as com GET /v1/api-keys e DELETE /v1/api-keys/{id}.


Permita que uma subconta leia os seus preços

GET /v1/subaccounts/agency-pricing

Todos os outros endpoints nesta página são chamados com a sua chave de agência, visando opcionalmente um cliente através de sub_account_id. Este é o oposto: é chamado com a chave de API da própria subconta, sem sub_account_id, para que a página de carregamento do próprio cliente (ou uma integração que crie para eles) possa exibir o que lhes cobra sem nunca ver a sua conta de agência.

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

Resposta

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

Isto reflete exatamente o que GET /v1/agency/pricing-tiers e GET /v1/agency/credit-price devolvem para si como agência, menos tudo o que o cliente não precisa de ver (ids do Stripe, max_tiers, etc.). Só funciona para uma conta que seja efetivamente uma subconta com uma agência associada — chamá-lo a partir da sua própria conta de agência devolve um erro de permissão.


Aspetos a ter em conta

  • Utilize a sua chave de agência. Autentique cada chamada com a chave de API da sua conta de agência — não a da subconta. O parâmetro sub_account_id é o que redireciona a ação.
  • Os créditos provêm da subconta. As compras e as cobranças recorrentes são deduzidas do saldo de crédito da subconta visada, não do seu.
  • Um 404 significa “não é a sua subconta”. Verifique o id e confirme que a conta é uma das que gere.
  • O parâmetro é opcional em todos os locais onde é aceite. Se o omitir, o mesmo endpoint atua sobre a sua conta de agência, pelo que pode reutilizar uma única integração para ambos.

Relacionado

  • Acesso à API — autenticação, URL base, erros, limites de taxa.
  • Subcontas — listar e gerir as contas que pode visar.
  • Recarregamento Automático de Subconta — conceder créditos a uma subconta via webhook + API.
  • API de Campanhas — criar, atualizar e copiar campanhas, incluindo a referência completa de campos.
  • API de Ligação de Canais — ligar os canais de um cliente e encaminhá-los para uma campanha.
  • Guia da API de Analytics (na secção da API) — o resumo de subcontas da agência e todos os outros endpoints de relatórios.
  • Snapshots — o que um instantâneo captura e como criar um no painel de controlo.