> ## Documentation Index
> Fetch the complete documentation index at: https://ajuda.pandazap.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API de Administração de Tenants: Provisionamento Multi-empresa

> Provisione tenants (contas de empresa), crie canais e integrações de API, e configure o modo híbrido WABA/não-oficial via API de administração do PanÐá Zap.

A **Tenant API** é uma API de nível plataforma, separada da API externa por `ApiID` usada no restante desta referência. Ela existe para quem opera o PanÐá Zap em modo **white-label/multi-empresa** e precisa criar e administrar contas de clientes (tenants) programaticamente — por exemplo, a partir de um sistema próprio de vendas ou onboarding automatizado.

<Warning>
  Esta API usa uma **URL base diferente** (sem o prefixo `/v2/api/external/{ApiID}/`) e, para o endpoint de atualização de tenant, exige um **`SuperAdminToken`** em vez do Bearer Token padrão de uma integração comum. Não utilize estes endpoints com o token de uma integração de cliente regular.
</Warning>

***

## Listar tenants

```http theme={null}
GET https://{BaseUrl}/tenantApiListTenants
```

***

## Exibir tenant

```http theme={null}
POST https://{BaseUrl}/tenantApiShowTenant
```

```json theme={null}
{ "id": 1 }
```

| Campo | Tipo    | Obrigatório | Descrição                 |
| ----- | ------- | ----------- | ------------------------- |
| `id`  | integer | Sim         | ID do tenant a consultar. |

***

## Criar tenant

Provisiona uma nova conta de empresa (tenant), incluindo o usuário administrador inicial e, opcionalmente, um plano e um gateway de pagamento.

```http theme={null}
POST https://{BaseUrl}/tenantApiStoreTenant
```

```json theme={null}
{
  "status": "active",
  "name": "Empresa Exemplo",
  "maxUsers": 3,
  "maxConnections": 3,
  "acceptTerms": true,
  "email": "user@example.com",
  "password": "securePassword123!",
  "userName": "Pedro Bastos",
  "profile": "admin",
  "planId": 1,
  "paymentGateway": "stripe",
  "stripeCustomerId": "cus_XXXXXXXXXXXXXX",
  "stripeToken": "sk_live_XXXXXXXXXXXXXXXX"
}
```

| Campo                                    | Tipo    | Obrigatório | Descrição                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------- | ------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`                                 | string  | Sim         | `active` ou `inactive`.                                                                                                                                                                                                                                                                                   |
| `name`                                   | string  | Sim         | Nome da empresa/tenant.                                                                                                                                                                                                                                                                                   |
| `maxUsers`                               | integer | Sim         | Número máximo de usuários permitidos (ignorado se `planId` for informado).                                                                                                                                                                                                                                |
| `maxConnections`                         | integer | Sim         | Número máximo de conexões WhatsApp permitidas (ignorado se `planId` for informado).                                                                                                                                                                                                                       |
| `acceptTerms`                            | boolean | Sim         | Confirmação de aceite dos termos de uso.                                                                                                                                                                                                                                                                  |
| `email`                                  | string  | Sim         | E-mail do usuário administrador do tenant.                                                                                                                                                                                                                                                                |
| `password`                               | string  | Sim         | Senha do administrador (mínimo 8 caracteres, com números e caracteres especiais).                                                                                                                                                                                                                         |
| `userName`                               | string  | Sim         | Nome completo do administrador.                                                                                                                                                                                                                                                                           |
| `profile`                                | string  | Sim         | Perfil do administrador — `admin` ou `user`.                                                                                                                                                                                                                                                              |
| `planId`                                 | integer | Não         | ID de um plano cadastrado em Planos. Quando informado, os limites e recursos do plano prevalecem sobre `maxUsers`/`maxConnections`. Um ID inexistente retorna erro `400` e nada é criado. Sem este campo, o tenant nasce sem plano.                                                                       |
| `paymentGateway`                         | string  | Não         | Gateway de pagamento vinculado — `asaas`, `stripe`, `pagarme` ou `mercadopago`. Define qual gateway atualiza automaticamente o status de pagamento do tenant via webhook.                                                                                                                                 |
| `<gateway>CustomerId` / `<gateway>Token` | string  | Não\*       | Credenciais do gateway escolhido — envie apenas o par correspondente. Exemplos: `stripeCustomerId`+`stripeToken`, `pagarmeCustomerId`+`pagarmeToken`, `mercadopagoCustomerId`+`mercadopagoToken`, `asaasCustomerId`+`asaasToken`(+`asaas: "enabled"`). Obrigatório quando `paymentGateway` for informado. |

***

## Atualizar tenant

Atualiza um tenant existente, identificado pelo CPF/CNPJ. Requer `SuperAdminToken`.

```http theme={null}
POST https://{BaseUrl}/tenantApiUpdateTenant
```

```json theme={null}
{
  "identity": "07122989674",
  "status": "active",
  "maxUsers": 100,
  "maxConnections": 10,
  "paymentGateway": "asaas",
  "supportChatEnabled": "enabled",
  "menuVisibility": ["Groups", "MassDispatch", "Kanban", "Tasks", "Api", "ChatBot", "Reports", "Campaigns", "PrivateChat", "Teams", "AllowedChannels"],
  "allowedChannels": ["waba", "baileys", "whatsapp", "telegram", "webchat", "webmail"],
  "channelConnectionLimits": {
    "waba": 0,
    "baileys": 0,
    "telegram": 0
  },
  "oauthEnabled": false
}
```

| Campo                                                      | Tipo      | Obrigatório | Descrição                                                                                                                                                                                                                                                                                                                                   |
| ---------------------------------------------------------- | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `identity`                                                 | string    | Sim         | CPF/CNPJ usado para identificar o tenant a atualizar.                                                                                                                                                                                                                                                                                       |
| `status`                                                   | string    | Não         | `active` ou `inactive`.                                                                                                                                                                                                                                                                                                                     |
| `maxUsers`                                                 | integer   | Não         | Novo limite de usuários.                                                                                                                                                                                                                                                                                                                    |
| `maxConnections`                                           | integer   | Não         | Novo limite de conexões.                                                                                                                                                                                                                                                                                                                    |
| `paymentGateway`                                           | string    | Não         | `none`, `asaas`, `mercadopago`, `stripe` ou `pagarme`. Trocar para um gateway diferente de Asaas desliga automaticamente o modo Asaas legado.                                                                                                                                                                                               |
| `<gateway>CustomerId` / `<gateway>Token`                   | string    | Não         | Credenciais do gateway informado — mesmo padrão de [Criar tenant](#criar-tenant).                                                                                                                                                                                                                                                           |
| `supportChatEnabled`                                       | string    | Não         | `enabled` ou `disabled`.                                                                                                                                                                                                                                                                                                                    |
| `menuVisibility`                                           | string\[] | Não         | Menus visíveis para o tenant. Opções: `Groups`, `MassDispatch`, `Kanban`, `Tasks`, `Api`, `ChatBot`, `Reports`, `Campaigns`, `PrivateChat`, `Teams`, `AllowedChannels`.                                                                                                                                                                     |
| `allowedChannels`                                          | string\[] | Não         | Canais habilitados para o tenant. Opções: `waba`, `baileys`, `whatsapp`, `meow`, `evo`, `evogo`, `zapi`, `uazapi`, `zapo`, `telegram`, `hub`, `webchat`, `mercadolivre`, `olx`, `linkedin`, `youtube`, `tiktok`, `woocommerce`, `nuvemshop`, `webmail`, `email`, `waba_oauth`, `dialog360`, `gupshup`, `instagram_oauth`, `facebook_oauth`. |
| `channelConnectionLimits`                                  | object    | Não         | Limite máximo de conexões por tipo de canal. Use `0` para ilimitado. `waba` e `waba_oauth` contam como o mesmo tipo real (a chave `waba` vence quando ambas vierem); `hub` cobre todos os canais do Hub.                                                                                                                                    |
| `oauthEnabled`                                             | boolean   | Não         | Habilita o fluxo OAuth (Meta Embedded Signup) para este tenant.                                                                                                                                                                                                                                                                             |
| `oauthProxyUrl`                                            | string    | Não         | URL do proxy OAuth.                                                                                                                                                                                                                                                                                                                         |
| `instagramWebhookProxyUrl` / `instagramWebhookProxySecret` | string    | Não         | URL e segredo do proxy de webhook do Instagram.                                                                                                                                                                                                                                                                                             |
| `messengerWebhookProxyUrl` / `messengerWebhookProxySecret` | string    | Não         | URL e segredo do proxy de webhook do Messenger.                                                                                                                                                                                                                                                                                             |

<Note>
  Nomes de canal em `allowedChannels` e `channelConnectionLimits`: os canais oficiais por login usam sublinhado (`waba_oauth`, `instagram_oauth`, `facebook_oauth`).
</Note>

***

## Criar integração de API para um tenant

```http theme={null}
POST https://{BaseUrl}/tenantCreateApi
```

```json theme={null}
{
  "name": "API 1",
  "sessionId": 1,
  "urlServiceStatus": null,
  "urlMessageStatus": null,
  "userId": 1,
  "authToken": "123456",
  "tenant": 1
}
```

| Campo              | Tipo           | Obrigatório | Descrição                                                |
| ------------------ | -------------- | ----------- | -------------------------------------------------------- |
| `name`             | string         | Sim         | Nome de exibição da integração de API.                   |
| `sessionId`        | integer        | Sim         | ID da sessão (canal WhatsApp) associada.                 |
| `urlServiceStatus` | string \| null | Não         | URL para receber atualizações de status do serviço.      |
| `urlMessageStatus` | string \| null | Não         | URL para receber atualizações de status das mensagens.   |
| `userId`           | integer        | Sim         | ID do usuário que está criando a integração.             |
| `authToken`        | string         | Sim         | Token de autenticação (Bearer Token) da nova integração. |
| `tenant`           | integer        | Sim         | ID do tenant proprietário da integração.                 |

***

## Excluir integração de API

```http theme={null}
POST https://{BaseUrl}/tenantDeleteApi
```

```json theme={null}
{
  "sessionId": 43,
  "userId": 1,
  "tenant": 1,
  "apiId": "5ec32c80-4549-4256-8ed1-ed57b86396c3"
}
```

| Campo       | Tipo    | Obrigatório | Descrição                                      |
| ----------- | ------- | ----------- | ---------------------------------------------- |
| `sessionId` | integer | Sim         | ID da sessão associada à API.                  |
| `userId`    | integer | Sim         | ID do usuário que está excluindo a API.        |
| `tenant`    | integer | Sim         | ID do tenant proprietário da API.              |
| `apiId`     | string  | Sim         | ID (UUID) da integração de API a ser excluída. |

***

## Criar canal (sessão) para um tenant

Cria um canal no tenant informado e, automaticamente, uma integração de API apontando para ele. A resposta traz `{ whatsapp, api }`.

```http theme={null}
POST https://{BaseUrl}/tenantApiCreateSession
```

```json theme={null}
{
  "tenant": 1,
  "name": "My WhatsApp Instance",
  "status": "DISCONNECTED",
  "type": "baileys"
}
```

| Campo    | Tipo    | Obrigatório | Descrição                                                                          |
| -------- | ------- | ----------- | ---------------------------------------------------------------------------------- |
| `tenant` | integer | Sim         | ID do tenant que receberá o canal.                                                 |
| `name`   | string  | Sim         | Nome da instância do WhatsApp.                                                     |
| `status` | string  | Não         | Status inicial — `DISCONNECTED` ou `CONNECTED`.                                    |
| `type`   | string  | Sim         | Tipo da sessão — `whatsapp`, `baileys`, `zapo`, `meow`, `evo`, `uazapi` ou `zapi`. |

### Modo Híbrido (WABA + Não Oficial)

A mesma rota aceita campos adicionais para gravar um **vínculo híbrido** entre um canal WABA oficial e um canal não oficial, permitindo que o tráfego de sessão (dentro da janela de 24h) seja desviado para o canal não oficial enquanto templates e campanhas continuam pela API oficial.

O sentido depende de qual canal está sendo criado nesta chamada:

1. **Criando o canal WABA** (`type: "waba"`): envie `hybridMode` e `linkedChannelId` (ID do canal não oficial já existente que vira o “transporte”).
2. **Criando o canal NÃO OFICIAL** (`baileys`, `whatsapp`, `zapo`, `meow`, `evo`, `evogo`, `zapi`, `uazapi`): envie `linkToWhatsappId` com o ID do canal WABA já existente, que passa a apontar para o canal recém-criado. Aqui `hybridMode` é opcional — sem ele, o vínculo é gravado mas o desvio continua desligado.

```json theme={null}
{
  "tenant": 1,
  "name": "WABA Principal",
  "type": "waba",
  "tokenAPI": "123456789012345",
  "wabaId": "987654321098765",
  "bmToken": "EAAxxxxxxxxxxxx",
  "hybridMode": "coexistence",
  "linkedChannelId": 12
}
```

| Campo              | Tipo    | Obrigatório | Descrição                                                                                                                                                                                                                                 |
| ------------------ | ------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tokenAPI`         | string  | Sim\*       | `phone_number_id` (somente dígitos). Obrigatório ao criar canal `waba`.                                                                                                                                                                   |
| `wabaId`           | string  | Sim\*       | WABA ID da Meta. Obrigatório ao criar canal `waba`.                                                                                                                                                                                       |
| `bmToken`          | string  | Sim\*       | Token do Business Manager. Obrigatório ao criar canal `waba`.                                                                                                                                                                             |
| `hybridMode`       | string  | Não         | `disabled` (padrão, nada muda), `two_numbers` (handoff entre dois números) ou `coexistence` (mesmo número — mensagens dentro da janela de 24h saem pelo canal vinculado; templates, campanhas e fora da janela continuam na API oficial). |
| `linkedChannelId`  | integer | Não         | ID do canal não oficial já existente que vira transporte. Usado ao criar o canal WABA.                                                                                                                                                    |
| `linkToWhatsappId` | integer | Não         | ID do canal WABA já existente a apontar para este canal. Usado ao criar o canal não oficial (sentido inverso de `linkedChannelId`).                                                                                                       |

**Resposta com bloco `hybrid`:**

```json theme={null}
{
  "success": true,
  "data": {
    "whatsapp": { ... },
    "api": { ... },
    "hybrid": {
      "applied": true,
      "whatsappId": 8,
      "hybridMode": "coexistence",
      "linkedChannelId": 12
    }
  }
}
```

Se a validação do vínculo falhar, **o canal e a API continuam sendo criados** e a resposta traz `{ "applied": false, "error": "ERR_..." }` — corrija depois com `PUT /whatsapp/{whatsappId}`.

| Código em `hybrid.error`                 | Significado                                                      |
| ---------------------------------------- | ---------------------------------------------------------------- |
| `ERR_HYBRID_INVALID_MODE`                | Valor de `hybridMode` inválido.                                  |
| `ERR_HYBRID_ONLY_WABA`                   | `hybridMode` diferente de `disabled` em um canal que não é WABA. |
| `ERR_HYBRID_LINKED_SELF`                 | O canal tentou se vincular a si mesmo.                           |
| `ERR_HYBRID_LINKED_NOT_FOUND`            | ID inexistente ou pertencente a outro tenant.                    |
| `ERR_HYBRID_LINKED_IN_USE`               | O canal vinculado já está em outro vínculo (a relação é 1:1).    |
| `ERR_HYBRID_COEXISTENCE_REQUIRES_LINKED` | Modo `coexistence` exige um `linkedChannelId` válido.            |
| `ERR_HYBRID_COEXISTENCE_LINKED_TYPE`     | O canal de transporte não está na whitelist de tipos suportados. |
| `ERR_HYBRID_INVALID_ID_LINK_TO`          | `linkToWhatsappId` inválido.                                     |
| `ERR_HYBRID_INVALID_ID_LINKED_CHANNEL`   | `linkedChannelId` inválido.                                      |
| `ERR_NO_WAPP_FOUND`                      | Canal não encontrado.                                            |

<Warning>
  A flag híbrida não substitui o onboarding oficial. O modo `coexistence` só desvia mensagens de fato se o número WABA foi onboardado em coexistência (fluxo de 2 QRs) e o canal vinculado estiver `CONNECTED`; fora disso, o envio segue pela API oficial (fail-open, sem erro). No envio pela API externa, o desvio por mensagem ainda exige `routeVia: "auto"`.
</Warning>

***

## Resposta Padrão

```json theme={null}
{
  "success": true,
  "data": { ... }
}
```
