DM Champ Docs

API para Agências

Como agência, você pode usar a mesma API REST que seus clientes usam, mas direcionar solicitações individuais para uma de suas subcontas gerenciadas em vez de sua própria conta. Isso permite que você crie ferramentas que realizam o onboarding de um cliente de ponta a ponta — criando seus agentes de IA, treinando sua IA em uma base de conhecimento, importando seus contatos, conectando seus canais de mensagens e comprando números de telefone — tudo sem precisar fazer login em cada subconta manualmente.

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

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


Como funciona o “agir em nome de”

Por padrão, toda solicitação de API atua na conta que possui a chave de API — sua conta de agência. Para atuar em uma conta de cliente gerenciada, adicione o parâmetro opcional sub_account_id à solicitação, definido como o ID da conta desse cliente.

  • Omitir sub_account_id → a solicitação atua em sua própria conta de agência.
  • Incluir sub_account_id → a solicitação atua nessa subconta, mas apenas após a plataforma confirmar que a subconta é realmente sua.

Você sempre se autentica com a chave de API da sua conta de agência. Você nunca precisa da chave da própria subconta e nunca manipula as credenciais da subconta.

Onde inserir

  • Endpoints GET / DELETE → passe-o como um parâmetro de consulta: ?sub_account_id=THE_SUB_ACCOUNT_ID (junto com seu apiKey, se você se autenticar por consulta).
  • Endpoints POST / PUT / PATCH → inclua-o no corpo da requisição JSON como "sub_account_id": "THE_SUB_ACCOUNT_ID".
  • Assistentes de IA → nada a configurar. O servidor MCP carrega a mesma configuração em suas ferramentas, portanto, uma conexão com sua chave de agência pode gerar relatórios sobre cada cliente: basta nomear o cliente em sua solicitação (“quantos contatos o Bella’s Bistro tem?”). Ações de escrita também estão disponíveis: cada endpoint que aceita sub_account_id é exposto como uma ferramenta, para que você possa criar, alterar e enviar em nome de um cliente a partir da mesma conexão.

Encontrando o ID de uma subconta

O sub_account_id é o identificador único da conta do cliente. Você pode obter a lista de suas subcontas e seus respectivos IDs nos endpoints da API de SubAccounts (veja o guia de Sub-Accounts) ou na página de Sub Accounts na barra lateral.


A propriedade é sempre verificada

Quando você passa um sub_account_id, a plataforma verifica se a conta é uma subconta real e se ela pertence à sua agência. Somente então a solicitação é processada.

Se o ID for desconhecido, não for uma subconta ou pertencer a uma agência diferente, a solicitação falhará com uma resposta 404:

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

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


Onde sub_account_id é suportado

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

  • Configuração de IA — campanhas, agentes, FAQs, fontes da base de conhecimento (rastreamento de site e upload de documentos), grupos da base de conhecimento, transmissões, funções personalizadas, servidores MCP
  • Contatos e CRM — contatos (incluindo importação), listas, etiquetas, tarefas, negócios, agendamentos, eventos
  • Canais e números — conectar WhatsApp / WhatsApp Web / Telegram / Instagram e Messenger / LINE, pesquisar / comprar / gerenciar números de telefone, modelos de WhatsApp, roteamento de canais
  • Mensagens e conteúdo — enviar mensagens, sessões de chat, exportações de chat, resumos diários
  • Configurações e integrações — webhooks, configuração do widget de chat, configuração de white-label, SMS BYOK e outras configurações de conta, análise, log de erros

Em cada uma delas, o parâmetro é opcional — deixe-o de fora e a chamada agirá na sua própria conta de agência, permitindo que uma única integração atenda a ambos. Créditos e uso sempre vêm da conta que você direciona: cobranças por respostas de IA, mensagens, tags e números de uma subconta são debitadas do saldo da subconta.

Onde NÃO se aplica

Alguns endpoints são de nível de agência ou auto-endereçados e ignoram sub_account_id:

  • Gerenciando as próprias subcontas — os endpoints de Subcontas (criar / listar / atualizar uma subconta) e o endpoint de limite de gastos BYOK já nomeiam a subconta em seu próprio caminho de URL. Os endpoints de preços e políticas e endpoints de monitoramento de chat seguem o mesmo padrão.
  • Copiando um Agente entre contas — POST /v1/subaccounts/agents/copy nomeia ambas as contas, tomando o destino como targetUserId. Veja o exemplo prático abaixo. (O POST /v1/subaccounts/campaigns/copy mais antigo funciona da mesma maneira, mas está obsoleto junto com o restante da API de Campanhas.)
  • Ajustando créditos e os dois rollups de toda a agência — POST /v1/subaccounts/credits identifica a subconta por email; GET /v1/subaccounts/credit-usage e GET /v1/subaccounts/campaign-status geram relatórios sobre todas as subcontas de uma só vez, portanto, não há uma conta única a ser alvo.
  • A própria conta da sua agência — O gerenciamento de chaves de API, relatórios de uso da agência, gerenciamento de equipe e seus níveis de preços sempre atuam na conta da sua agência.
  • Adicionando contatos a uma lista ou removendo-os de uma: POST / DELETE /v1/contacts/lists e POST /v1/contacts/lists/batch atuam na conta que possui a chave. Criar, editar e excluir as próprias listas (/v1/lists) requer sub_account_id.
  • Webhooks de mensagens recebidas — endpoints nos quais sistemas externos postam dentro estão vinculados à conta cujas credenciais os configuraram, portanto, não há nada para redirecionar.

A lista sempre atualizada e legível por máquina de quais parâmetros cada endpoint aceita encontra-se na referência da API do seu painel (Settings → Integrations → API Key) e na especificação OpenAPI em GET /v1/docs/openapi.yaml. Lançamos alterações na API com frequência — trate essas fontes como a referência definitiva.

Página de configurações da Chave de API com chave mascarada e controle de Regenerar

Configurações → Integrações → Chave de API — a chave da sua agência fica aqui, junto com o link para a referência completa da API.


Liste suas subcontas ou verifique um e-mail

GET /v1/subaccounts

Chamado sem parâmetros, ele retorna todas as subcontas sob sua agência em um array data. Adicione o parâmetro de consulta opcional email para pesquisar um único cliente:

curl "https://api.dmchamp.com/v1/[email protected]&apiKey=YOUR_API_KEY"
  • Esse e-mail pertence a uma de suas subcontas ativas → HTTP 200, com apenas essa conta: { "success": true, "data": { ... } }.
  • Ele não pertence → HTTP 404, Agency Sub Account not found.

Não existe um parâmetro que responda com um simples sim ou não, portanto, leia o código de status: 200 significa que o e-mail é um de seus clientes, 404 significa que não é. Subcontas excluídas são omitidas, portanto, uma conta que você removeu também será lida como 404.

Cada conta retorna com seu perfil, suas configurações, seus limites de uso e os recursos que estão ativados, o que é tudo o que você precisa para exibir uma linha de cliente em seu próprio painel.

A resposta nunca carrega credenciais. Chaves de API, senhas, tokens de login e os detalhes dos canais que um cliente conectou (Twilio, Google, Meta e bring-your-own-key) são removidos antes do envio. Não há parâmetro para escolher quais campos você recebe, então leia os campos de que precisa e ignore o restante.

Requer acesso à API e uma conta de agência.


Criar uma conta de cliente

POST /v1/subaccounts

Criar a conta é uma única chamada com o e-mail, nome e nome comercial do cliente. Algumas coisas sobre isso valem a pena saber antes de você criar seu fluxo de inscrição.

Você não pode escolher a senha. Não há campo de senha: uma é gerada para você e entregue uma única vez, como temporary_password na resposta 201. Armazene-a ou repasse-a imediatamente, pois nada a mostrará a você novamente. O cliente pode alterá-la em seu perfil ou redefini-la na tela de login.

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

Nada é enviado por e-mail ao cliente, a menos que você solicite. Por padrão, a conta é criada silenciosamente, e informar o cliente sobre ela é sua responsabilidade. Envie send_account_info_to_sub_account: true e eles receberão um e-mail de boas-vindas com seu endereço de e-mail, aquela senha temporária e um link para entrar, tudo em seu próprio domínio white-label e sob sua marca.

A flag cobre apenas o e-mail do cliente. Sua agência sempre recebe um aviso de Nova Subconta Criada, mas ele nunca contém a senha: por segurança, a resposta 201 é o único lugar onde você a obtém. Se ela for perdida, o cliente define a sua própria usando Esqueci a senha na tela de login.

Os créditos iniciais são definidos por você. usage_limits.credits é o limite de gastos inicial do cliente e usage_limits.monthly_credits é a mesada mensal recorrente. Envie "credits": 0 e a conta começará sem nada para gastar; deixe credits de fora e ela começará com um saldo único de 100 créditos para que a IA possa responder imediatamente. Nenhum dos dois retira nada do seu pool da agência no momento da criação: seu pool só é cobrado conforme o cliente realmente usa os créditos.

Nomes comerciais devem ser únicos dentro de sua agência. Dois de seus clientes não podem ser ambos “Client Co”, porque esse nome é o que identifica a conta em seu painel e em seus relatórios. Nomes de outras agências não interferem nisso.

Quando a chamada falha:

Status O que aconteceu
400 Um campo está faltando ou incorreto, o e-mail não é um endereço válido ou a chave que você usou não pertence a uma conta de agência.
401 A chave de API está incorreta, expirada ou revogada.
402 Sua própria assinatura não está ativa, portanto, novas contas de cliente não podem ser criadas até que seu faturamento seja regularizado.
403 Você atingiu o número de contas de cliente que seu plano permite.
409 Esse nome comercial já é usado por um de seus clientes, ou esse e-mail já pertence a uma conta.

Excluir uma conta de cliente

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

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

Isso é o mesmo que o botão excluir na página de Subcontas, e não pode ser desfeito. O cliente é bloqueado imediatamente e não conta mais para o seu total de clientes; suas conversas, contatos, agentes e canais conectados são apagados em segundo plano nos minutos seguintes. Um plano que o cliente comprou através do seu checkout é cancelado.

{
  "success": true,
  "message": "Sub-account deletion started",
  "data": { "uid": "SUB_ACCOUNT_UID", "email": "[email protected]", "status": "deletion_started" }
}
  • Passe email ou uid. Se você passar ambos, eles devem nomear o mesmo cliente.
  • Apenas seus próprios clientes podem ser excluídos. Qualquer outro e-mail ou uid, e um cliente que já foi excluído, retorna 404.
  • Chamá-lo novamente enquanto a exclusão ainda está em execução retorna 200 com "status": "already_in_progress".
  • Assistentes de IA conectados através do servidor MCP têm isso como a ferramenta delete_subaccount quando conectados ao endereço MCP padrão (ferramentas de agência são deixadas de fora de um endereço MCP white-label).
  • Para parar um cliente por um tempo sem perder nada, pause-o em vez disso: eles são bloqueados, tudo é mantido e uma chamada o traz de volta.

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

Conectar Instagram e Messenger é um fluxo baseado em navegador. Você o inicia com a API, entrega a URL de consentimento retornada ao cliente (ou abre para ele), espera que ele autorize no navegador e, em seguida, escolhe qual página conectar — tudo isso direcionando a subconta dele com sub_account_id.

Passo 1 — Iniciar a conexão

Chame o endpoint de conexão com o sub_account_id do cliente no corpo. Nenhuma credencial é enviada aqui; a plataforma retorna uma URL de consentimento que o cliente deve abrir em um navegador, além de um token de correlação de uso ú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 oauth_url em um navegador para autorizar. O state_token correlaciona esta tentativa e é um segredo de curta duração — não o registre em logs. A tentativa expira em expires_at; se expirar, comece novamente.

Passo 2 — Fazer polling até que as páginas carreguem

Após a autorização do cliente, faça a sondagem (polling) do endpoint de status (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 passa por pending → token_received → pages_loaded → connected. Aguarde por pages_loaded antes de selecionar uma página. Dois estados de erro terminal também podem aparecer em vez de progredir: failed e expired (o cliente recusou o consentimento ou o período de ~30 minutos do token de estado expirou) — um campo reason é incluído quando qualquer um deles ocorre. Pare a sondagem e reinicie na Etapa 1 se vir um deles; não espere por pending para sempre. Tokens de acesso à página nunca são retornados.

Passo 3 — Selecione a página para conectar

Escolha um dos IDs de página do Passo 2 e selecione-o. Selecionar uma página conecta tanto o Instagram quanto 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"
}

É isso — o Instagram e o Messenger agora estão conectados na subconta do cliente. Você forneceu apenas 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 ele no corpo da requisição. 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 registro do remetente do WhatsApp continua em segundo plano. Faça a sondagem de GET /v1/phone-numbers/{phoneNumber}/status?sub_account_id=abc123def456 até que o status atinja ONLINE antes de enviar.


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

O padrão usual de agência é manter um Agente mestre na sua conta de agência, configurado da maneira que você deseja que cada cliente comece, e criar uma cópia dele em cada nova subconta no momento do provisionamento. São três chamadas e nada precisa ser repetido depois: a cópia mantém suas configurações até que você 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 mídia são incluídas; os modelos de WhatsApp, postagens sociais conectadas e contatos da conta de origem, deliberadamente, não são. Lista completa de campos na API de Agentes de IA.

Observe que este endpoint utiliza targetUserId em vez de sub_account_id — ele nomeia ambas as contas. As duas chamadas abaixo usam o parâmetro sub_account_id normal.

Passo 2 — Ativá-lo

A cópia sempre chega pausada, portanto, não pode enviar mensagens a ninguém até que você autorize. Este também é o momento de definir o nível de IA em que você deseja que o cliente esteja; ele permanece lá, então não há necessidade de reaplicá-lo em uma programação.

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 ela

A cópia também chega sem roteamento, portanto, nada chega até ela até que você a torne a responsável pelas respostas nos canais que o cliente conectou. 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 contato desconhecido nesse canal é captada pelo Agente copiado automaticamente. Veja Apontar um canal para um Agente para os outros canais e roteamento por número.

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


Pule o assistente de configuração para um cliente que você mesmo configura

POST /v1/subaccounts

Por padrão, na primeira vez que o proprietário de uma nova subconta faz login, ele é guiado pelo Assistente de Configuração. Para clientes “done-for-you” — onde você cria o agente de IA e conecta os canais antes mesmo de o cliente fazer login — passe guided_onboarding: false ao criar a conta. Eles acessarão a tela inicial normal — o painel em um computador, seus chats em um telefone — e a entrada do Assistente de Configuração ficará oculta na 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": "[email protected]",
    "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 se comportará exatamente como sempre se comportou, portanto, as integrações existentes não precisam de alterações. Para devolver o assistente a um cliente mais tarde, exiba novamente o item guided_onboarding com PUT /v1/subaccounts/{subAccountUid}/menu-visibility (abaixo) — a visibilidade do menu controla se o assistente pode ser acessado, guided_onboarding controla apenas o redirecionamento do primeiro login.


Desative Tarefas, Resumos Diários ou a Biblioteca de Mídia para um cliente

POST /v1/subaccounts

Esses três recursos estão ativados para cada novo cliente, a menos que você especifique o contrário, e eles se comportam de maneira diferente de todos os outros recursos neste guia: eles são de opt-out (desativação opcional), não de opt-in. Deixá-los de fora da features não é suficiente por si só, porque a lista features de uma integração mais antiga simplesmente nunca os mencionou — não conseguimos distinguir entre “a agência desativou isso” e “esta lista foi escrita antes de a opção existir”.

Portanto, declare isso 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": "[email protected]",
    "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 você omitir permanecerá ativado. Com tasks: false, a IA para de criar tarefas para aquele cliente e nenhum e-mail de “Nova Tarefa Criada” é enviado; com daily_summaries: false, o resumo noturno nunca é gerado ou enviado por e-mail.

feature_settings é a única coisa que desativa esses três recursos no momento da criação. Deixá-los de fora da features não faz nada por si só, não importa como o restante da sua lista esteja — isso é intencional, para que uma integração mais antiga não perca silenciosamente todos os três.

Para alterar qualquer um desses itens posteriormente, envie a lista features completa para PUT /v1/subaccounts/{subAccountUid}/features — lá, a presença na lista ativa um recurso e a ausência o desativa.


Faça login automático de seus clientes em suas subcontas (SSO)

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

Uma única chamada com a chave de API da sua agência retorna uma URL pronta para abrir que conecta o cliente diretamente à sua própria subconta — sem tela de login, sem etapa de senha, nada para construir por cima. Abra em uma nova aba, em um redirecionamento ou em um iframe dentro do seu próprio produto.

Campo Obrigatório Descrição
redirect Não Página no aplicativo em que você deseja que o cliente termine, por exemplo, "/chats" ou "/agents". Retornado como deep_link_url na resposta.
app_base_url Não Host do painel para o link. O padrão é o seu domínio de white-label (ou o domínio da plataforma, caso não tenha um). Deve 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 usar bem:

  • Um salto. Abrir o url autentica o cliente e o leva diretamente para a página redirect do painel — sem tela de login, sem página intermediária. O deep_link_url nomeia o mesmo destino, para integradores que preferem navegar por um frame explicitamente após o login; uma vez que a sessão exista, qualquer caminho do painel funciona nesse contexto de navegador.
  • Crie sob demanda, abra imediatamente. O link contém uma credencial de login e expira após cerca de uma hora. Solicite-o no lado do servidor no momento em que o cliente clicar, e nunca o armazene ou envie por e-mail.
  • O token de login viaja no fragmento da URL (#…), que os navegadores nunca enviam para servidores, e é removido da barra de endereços no momento em que é consumido.
  • Apenas suas próprias subcontas. O endpoint recusa qualquer conta que sua agência não possua.
  • Um link expirado mostra um erro claro com um caminho para tentar novamente — crie um novo.

Ocultar itens de navegação em uma subconta

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

Controla quais itens da barra lateral e de configurações uma subconta vê — útil quando você incorpora o painel e deseja apenas as superfícies que seu produto ainda não cobre. Tudo o que não estiver listado permanece visível; envie null como o valor total de menuVisibility para redefinir tudo como visível. Ocultar um item oculta a entrada do menu — combine isso com os recursos que você concede à subconta para um controle rígido.

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

Resposta

{
  "success": true,
  "data": {
    "subAccountUid": "SUB_ACCOUNT_UID",
    "menuVisibility": {
      "side_nav": { "Dashboard": false, "Deals": 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éditos exibido na barra lateral) e guided_onboarding (o Assistente de Configuração). Campaigns apenas oculta a página de Campanhas desativada; as páginas de Agentes de IA e Transmissões não possuem chave e não podem ser ocultadas dessa forma. Três chaves adicionais — AiInsights, Sub Accounts e Agency Reselling — são aceitas, mas não fazem nada: elas se aplicavam apenas ao painel clássico desativado, portanto, defini-las não tem efeito em suas subcontas. Chaves ausentes significam visível; quando você mesmo faz login na subconta, os itens ocultos são exibidos temporariamente para que você possa sempre reverter as alterações.

O mesmo objeto menuVisibility também aceita dois campos opcionais para o painel principal do cliente. dashboard_widgets mapeia um ID de widget para true (exibido) ou false (oculto), e dashboard_order é uma lista de IDs de widgets na ordem em que devem aparecer. Os IDs, em sua ordem padrão, são kpis, performance, credits (Uso de crédito), funnel, inbox, outcomes, channel_health, ai_cost, ai_human, heatmap (Horários mais ativos), top_campaigns (Principais agentes), contacts_by_country, activity e tasks_deals. IDs ausentes permanecem visíveis, e IDs deixados de fora de dashboard_order seguem na ordem padrão. Por exemplo, "dashboard_widgets": { "credits": false } oculta o painel de créditos do cliente.

Ocultar uma página do menu nunca concede acesso a ela. Automations precisa que o recurso automations seja concedido na subconta — defina a chave como true sem ele e a página ainda não aparecerá. Tasks e DailySummaries funcionam de forma inversa: eles estão ativados para cada cliente, a menos que você os desative (veja Desative Tarefas, Resumos Diários ou a Biblioteca de Mídia para um cliente).


Escolha quais tipos de canal um cliente pode conectar

PUT /v1/subaccounts/{subAccountUid}/features

As chaves de Tipos de Canal que você vê em um nível de plano são IDs de recursos comuns, portanto, você pode defini-las por cliente a partir da API em vez do painel. Este é um dos endpoints que nomeia a subconta em sua própria URL, por isso não requer sub_account_id.

ID do Recurso Canal
channel_chat_widget Widget de Chat do Site
channel_whatsapp_api API do WhatsApp Business
channel_whatsapp_web WhatsApp Web (número vinculado por QR)
channel_instagram Instagram
channel_messenger Facebook Messenger
channel_telegram Telegram
channel_line LINE
channel_viber Viber
channel_email Caixa de entrada de e-mail
channel_sms SMS
channel_imessage iMessage
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/features" \
  -H "X-API-Key: YOUR_AGENCY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "features": [
      "channels_3",
      "channel_chat_widget",
      "channel_whatsapp_web",
      "channel_instagram",
      "image_understanding",
      "contact_tagging",
      "incoming_campaigns",
      "webhooks"
    ]
  }'

O que acertar:

  • A chamada substitui toda a lista de recursos. Envie todos os recursos que o cliente deve manter, não apenas aqueles que você está alterando. Os mesmos IDs funcionam como features em POST /v1/subaccounts quando você cria a conta.
  • Os tipos de canal e a contagem de canais são restrições separadas, e ambas se aplicam. channels_1 / channels_3 / channels_unlimited controlam quantas conexões; os IDs channel_* controlam quais tipos. O exemplo acima significa “até 3 conexões, e apenas Chat Widget, WhatsApp Web ou Instagram”.
  • automations_edit, broadcasts_send e smart_lists_create permitem que o cliente crie, edite e exclua suas próprias automações, transmissões e listas inteligentes. Uma lista que não nomeia nenhum dos três os deixa como estão (em uma nova subconta: todos os três ativados), para que uma integração mais antiga continue funcionando. Nomeie pelo menos um e a lista definirá todos os três: os que você deixar de fora serão desativados. O cliente ainda pode usar o que você configurou para ele de qualquer maneira, e sua chave de API de agência e suas próprias sessões na conta do cliente nunca são restringidas por esses três.
  • Todo outro recurso é exatamente o que a lista diz, na criação e na atualização. Um cliente criado ou atualizado com uma lista features recebe esses recursos e nada mais. Isso inclui crm_erp_integrations (a seção de integrações CRM & ERP, onde um cliente conecta o Odoo): ela só fica ativa quando sua lista a inclui, portanto, adicione-a se o cliente precisar conectar um CRM ou ERP. Um cliente criado sem nenhuma lista features recebe o conjunto padrão, que a inclui.
  • Não enviar nenhum ID channel_* significa nenhuma restrição de canal. Esse é o comportamento original, e é por isso que os clientes existentes não foram afetados quando isso foi lançado. Envie um ou mais e todo o resto aparecerá como bloqueado na página de Canais do cliente com uma nota de upgrade em vez de um botão Conectar. Os canais que o cliente já conectou continuam funcionando.

Definir a lista de canais em um nível de plano, para que cada cliente que compra esse nível a herde, é feito no painel, nas configurações do seu plano de agência. Este endpoint a define em uma subconta específica.


Defina um limite exato de membros da equipe para um cliente

PUT /v1/subaccounts/{subAccountUid}/limits

Os recursos do team_seats_* oferecem apenas níveis predefinidos (3 / 5 / 10 / ilimitado). Para dar a um cliente um número exato de assentos na equipe — 2, 7, 15, qualquer um — defina usage_limits.team_seats_limit em vez disso. Ele prevalece sobre as predefinições, e a plataforma o aplica em cada convite, adição direta e aceitação de convite: assim que o limite é atingido, convites adicionais são recusados pelo servidor.

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

Reduzir o limite nunca remove membros existentes da equipe; 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 }
  }'

Você 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, busque a subconta com GET /v1/subaccounts?email=... e verifique usage_limits.team_seats_limit (ausente/null = os padrõ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 deseja alterar. Um creditManagementMode de nível superior ("manual" ou "reselling") alterna o modo de crédito do cliente; uma subconta criada via API inicia no modo manual, portanto, alterne para "reselling" antes que o cliente pague através do seu checkout do SaaS Mode (veja Subcontas, Executando um teste gratuito).

Como isso interage com os limites de assentos do plano SaaS. Seus planos SaaS podem ter sua própria franquia de assentos (definida no editor de planos — veja Assentos de equipe em um plano), que é aplicada automaticamente quando um cliente assina. Um limite que você define por meio deste endpoint conta como uma concessão manual: comprar um plano substitui esse limite pela franquia de assentos do próprio plano (essa compra é uma escolha explícita de plano), mas renovações mensais automáticas nunca sobrescrevem um limite manual — portanto, uma exceção única que você concede a um cliente persiste durante seu ciclo de faturamento. Limpar o limite manual com null devolve o controle do campo ao plano na próxima renovação.

Limite o que um cliente carrega entre renovações. Duas chaves usage_limits adicionais ficam ao lado de roll_over_to_next_month. Ambas também são aceitas por POST /v1/subaccounts no momento da criação, e null limpa qualquer uma delas.

Chave O que faz
rollover_cap_months Meses de franquia que o cliente pode manter. Um número de 0 a 120, frações permitidas (0.5 = meio mês). A cada renovação, o saldo não utilizado é reduzido para, no máximo, esse número de vezes a franquia concedida na renovação, antes que os novos créditos sejam adicionados; 0 não transporta nada.
rollover_expiry_days Um número inteiro de dias, de 1 a 3650. Créditos deixados sem uso por tanto tempo são descartados na primeira renovação após atingirem essa idade. O consumo sempre abate os créditos mais antigos primeiro, portanto, um cliente que gasta sua franquia a cada mês nunca perde nada.

Se não forem definidos, ambos recorrem ao plano do cliente; um valor enviado aqui prevalece sobre o do plano. Apenas créditos recorrentes (a franquia mensal e os créditos do plano) estão sujeitos a eles: recargas, recargas automáticas e adições únicas nunca são limitadas ou expiradas. Cada redução é registrada no histórico de créditos do cliente como um Ajuste de Crédito de Limite de Rolagem ou um Ajuste de Crédito de Créditos Expirados e nunca conta como uso. Os equivalentes no nível do plano são rollover_cap_months e rollover_expiry_days em um nível de preço — veja Os campos em um nível e Limitando o que é transferido.


Definir precificação e política 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 chaves adicionais por cliente, juntamente com /limits, /features e /menu-visibility acima. Cada uma utiliza o uid da subconta na URL (sem parâmetro de corpo/query sub_account_id — o destino já está nomeado no caminho) e tem o mesmo escopo: sua chave de agência, e a subconta deve pertencer à sua agência.

Quais modelos de IA um cliente pode usar

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 } inclui (ou exclui) o cliente no nível Max AI, pelo preço de tabela da plataforma. Ativar isso para um cliente BYOK altera o custo de IA dele de “0 créditos, pagos com minha própria chave” para “cobrado do meu pool de créditos”, portanto, é uma decisão deliberada por cliente, em vez de um padrão para toda a agência.

Para restringir QUAIS níveis os Agentes de um cliente podem escolher (em vez de apenas limitar o Máximo), use 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 extraída de standard, economy, max, mini — ela SUBSTITUI a lista de permissões do cliente. Envie null (ou []) para limpar a restrição e permitir que eles escolham qualquer nível. Uma lista definida aqui conta como um bloqueio manual: o allowed_ai_tiers do próprio plano (veja Gerencie seus níveis de preços via API) não afeta mais este cliente na renovação. Isso é importante porque uma subconta que escolhe seu próprio nível de IA gasta do seu pool de créditos, então é a alavanca para determinar quais modelos um cliente revendedor pode usar para aumentar sua fatura.

Uma resposta de espera enquanto o cliente está sem 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 seu pool) está vazio, a IA não pode responder e o contato não ouve nada. Com enabled: true, cada contato que escreve durante a interrupção recebe message uma vez (máx. 500 caracteres, enviado como está em todos os canais), e a IA responde a essas conversas de verdade assim que os créditos retornarem. enabled: false mantém o texto salvo para mais tarde; enabled: false sem message remove a configuração. O mesmo interruptor que Resposta de espera quando sem créditos no modal de Edição da subconta — veja Uma resposta de espera enquanto um cliente está sem créditos.

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

Duas maneiras de definir sua taxa voltada 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 queima por ação de IA do modelo Max — sua margem de lucro voltada para o cliente sobre o que seu pool realmente paga. null limpa a substituição de volta para o preço de lista da plataforma. A taxa deve ser pelo menos o que uma ação Max custa ao seu próprio pool (para que você nunca possa precificar um cliente abaixo do seu custo) e não mais que 10 créditos; uma solicitação fora desse intervalo é rejeitada com o piso calculado na mensagem de erro.

Para precificação por tipo de ação em vez de uma taxa Max fixa, use 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 MESCLAGEM no mapa existente do cliente — uma chave que você não menciona é deixada como estava, e null redefine essa chave de volta ao seu padrão. As chaves reconhecidas:

Chave Preços
AI_MESSAGE Uma resposta de IA
AI_TOOL_USE Uma chamada de ferramenta de IA
EVALUATION_CALL Uma passagem de avaliação de chat
INTERRUPTION_HANDLING Lidar com uma interrupção no meio da resposta
CONTACT_TAG Uma tag de contato 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 à IA que o cliente paga: aluguel mensal de número, taxas de entrega em faixa gerenciada e custos de repasse de modelos Meta/Twilio.

As taxas por ação devem ser um número maior que 0 e até 10; wa_carrier_multiplier deve ser de pelo menos 1 (sem desconto abaixo do custo) e até 10. Enviar uma chave não reconhecida, ou um valor fora do intervalo, rejeita a solicitação INTEIRA e nomeia cada chave ofensiva, para que um erro de digitação nunca salve silenciosamente um preço que não é realmente aplicado.

Se você é um membro do Champions Circle, o insider-rate transfere sua Tarifa Insider (20% de desconto em ações Max e Mini, leads e automações do Lead Finder) para um cliente, em vez de aplicá-la 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 exige que sua própria conta de agência possua uma assinatura Circle; desativá-lo nunca exige, portanto, um membro com assinatura expirada sempre pode reverter a configuração de um cliente.

Bloquear seções do playbook 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 lista das seções do playbook a serem congeladas, e ela SUBSTITUI a lista bloqueada do cliente. Envie null (ou []) para desbloquear tudo. Útil para clientes com serviço completo (done-for-you), onde você é o proprietário do playbook e é avaliado pelo resultado.

Agentes criados no editor atual mantêm seu playbook nessas seções, portanto, estas são as que devem ser bloqueadas:

Seção no editor do agente Chave de API
Fluxo de Conversa conversation_flow
Informações da Empresa company_info
Oferta offer
Fonte de Lead lead_source
Propostas Únicas de Venda unique_selling_points
Posicionamento de Mercado market_positioning
Preços pricing_info
Tratamento de Objeções objection_handling
Perguntas a fazer questions
Alertar um membro da equipe quando alert_human_when
Outros other
Recursos resources
Instruções de E-mail email_instructions
Personalidade personality
Objetivo goal
Regras rules
Condições de Conclusão conclude_unless
Instruções (apenas agentes mais antigos) instructions

Agentes atuais nunca leem instructions, portanto, bloquear apenas isso não protege nada neles: bloqueie conversation_flow, rules e as outras seções que o cliente não deve tocar.

Uma seção bloqueada não pode ser alterada por ninguém conectado como cliente: o próprio login do cliente, os membros da equipe dele, a própria chave de API dele e você também, quando alterna para o painel do cliente a partir da sua conta de agência. A alteração é recusada no agente ativo, em um rascunho não publicado e quando um rascunho é publicado. Para editar uma seção bloqueada você mesmo, use a API com sua chave de agência e sub_account_id, ou desbloqueie-a, faça a alteração e bloqueie-a novamente. Seções que você não bloqueou permanecem totalmente editáveis.

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

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

Apenas as categorias que você enviar serão alteradas: cada uma é mesclada com a configuração atual do cliente, e todas as categorias que você omitir manterão seus valores. Cada categoria em settings aceita enabled (booleano) e até três channels de email, in_app, webhook. Envie null para redefinir para os padrões da plataforma.

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


Pause um cliente que suspendeu a assinatura dele

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

Quando um cliente suspende a assinatura com você, pause a conta dele em vez de excluí-la: tudo o que ele envia para imediatamente — mensagens de saída, transmissões, respostas de IA em todos os canais — e, quando ele faz login, vê um bloqueio de Conta pausada em tela cheia (com sua mensagem opcional) em vez do aplicativo. Nada é excluído ou desconectado: agentes, transmissões, canais conectados, contatos e histórico de chat permanecem exatamente como estão, portanto, retomar a conta coloca o cliente exatamente de onde ele parou — sem necessidade de refazer a configuração.

Campo Obrigatório Descrição
message Não Exibido para o cliente na tela de bloqueio. Deixe em branco para usar o texto padrão.
reason Não Nota interna da agência armazenada com a pausa e no log de auditoria — nunca exibida para o 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 retornar, POST /v1/subaccounts/SUB_ACCOUNT_UID/unpause (sem corpo) remove o bloqueio — o envio de mensagens e as respostas de IA são retomados imediatamente.

Vale a pena saber:

  • É o mesmo estado que a alternância de Bloqueio rígido do painel (Bloqueando / Pausando uma Subconta) — um cliente pausado via API aparece como bloqueado no painel e vice-versa, e despausar limpa um bloqueio colocado de qualquer um dos lados. O estado atual pode ser lido no campo agency_block em GET /v1/subaccounts (level de "none", "soft_blocked" ou "hard_blocked").
  • Ambas as chamadas são idempotentes. Pausar um cliente já pausado apenas atualiza a mensagem, o motivo e o carimbo de data/hora; despausar um cliente ativo não altera nada.
  • O cliente não é notificado por e-mail automaticamente — muitas agências usam white-label, então informar o cliente fica a seu critério.
  • Sua própria cobrança do DM Champ permanece inalterada. Pausar um cliente afeta apenas seu relacionamento com ele.
  • Assistentes de IA também podem fazer isso: o servidor MCP expõe esses endpoints como as ferramentas pause_subaccount e unpause_subaccount no endereço MCP padrão (ferramentas de agência são deixadas de fora de um endereço MCP white-label).

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 via API ao ajuste manual de crédito do painel. Esta é uma alteração de saldo única, distinta das configuraçõ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 subconta por e-mail em vez de sub_account_id.

Campo Obrigatório Descrição
email Sim O e-mail da subconta, conforme existe em sua agência.
amount Sim Número inteiro diferente de zero de créditos, no máximo 100.000 por chamada. Valores positivos adicionam, negativos deduzem.
description Não Exibido junto ao ajuste no histórico de créditos do cliente. O padrão é uma linha genérica “Ajustado pela agência via API”.
idempotency_key Não Qualquer string única (até 255 caracteres, sem espaços) que você escolher para este ajuste. Você pode enviá-la como um cabeçalho Idempotency-Key.

Tentando novamente com segurança. Envie a mesma chave de idempotência ao tentar uma chamada novamente, por exemplo, após um tempo limite, e os créditos serão adicionados ou removidos apenas uma vez. Por 24 horas, uma repetição com a mesma chave e os mesmos detalhes retorna a primeira resposta novamente (com um cabeçalho Idempotent-Replayed: true) em vez de alterar o saldo uma segunda vez. A mesma chave com um e-mail, valor ou descrição diferente é recusada (422), e uma repetição que chega enquanto a primeira chamada ainda está em execução recebe um 409: aguarde um momento e tente novamente. Chamadas sem uma chave funcionam como antes.

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

Resposta

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

Um amount negativo que levaria o saldo abaixo de zero é recusado com 400, informando o saldo disponível e o valor que você tentou deduzir. Se o cliente estiver no modo de revenda, um valor adicionado conta como créditos comprados por ele: é retirado do seu pool de créditos da agência naquele momento, exatamente como uma compra através do seu checkout, e permanece após o próximo reset mensal da mesma forma que uma recarga real. Quando seu pool não consegue cobrir o valor, a chamada é recusada com 402 e nada muda, portanto, recarregue o saldo da sua agência primeiro. Uma dedução em um cliente de revenda remove os créditos apenas do cliente; nada é retornado ao seu pool. Em um cliente com alocação padrão, uma adição é tratada como parte de sua franquia recorrente e não retira nada do seu pool até que o cliente a gaste. De qualquer forma, eles são uma adição única, portanto, um limite de rollover ou uma expiração definida na conta (ou em seu plano) nunca os reduzirá — apenas a franquia recorrente e os créditos do plano estão sujeitos a isso.


Ler as conversas de uma subconta

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

Permite criar uma visualização de monitoramento ou suporte das conversas de um cliente sem precisar fazer login na conta dele. Primeiro, liste os contatos com uma prévia da última mensagem e, em seguida, leia o histórico completo de mensagens de um contato.

Listar contatos

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 Contatos por página. Padrão 25, máximo 50.
lastActivityAt Não Cursor de paginação — passe o lastActivityAt da página anterior para continuar.
searchQuery Não Filtrar por nome ou número de telefone do contato.

Resposta

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

Os contatos são ordenados pela atividade mais recente primeiro. Continue paginando com lastActivityAt enquanto hasMore for true.

Ler mensagens de um contato

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. Padrão 30, máximo 100.
beforeTimestamp Não Cursor de paginação — buscar mensagens mais antigas que este timestamp 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 retornadas da mais recente para a mais antiga; navegue pelo histórico retrocedendo as páginas com beforeTimestamp.


Ler o uso de créditos e a integridade 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 você gerencia, para criar seus próprios relatórios de agência em vez de clicar em cada cliente individualmente.

Uso 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 Omita para um resumo de toda a agência, uma linha por subconta. Inclua para alternar para o modo de detalhes: o resumo daquela subconta mais seus registros de uso brutos e paginados.
limitCount Não Apenas modo de detalhes. Padrão 500, máximo 2000.
startAfterTimestamp Não Apenas modo de detalhes — cursor de paginação.
{
  "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
  }
}

Passe subAccountId e a mesma resposta também trará records: cobranças individuais com amount, reason, campaignName, contactName e timestamp. Um cliente que gasta usando sua própria chave BYOK, em vez dos seus créditos, terá os valores de custo/token ocultos (costsRedacted: true) — isso é telemetria de custo da plataforma, não algo para exibir a um revendedor.

Status 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. Padrã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": "[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
  }
}

Cada linha também contém as contagens de Agentes de IA do cliente (totalAgents, activeAgents, pausedAgents, draftAgents), e o nível superior adiciona totalActiveAgents e totalPausedAgents para a página. Os campos de campanha cobrem apenas campanhas clássicas. hasIssues / issueDetails sinalizam subcontas que merecem atenção. Em uma conta com agentes, eles vêm da pontuação de prontidão dos agentes ativados (por exemplo, "WhatsApp Web is disconnected" ou "Agent \"Front desk\": Routed on a channel that is not connected"); agentes desativados nunca são sinalizados. Em uma conta sem agentes, eles sinalizam campanhas clássicas, como uma pausada. Use isso para criar um painel de verificação de integridade em toda a carteira, em vez de abrir cada cliente para ver quais agentes estão desativados.

Para mensagens de série temporal 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.


Entregue 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, além de sua base de conhecimento, ferramentas e mídia, capturados a partir da sua própria conta. Dois endpoints o colocam no seu fluxo de provisionamento.

Automático — todo novo cliente já nasce com ele. Marque um snapshot como padrão uma vez, e todas as contas que você criar a partir de então chegarão com ele instalado. Isso cobre contas criadas através do POST /v1/subaccounts, contas que você cria no painel e contas criadas automaticamente quando um cliente paga através do seu link de checkout.

Primeiro, encontre o id do snapshot:

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

Em seguida, defina-o como padrão:

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 desativá-lo novamente. Você pode fazer a mesma coisa pelo painel clicando na estrela na página Snapshots.

Para ler o que está marcado como favorito atualmente (digamos, antes de um script de provisionamento decidir se deve definir um), GET /v1/snapshots/default retorna { "success": true, "data": { "default_snapshot_id": "SNAPSHOT_ID" } } — null quando nada está marcado. GET /v1/snapshots (usado para encontrar o id acima) retorna o mesmo default_snapshot_id junto com o array snapshots completo, portanto, a maioria das integrações precisa apenas dessa chamada. Os campos do objeto de instantâneo completo estão no guia Snapshots.

Sob demanda — instale em uma conta específica. Útil para integrar um cliente existente ou para fornecer a um cliente um segundo modelo posteriormente.

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 o sub_account_id e ele será instalado na sua própria conta de agência. Assim 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 sobre isso:

  • Agentes instalados começam pausados. Conecte os canais do cliente primeiro e, em seguida, ative o agente. Isso vale tanto para o caminho automático quanto para o sob demanda.
  • O provisionamento nunca falha por causa de um snapshot. Se a instalação não puder ser concluída, a conta do cliente ainda será criada e poderá ser usada — ela apenas chegará vazia e você poderá aplicar o snapshot posteriormente.
  • Canais, calendários e conexões OAuth nunca são copiados. Cada conta conecta os seus próprios. Ferramentas que usam uma chave de API simples continuam funcionando imediatamente.
  • Aplicar duas vezes cria uma segunda cópia. Nada é sobrescrito.

Crie o próprio modelo via API

POST /v1/snapshots · agentes, funções personalizadas e mídia via API

A seção acima distribui um snapshot criado por alguém no painel. A parte de criação também está exposta, portanto, todo o ciclo — montar a configuração principal uma vez, capturá-la e entregá-la a cada cliente — pode ser executado via código.

As peças, na ordem em que um script de provisionamento as utiliza:

  1. Crie suas funções personalizadas. POST /v1/custom-functions cria uma; GET /v1/custom-functions lista o que você tem, 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 você salvá-la.
  2. Crie e configure o agente. POST /v1/agents o cria, PUT /v1/agents/{agentId} o atualiza, e PATCH /v1/agents/{agentId}/active com { "active": false } o mantém pausado enquanto você trabalha (a mesma chamada com true o coloca em operação). GET /v1/agents os lista.
  3. Dê habilidades ao agente. POST /v1/agents/{agentId}/custom-functions com { "custom_function_id": "..." } anexa uma função ao agente; o DELETE /v1/agents/{agentId}/custom-functions/{customFunctionId} correspondente a remove.
  4. Preencha a biblioteca de mídia. POST /v1/agents/{agentId}/media-library faz o upload de 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 um 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í, segue-se a seção anterior: marque-o como padrão para que cada novo cliente já nasça com ele, ou aplique-o sob demanda. A manutenção é feita da mesma forma: PATCH /v1/snapshots/{snapshotId} com { "name": "..." } renomeia um, DELETE /v1/snapshots/{snapshotId} exclui um (e remove a marcação de padrão, caso estivesse marcado), e GET /v1/snapshots/apply-targets lista todas as contas nas quais você pode realizar a instalação.

Os endpoints de agente, função personalizada e mídia aceitam sub_account_id, portanto, as mesmas chamadas também podem manter um agente diretamente dentro da conta de um cliente. As chamadas de snapshot sempre atuam na sua conta de agência — o modelo permanece com você. Os esquemas completos de solicitação e resposta para todos eles estão na Referência da API.


Gerencie seus níveis de preços via 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 você vende em Modo SaaS → Níveis de Preços podem ser lidos e alterados via código, para que seu próprio painel administrativo ou script de provisionamento possa adicionar um plano, ajustar um preço ou fornecer um link de checkout sem que ninguém precise abrir o painel. Autentique-se com sua chave de API de agência como em qualquer outra chamada nesta página; esses endpoints são de nível de agência, portanto, não utilizam sub_account_id. Toda gravação executa a mesma validação e a mesma sincronização de produto e preço do Stripe que o salvamento no painel, portanto, um plano criado aqui é indistinguível de um que você configurou manualmente.

Liste 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 retorna com seu tierIndex — sua posição na sua lista de Planos, que é como as outras três chamadas o endereçam — e um checkout_url pronto para compartilhar, o mesmo link que a aba Pagamentos fornece, já apontando para o domínio white label no qual o plano é vendido.

Adicione um nível

O corpo é um objeto de nível; ele é anexado ao final 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 traz o nível criado, incluindo o tierIndex no qual ele foi inserido e seu checkout_url.

Edite um nível

Envie apenas os campos que deseja alterar; todo o restante do 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 reconhece é recusado em vez de ignorado, e o erro o nomeia — assim, um erro de digitação nunca pode gravar silenciosamente uma configuração que parece ativa, mas não faz nada. Alterar o preço, os créditos, a moeda ou a periodicidade de cobrança cria um novo preço no seu Stripe; clientes que já assinaram permanecem no que assinaram.

Exclua 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: um plano que ainda possui assinantes ativos não pode ser excluído. A solicitação retorna recusada, informando quantos assinantes estão nele — cancele ou migre-os primeiro. Uma exclusão bem-sucedida responde com seus níveis restantes, já renumerados.

Os campos em um nível

Campo O que é
label / description O nome do plano e a linha opcional exibida na sua página de checkout.
credits Créditos que o cliente recebe por mês em um plano mensal ou anual, e por período de faturamento em um semanal. Um número inteiro de pelo menos 1, ou 0 em um plano cujos features incluem byok (o cliente executa a IA com sua própria chave de API, portanto, o plano não concede créditos e não consome nada do seu pool).
price_cents Preço por intervalo de faturamento, na menor unidade monetária (2900 = $29.00). Em um plano anual, este é o preço do ano inteiro.
currency Código ISO em letras minúsculas — usd, eur, gbp e assim por diante.
billing_interval / billing_interval_count month (o padrão), year, ou week com uma contagem de 1 a 52 para “a cada N semanas”.
trial_days Duração do teste gratuito, de 0 a 90. 0 (ou deixar em branco) significa sem teste.
trial_credits Créditos com os quais o cliente inicia o teste. O padrão é o credits do plano.
trial_card_required false permite que o cliente inicie o teste sem inserir um cartão. O padrão é true.
trial_hard_expiry true devolve créditos de teste não utilizados ao seu pool e bloqueia a conta do cliente quando um teste termina sem uma atualização. O padrão é false — veja Expiração rígida após o teste.
rollover_cap_months Meses de tolerância que clientes neste plano podem acumular entre renovações — um número de 0 a 120, frações permitidas. 0 não acumula nada; null (o padrão) significa sem limite. Veja Limitando o que é acumulado.
rollover_expiry_days Dias após os quais créditos não utilizados são descartados na próxima renovação — um número inteiro de 1 a 3650. null (o padrão) significa que eles nunca expiram.
features / feature_settings O que os clientes neste plano recebem — os mesmos IDs de recurso que Escolha quais tipos de canal um cliente pode conectar.
team_seats_limit Assentos de equipe que o plano concede: um número exato, 0 para nenhum, -1 para ilimitado.
allowed_ai_tiers Modelos de IA que os clientes no plano podem usar, extraídos de standard (Pro), economy, max, mini. Aplicado quando um cliente assina e a cada renovação. null ou [] (o padrão) significa que o plano não gerencia modelos. Um bloqueio definido manualmente em uma subconta com PUT /v1/subaccounts/:uid/ai-tiers nunca é sobrescrito pelo plano.
white_label_config Em qual dos seus domínios white label o plano é vendido.

Os campos de teste só fazem sentido em um plano que possui um teste: salve um nível com trial_days: 0 e eles serão descartados. Os IDs de produto e preço do Stripe do plano são gerenciados para você e não podem ser definidos manualmente.

Três coisas para acertar:

  • Os índices de nível são posições, não IDs permanentes. Excluir um plano desloca todos os planos subsequentes para baixo, portanto, busque a lista novamente após qualquer alteração — e copie novamente os links de checkout que você publicou, exatamente como faria após excluir um plano no painel.
  • O Modo SaaS deve ser configurado primeiro. Esses endpoints precisam de uma conta de agência com white labeling e uma chave Stripe já salva; sem isso, não há conta Stripe para o produto e preço do plano residirem.
  • Vinte planos é o limite, o mesmo que no painel. O campo max_tiers na resposta da lista informa o limite atual.

Os esquemas completos de solicitação e resposta estão na Referência da API, em Agência.


Defina seu preço por crédito via API

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

O preço que os clientes pagam por recargas avulsas (Modo SaaS → Preço por Crédito) também pode ser lido e alterado via código. Isso foi criado para casos em que o preço precisa ser ajustado automaticamente: uma agência que vende créditos em uma moeda, mas cobra em outra, pode permitir que uma tarefa agendada revise o preço conforme a taxa de câmbio muda, em vez de alguém editá-lo manualmente toda semana.

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, portanto, uma tarefa pode verificar um novo preço antes de enviá-lo. 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 deseja alterar. price_per_credit_cents é o preço na menor unidade monetária (130 = R$1,30); currency é um código ISO em letras minúsculas; note é uma linha opcional de até 200 caracteres exibida aos clientes diretamente abaixo do preço por crédito na página de Faturamento — útil para um preço de referência em outra moeda, como “USD 0,25 por crédito à nossa taxa de referência”. Envie "note": "" para removê-la. A resposta tem o mesmo formato da leitura acima, para que uma tarefa possa comparar e pular a gravação quando nada tiver mudado.

As mesmas regras do painel se aplicam: o preço não pode ficar abaixo do mínimo da plataforma para aquela moeda, e a conta precisa de white labeling. Ao contrário dos endpoints de níveis de preço, nenhuma chave do Stripe é necessária para ler ou alterar este valor.

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

Colocar sua chave de agência completa em um agendador concede mais acesso do que uma atualização de preço necessita. Em vez disso, crie uma chave com escopo limitada à á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 — ela não pode acessar subcontas, planos, créditos ou sua conexão com 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 — ela nunca é exibida novamente, portanto, armazene-a imediatamente. Defina "read_only": true para uma chave que precise apenas ler o preço e adicione "expires_at" (uma data ISO) se desejar que ela pare de funcionar automaticamente. Apenas a chave do proprietário da conta pode criar chaves com escopo; liste ou revogue-as com GET /v1/api-keys e DELETE /v1/api-keys/{id}.


Permita que uma subconta leia 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, opcionalmente direcionando um cliente via sub_account_id. Este é o oposto: ele é chamado com a própria chave de API da subconta, sem sub_account_id, para que a página de recarga do próprio cliente (ou uma integração que você crie para ele) possa exibir o que você cobra dele sem nunca ver 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"
  }
}

Isso reflete exatamente o que GET /v1/agency/pricing-tiers e GET /v1/agency/credit-price retornam para você como agência, menos qualquer coisa que o cliente não precise ver (ids do Stripe, max_tiers, etc.). Funciona apenas para uma conta que seja, de fato, uma subconta com uma agência vinculada — chamá-lo de sua própria conta de agência retorna um erro de permissão.


Pontos a considerar

  • Use a chave da sua agência. Autentique cada chamada com a chave de API da conta da sua agência — não a da subconta. O parâmetro sub_account_id é o que redireciona a ação.
  • Os créditos vêm da subconta. Compras e cobranças recorrentes são debitadas do saldo de créditos da subconta alvo, não do seu.
  • Um 404 significa “não é sua subconta”. Verifique novamente o id e se a conta é uma que você gerencia.
  • O parâmetro é opcional onde quer que seja aceito. Omita-o e o mesmo endpoint atuará na conta da sua agência, para que você possa reutilizar uma única integração para ambos.

Relacionado