
# 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](../integrations/api-access.md). Tudo o que lá consta aplica-se também aqui — autentica-se com a chave de API da **sua conta de agência**.

::: note
**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](../integrations/connect-ai-clients.md) 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](sub-accounts.md)) 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`**:

```json
{
  "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](#set-per-client-ai-pricing-and-policy) e os [endpoints de monitorização de chat](#read-a-sub-accounts-conversations) seguem o mesmo padrão.
- **Copiar um Agente entre contas** — `POST /v1/subaccounts/agents/copy` nomeia ambas as contas, assumindo o destino como `targetUserId`. Veja o [exemplo prático](#worked-example-ship-a-template-agent-into-every-new-client) abaixo. (O `POST /v1/subaccounts/campaigns/copy` mais antigo funciona da mesma forma, mas está descontinuado juntamente com o resto da [API de Campanhas](../api/campaigns.md).)
- **Ajustar créditos e os dois rollups de toda a agência** — [`POST /v1/subaccounts/credits`](#grant-or-deduct-credits-directly) identifica a subconta através de `email`; [`GET /v1/subaccounts/credit-usage`](#read-credit-usage-and-campaign-health-across-your-book) 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](#manage-your-pricing-tiers-over-the-api) 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.

::: master-only
<figure><img src="../.gitbook/assets/v2-api-access-key-section.png" alt="Página de definições da Chave de API com chave mascarada e controlo de Regenerar"><figcaption><p>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.</p></figcaption></figure>
:::

***

## 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**

```bash
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**

```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**

```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:**

```json
{
  "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**

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

**JavaScript**

```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**

```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:**

```json
{
  "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 `pending` → `token_received` → `pages_loaded` → `connected`. 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**

```bash
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**

```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**

```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:**

```json
{
  "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):**

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

**Compra (JavaScript):**

```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):**

```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:**

```json
{
  "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`

```bash
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](../api/agents.md#copy-an-agent-into-a-sub-account-agencies).

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.

```bash
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](#set-per-client-ai-pricing-and-policy) 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:

```bash
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](../api/entry-points.md#point-a-channel-at-an-agent) 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.

```bash
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`:

```bash
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**

```bash
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**

```json
{
  "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**

```bash
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**

```json
{
  "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](#turn-tasks-daily-summaries-or-the-media-library-off-for-a-client)).

***

## 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 |

```bash
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.

```bash
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](agency-accounts.md#step-3--set-up-pricing-tiers)), 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](#the-fields-on-a-tier) e [Limitar o que é transportado](sub-accounts.md#capping-what-rolls-over).

***

## 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**

```bash
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`:

```bash
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**

```bash
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](sub-accounts.md#a-holding-reply-while-a-client-is-out-of-credits).

**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:

```bash
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`:

```bash
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](https://skool.com/dm-champions), 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:

```bash
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**

```bash
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**

```bash
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**

```bash
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**

```json
{
  "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](sub-accounts.md#blocking-pausing-a-sub-account)) — 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](../integrations/connect-ai-clients.md) 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`](#set-an-exact-team-member-limit-for-a-client).

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**

```bash
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**

```json
{
  "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**

```bash
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**

```json
{
  "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**

```bash
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**

```json
{
  "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**

```bash
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. |

```json
{
  "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**

```bash
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. |

```json
{
  "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](snapshots.md) é 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:

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

Depois, defina-o como predefinido:

```bash
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](snapshots.md).

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

```bash
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".**

```bash
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](../api/reference.md).

***

## 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

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

**Resposta**

```json
{
  "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](white-labeling.md) em que esse plano é vendido.

### Adicionar um nível

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

```bash
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.

```bash
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

```bash
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](agency-accounts.md#step-3--set-up-pricing-tiers). |
| `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](sub-accounts.md#capping-what-rolls-over). |
| `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](#choose-which-channel-types-a-client-can-connect). |
| `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](white-labeling.md#up-to-three-white-labels) 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](../api/reference.md), 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

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

**Resposta**

```json
{
  "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

```bash
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.

```bash
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.

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

**Resposta**

```json
{
  "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`](#list-your-tiers) e [`GET /v1/agency/credit-price`](#read-the-current-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](../integrations/api-access.md) — autenticação, URL base, erros, limites de taxa.
- [Subcontas](sub-accounts.md) — listar e gerir as contas que pode visar.
- [Recarregamento Automático de Subconta](sub-account-auto-recharge.md) — conceder créditos a uma subconta via webhook + API.
- [API de Campanhas](../api/campaigns.md) — criar, atualizar e copiar campanhas, incluindo a referência completa de campos.
- [API de Ligação de Canais](../api/channels.md) — 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](snapshots.md) — o que um instantâneo captura e como criar um no painel de controlo.
