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

# Fluxo de Ativação

> Como sua instância da Evolution registra uma licença gratuita — endpoints, polling, autenticação HMAC e ciclo de vida.

<Tip>
  Para deploys após o primeiro registro do mesmo e-mail, você pode pular o navegador e usar a [ativação automática por e-mail](/licensing/auto-activation) — uma única chamada de API. O fluxo abaixo continua sendo necessário no **primeiro** registro de um e-mail.
</Tip>

## Visão geral do fluxo

<img src="https://mintcdn.com/evoai-683d737d/kugQZ5jQJNSBV0-D/licensing/images/flow.png?fit=max&auto=format&n=kugQZ5jQJNSBV0-D&q=85&s=6eb462e16e771488065b078f50eb58f6" alt="Diagrama do fluxo de ativação manual: instância chama register/init, exibe URL, operador autentica no navegador, instância faz polling, recebe api_key, ativa via HMAC e segue com heartbeats." width="1536" height="1024" data-path="licensing/images/flow.png" />

A URL base do servidor é definida na variável `LICENSE_BASE_URL` do `.env` do produto (padrão: `https://license.evolutionfoundation.com.br`).

***

## Passo 1 — Iniciar registro

Quando a instância detecta que não há `api_key` salva localmente, ela chama:

```http theme={null}
POST /v1/register/init
Content-Type: application/json

{
  "tier": "community",
  "version": "2.4.0",
  "instance_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Campos:**

| Campo | Tipo | Descrição |
| - | - | - |
| `tier` | string | `community` ou `beta` |
| `version` | string | Versão do produto Evolution (ex.: `2.4.0`) |
| `instance_id` | UUID v4 | Identificador local da instância — gerado uma vez e persistido |

**Resposta (200):**

```json theme={null}
{
  "register_url": "https://license.evolutionfoundation.com.br/register?token=abc123def456...",
  "token": "abc123def456..."
}
```

<Warning>
  O `token` expira em **30 minutos**. Há rate limit de **10 inits por hora por IP**. Se o operador não concluir a ativação no prazo, basta repetir o passo 1.
</Warning>

**Erros possíveis:**

| HTTP | Code | Significado |
| - | - | - |
| 400 | `INVALID_TIER` | tier não é `community` nem `beta` |
| 400 | `INVALID_BODY` | JSON malformado |
| 429 | `RATE_LIMIT` | excedeu 10 inits/hora |

***

## Passo 2 — Exibir a URL ao operador

A instância exibe o `register_url` ao operador. Padrões aceitos:

* **Web UI / Manager** — botão "Ativar Licença" abre o link no navegador
* **Terminal / CLI** — imprime a URL e fica aguardando
* **QR Code** — em deployments headless, gera um QR para escanear

Exemplo de output em CLI:

```
─────────────────────────────────────────────────────────────────
  Ativação de licença Evolution API
─────────────────────────────────────────────────────────────────

  Para ativar, abra no navegador:

  https://license.evolutionfoundation.com.br/register?token=abc123def...

  Aguardando confirmação... (expira em 30 minutos)
─────────────────────────────────────────────────────────────────
```

***

## Passo 3 — O que acontece no navegador

O servidor de licença renderiza a página de registro com a identidade visual da Evolution. O operador escolhe entre:

* **Magic Link** — informa nome e e-mail, recebe link de confirmação por e-mail
* **Google OAuth** — login com conta Google
* **GitHub OAuth** — login com conta GitHub

Após autenticar, o servidor cria (ou recupera) o customer e gera um `authorization_code` interno. Esse fluxo é transparente para a instância — ela só precisa fazer polling.

***

## Passo 4 — Polling do status

Enquanto o operador resolve o login, a instância faz polling:

```http theme={null}
GET /v1/register/status?token=abc123def456...
```

**Resposta enquanto pendente:**

```json theme={null}
{ "status": "pending" }
```

**Resposta quando concluído:**

```json theme={null}
{
  "status": "completed",
  "api_key": "64chars_hex_key...",
  "customer_id": 8,
  "tier": "community"
}
```

**Resposta após expiração:**

```json theme={null}
{ "status": "expired" }
```

**Recomendações de implementação:**

* Intervalo de polling entre **3 e 5 segundos** (não mais rápido)
* Timeout total de 30 minutos
* Quando receber `completed`, persistir `api_key` em local seguro (config criptografada, secret manager, etc.)

***

## Passo 5 — Ativar a instância

Com a `api_key` em mãos, a instância chama o endpoint de ativação:

```http theme={null}
POST /v1/activate
Content-Type: application/json
X-API-Key: 64chars_hex_key...
X-Signature: <HMAC-SHA256 do body usando a api_key>

{
  "instance_id": "550e8400-e29b-41d4-a716-446655440000",
  "version": "2.4.0"
}
```

**Resposta:**

```json theme={null}
{
  "status": "active",
  "tier": "community",
  "instance_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

<Note>
  A geolocalização (`operator_country`, `operator_city`) é **detectada automaticamente** pelo IP da request. A instância não precisa enviar essa informação.
</Note>

***

## Passo 6 — Heartbeat periódico

Após ativação, a instância envia heartbeats a cada **5 minutos**:

```http theme={null}
POST /v1/heartbeat
Content-Type: application/json
X-API-Key: 64chars_hex_key...
X-Signature: <HMAC-SHA256 do body>

{
  "instance_id": "550e8400-e29b-41d4-a716-446655440000",
  "telemetry_bundle": {
    "messages_sent": 1500,
    "features": ["chatbot", "broadcast", "webhook"]
  }
}
```

O campo `telemetry_bundle` é JSON livre. Os campos extraídos automaticamente pelo servidor são detalhados em [Telemetria](/licensing/telemetry).

***

## Passo 7 — Desativação (opcional)

Em shutdown gracioso (uninstall, container stop intencional), recomenda-se:

```http theme={null}
POST /v1/deactivate
Content-Type: application/json
X-API-Key: 64chars_hex_key...
X-Signature: <HMAC-SHA256 do body>

{
  "instance_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

Isso libera a contagem da instância no licenciamento. Não é obrigatório — o servidor expira instâncias inativas automaticamente após 7 dias sem heartbeat.

***

## Autenticação HMAC

Todas as chamadas para `/v1/activate`, `/v1/heartbeat` e `/v1/deactivate` exigem o header `X-Signature` com HMAC-SHA256 do body.

**Algoritmo:**

1. Serializar o body em JSON
2. Calcular `HMAC-SHA256(body, api_key)`
3. Converter para hexadecimal
4. Enviar no header `X-Signature`

<Warning>
  O body usado no HMAC deve ser **byte-a-byte idêntico** ao enviado. Não reformate o JSON entre o cálculo da assinatura e o envio.
</Warning>

### Exemplo Python

```python theme={null}
import hmac, hashlib, json, requests

api_key = "64chars_hex..."
payload = {
    "instance_id": "550e8400-e29b-41d4-a716-446655440000",
    "version": "2.4.0",
}
body = json.dumps(payload, separators=(",", ":"))
sig = hmac.new(api_key.encode(), body.encode(), hashlib.sha256).hexdigest()

requests.post(
    "https://license.evolutionfoundation.com.br/v1/activate",
    data=body,
    headers={
        "Content-Type": "application/json",
        "X-API-Key": api_key,
        "X-Signature": sig,
    },
)
```

### Exemplo Node.js

```javascript theme={null}
const crypto = require('crypto');

const apiKey = '64chars_hex...';
const payload = {
  instance_id: '550e8400-e29b-41d4-a716-446655440000',
  version: '2.4.0',
};
const body = JSON.stringify(payload);
const sig = crypto.createHmac('sha256', apiKey).update(body).digest('hex');

await fetch('https://license.evolutionfoundation.com.br/v1/activate', {
  method: 'POST',
  body,
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': apiKey,
    'X-Signature': sig,
  },
});
```

### Exemplo Go

```go theme={null}
package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
)

func sign(body []byte, apiKey string) string {
    mac := hmac.New(sha256.New, []byte(apiKey))
    mac.Write(body)
    return hex.EncodeToString(mac.Sum(nil))
}
```

***

## Códigos de erro

| HTTP | Code | Causa | Ação recomendada |
| - | - | - | - |
| 401 | `HMAC_INVALID` | Assinatura incorreta | Verificar serialização do body |
| 401 | `INVALID_API_KEY` | Key mal formatada | Confirmar uso da hex de 64 chars |
| 403 | `KEY_SUSPENDED` | Key suspensa por abuso | Contatar suporte |
| 403 | `INSTANCE_LIMIT` | Limite de instâncias atingido | Solicitar aumento |
| 404 | `INSTANCE_NOT_FOUND` | Heartbeat sem ativação prévia | Rodar `/v1/activate` primeiro |
| 410 | `TOKEN_EXPIRED` | Token de 30min expirou | Repetir `/v1/register/init` |
| 429 | `RATE_LIMIT` | Excedeu rate limit | Backoff exponencial |

***

## Checklist de integração

Para quem está implementando a ativação em um fork ou produto derivado:

* [ ] Gerar e persistir `instance_id` (UUID v4) na primeira execução
* [ ] Implementar `POST /v1/register/init` quando não houver `api_key`
* [ ] Exibir `register_url` ao operador (UI, terminal ou QR)
* [ ] Polling `GET /v1/register/status` a cada 3–5s
* [ ] Persistir `api_key` em local seguro (não em texto plano)
* [ ] Implementar cálculo HMAC-SHA256 para todas as chamadas assinadas
* [ ] `POST /v1/activate` na inicialização do serviço
* [ ] `POST /v1/heartbeat` a cada 5min com `messages_sent` + `features`
* [ ] `POST /v1/deactivate` em shutdown gracioso
* [ ] Tratar erros (token expirado, key suspensa, limite de instâncias)
* [ ] Backoff exponencial em falhas transitórias de rede

***

## Modo offline e degradação

Se o servidor de licença estiver inacessível:

* A instância **continua funcionando normalmente**
* Heartbeats falham silenciosamente (sem quebrar a aplicação)
* Após reconexão, o próximo heartbeat retoma o ciclo

A ativação inicial (passo 1–5) é a única etapa que **exige conectividade**. Depois disso, a instância tolera períodos offline.

Veja [FAQ — modo offline](/licensing/faq#modo-offline) para mais detalhes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.