Administração (Superadmin)

17. Administração (Superadmin)#

Rotas exclusivas para administradores da plataforma.

GET/v1/admin/system#

Informações do sistema.

Auth: Superadmin

Resposta 200:

json
{
  "uptime_seconds": 86400,
  "goroutines": 42,
  "memory": {
    "alloc_mb": 128,
    "sys_mb": 256,
    "gc_cycles": 50,
    "heap_objects": 100000,
    "heap_inuse_mb": 100
  },
  "go_version": "go1.25.0",
  "num_cpu": 4
}

GET/v1/admin/companies#

Lista todas as empresas da plataforma.

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
page int 1 Página
limit int 20 Itens por página (max 100)

Resposta 200:

json
{
  "data": [
    {
      "id": 1,
      "name": "Minha Empresa",
      "status": "active",
      "created_at": "2026-03-01T00:00:00Z"
    }
  ],
  "total": 10,
  "page": 1,
  "limit": 20
}

GET/v1/admin/companies/{companyId}/stats#

Estatísticas de uma empresa.

Auth: Superadmin

Resposta 200:

json
{
  "company_id": 1,
  "name": "Minha Empresa",
  "status": "active",
  "instances": 3,
  "messages": 15000,
  "webhooks": 2
}

POST/v1/admin/companies/{companyId}/suspend#

Suspende uma empresa. Todos os acessos são bloqueados.

Auth: Superadmin

Resposta 200:

json
{
  "company_id": 1,
  "status": "suspended"
}

POST/v1/admin/companies/{companyId}/unsuspend#

Reativa uma empresa suspensa.

Auth: Superadmin

Resposta 200:

json
{
  "company_id": 1,
  "status": "active"
}

GET/v1/admin/instances#

Lista todas as instâncias de todas as empresas.

Auth: Superadmin

Observação: sem rate limit adicional no grupo admin; a protecao e feita por autenticação JWT + RequireSuperadmin().

Query Parameters:

Parametro Tipo Padrão Descricao
page int 1 Página
limit int 20 Itens por página (max 100)

Resposta 200:

json
{
  "data": [
    {
      "company_id": 1,
      "instance": { "id": "84c2e480-...", "name": "...", "status": "CONNECTED" }
    }
  ],
  "total": 25,
  "page": 1,
  "limit": 20
}

POST/v1/admin/instances/{instanceId}/disconnect#

Forca a desconexao de uma instância.

Auth: Superadmin

Resposta 200:

json
{
  "instance_id": "84c2e480-...",
  "disconnected": true
}

POST/v1/admin/instances#

Cria uma nova instância para qualquer empresa.

Auth: Superadmin

Request:

json
{
  "company_id": 14,
  "name": "Nova instancia"
}

Resposta 201: Objeto de instância criado.


POST/v1/admin/instances/{instanceId}/connect#

Conecta uma instância (gera QR code).

Auth: Superadmin

Resposta 200: Objeto de instância com qr_base64 se disponível.


POST/v1/admin/instances/{instanceId}/restart#

Desconecta e reconecta uma instância, gerando nova sessão QR.

Auth: Superadmin

Resposta 200: Objeto de instância com qr_base64 se disponível.


POST/v1/admin/instances/{instanceId}/logout#

Faz logout e apaga a sessão. Requer novo pareamento.

Auth: Superadmin

Resposta 200: Objeto de instância atualizado.


DELETE/v1/admin/instances/{instanceId}#

Remove uma instância permanentemente.

Auth: Superadmin

Resposta 204: Sem corpo.


GET/v1/admin/instances/{instanceId}/qr#

Retorna o QR code atual de qualquer instância.

Auth: Superadmin

Resposta 200: Mesmo formato de GET /v1/instances/{instanceId}/qr.


GET/v1/admin/instances/{instanceId}/qr/stream#

Stream SSE de QR codes de qualquer instância. Mesmo formato de GET /v1/instances/{instanceId}/qr/stream.

Auth: Superadmin


POST/v1/admin/instances/{instanceId}/pairing-code#

Gera código de pareamento para qualquer instância. Mesmo formato de POST /v1/instances/{instanceId}/pairing-code.

Auth: Superadmin


GET/v1/admin/queue#

Estatísticas globais de todas as filas.

Auth: Superadmin

Resposta 200:

json
{
  "queues": [
    {
      "name": "default",
      "size": 100,
      "pending": 5,
      "active": 1,
      "completed": 90,
      "failed": 2,
      "scheduled": 1,
      "retry": 1
    }
  ]
}

GET/v1/admin/queue/archived#

Lista tasks que falharam permanentemente (DLQ — Dead Letter Queue).

Auth: Superadmin

Query params:

  • queue — Nome da fila (default: default)
  • limit — Max items retornados (default: 25, max: 100)

Resposta 200:

json
{
  "queue": "default",
  "count": 2,
  "archived": [
    {
      "id": "task_abc123",
      "type": "msg:send_text",
      "queue": "default",
      "max_retry": 3,
      "retried": 3,
      "last_failed_at": "2026-03-22T10:30:00Z",
      "last_err": "send failed: not connected",
      "instance_id": "84c2e480-...",
      "company_id": 1
    }
  ]
}

GET/v1/admin/logs/files#

Lista arquivos de log disponíveis no diretorio configurado.

Auth: Superadmin

Resposta 200:

json
{
  "dir": "./data/logs",
  "files": [
    { "name": "biazap.log", "size": 9371 },
    { "name": "biazap-2026-03-21.log.gz", "size": 2048 }
  ]
}

GET/v1/admin/logs#

Retorna linhas filtradas de um arquivo de log (tail com filtros).

Auth: Superadmin

Query params:

Param Default Descricao
file biazap.log Nome do arquivo (sem path)
limit 200 Max linhas retornadas (max 5000)
skip 0 Pular N linhas do final
level Filtrar por level (error, warn, info, debug)
contains Busca texto livre em qualquer campo
instance_id Filtrar por instance_id
trace_id Filtrar pela trace_id exata (cole do console card)
error_code Filtrar pelo error_code exato

Resposta 200:

json
{
  "file": "biazap.log",
  "total": 1234,
  "showing": 10,
  "skip": 0,
  "limit": 10,
  "lines": [
    "{\"level\":\"info\",\"time\":\"2026-03-22T13:41:48Z\",\"message\":\"text message sent\"}"
  ]
}

Exemplos de uso:

bash
# Ultimas 50 linhas
GET /v1/admin/logs?limit=50

# Apenas erros
GET /v1/admin/logs?level=error&limit=100

# Filtrar por instancia
GET /v1/admin/logs?instance_id=84c2e480-xxxx&limit=200

# Busca texto livre
GET /v1/admin/logs?contains=rate+limited&limit=50

POST/v1/admin/broadcast#

Envia uma notificação para todos os webhooks ativos da plataforma.

Auth: Superadmin

Request:

json
{
  "message": "Manutencao programada para hoje as 22h",
  "type": "system.broadcast"
}
Campo Tipo Obrigatório Descricao
message string sim Conteúdo da notificação
type string não Tipo do evento. Padrão: system.broadcast

Resposta 200:

json
{
  "broadcast": true,
  "webhooks_notified": 15
}

GET/v1/admin/tokens#

Lista todos os tokens ativos da plataforma.

Auth: Superadmin

Query Parameters:

Parametro Tipo Descricao
company_id int Filtrar por empresa (opcional)

Resposta 200:

json
[
  {
    "id": 15,
    "company_id": 14,
    "company_name": "EJ ESTETICA",
    "label": "producao",
    "last4": "f4eb",
    "role": "owner",
    "created_at": "2026-03-07T23:42:37Z"
  }
]

POST/v1/admin/tokens#

Cria um token de API para qualquer empresa.

Auth: Superadmin

Request:

json
{
  "company_id": 14,
  "label": "integracao-v2",
  "role": "owner"
}
Campo Tipo Obrigatório Descricao
company_id int sim ID da empresa
label string sim Nome identificador
role string não owner, admin, agent. Padrão: owner

Resposta 201:

json
{
  "token_id": 16,
  "token": "ctc_xxxx...xxxx",
  "label": "integracao-v2",
  "role": "owner",
  "last4": "xxxx",
  "company_id": 14,
  "created_at": "2026-03-30T14:00:00Z"
}

Importante: O token so e exibido uma vez. Salve-o em local seguro.


DELETE/v1/admin/tokens/{tokenId}#

Revoga qualquer token da plataforma.

Auth: Superadmin

Resposta 204: Sem corpo.


GET/v1/admin/webhooks/{webhookId}/logs#

Lista delivery logs de qualquer webhook.

Auth: Superadmin

Query Parameters:

Parametro Tipo Descricao
page int Página (default: 1)
limit int Itens por página (default: 50, max: 100)
success string Filtrar: true ou false

Resposta 200:

json
{
  "data": [
    {
      "id": 123,
      "webhook_id": 12,
      "event_id": "evt-uuid",
      "event_type": "message.delivered",
      "payload": "{}",
      "payload_raw": "{\"event_type\":\"message.delivered\",...}",
      "status_code": 500,
      "response": "{\"success\":false,\"error\":\"...\"}",
      "attempt": 1,
      "success": false,
      "created_at": "2026-03-30T15:42:01Z"
    }
  ],
  "total": 27,
  "page": 1,
  "limit": 50
}

Nota: O campo payload_raw contem o corpo completo enviado ao webhook. So disponível para entregas falhadas (deliveries com sucesso tem payload_raw limpo após 48h pelo cleanup).


GET/v1/admin/webhooks#

Lista todos os webhooks da plataforma com enriquecimento de empresa e instância.

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
page int 1 Página
limit int 20 Itens por página (max 100)

Resposta 200:

json
{
  "data": [
    {
      "id": 12,
      "url": "https://example.com/webhook",
      "events": "message.received,message.sent",
      "active": true,
      "instance_id": "",
      "instance_name": "",
      "company_id": 14,
      "company_name": "EJ ESTETICA",
      "created_at": "2026-03-07T10:00:00Z",
      "updated_at": "2026-03-07T10:00:00Z"
    }
  ],
  "total": 10,
  "page": 1,
  "limit": 20
}

GET/v1/admin/webhooks/{webhookId}#

Retorna um webhook por ID.

Auth: Superadmin

Resposta 200: Mesmo formato do item acima.


PATCH/v1/admin/webhooks/{webhookId}#

Atualiza campos de qualquer webhook.

Auth: Superadmin

Request (todos opcionais):

json
{
  "url": "https://novo-endpoint.com/webhook",
  "events": "message.received",
  "active": true,
  "instance_id": "84c2e480-..."
}

Resposta 200: Webhook atualizado.


DELETE/v1/admin/webhooks/{webhookId}#

Remove qualquer webhook.

Auth: Superadmin

Resposta 204: Sem corpo.


GET/v1/admin/webhooks/metrics#

Metricas de saúde por webhook (entregas, falhas, taxa de sucesso) em uma janela de tempo.

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
hours int 24 Janela de tempo em horas

Resposta 200:

json
{
  "period_hours": 2,
  "webhooks": [
    {
      "webhook_id": 21,
      "url": "https://example.com/webhook",
      "company_id": 14,
      "company_name": "EJ ESTETICA",
      "instance_id": "84c2e480-...",
      "instance_name": "EJ Whats",
      "total": 37,
      "successes": 37,
      "failures": 0,
      "success_rate": 100
    }
  ]
}

company_name e instance_name são enriquecidos a partir das tabelas companies e tenant_instances. Se o webhook não está filtrado por instância, instance_id e instance_name ficam vazios.


GET/v1/admin/delivery-logs#

Lista delivery logs de todos os webhooks da plataforma com paginação e filtros.

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
page int 1 Página
limit int 50 Itens por página (max 100)
success bool - Filtrar por sucesso/falha
event_type string - Filtrar por tipo de evento
since string - Filtrar desde data (RFC3339)
webhook_id int - Filtrar por webhook ID

Resposta 200:

json
{
  "data": [
    {
      "id": 1234,
      "webhook_id": 21,
      "event_id": "3c726dc7-...",
      "event_type": "message.received",
      "payload": "{}",
      "payload_raw": "{\"event_type\":\"message.received\",...}",
      "status_code": 200,
      "response": "{\"success\":true}",
      "attempt": 1,
      "success": true,
      "created_at": "2026-04-12T17:00:00Z",
      "webhook_url": "https://example.com/webhook",
      "company_name": "EJ ESTETICA",
      "company_id": 14
    }
  ],
  "total": 85,
  "page": 1,
  "limit": 50
}

POST/v1/admin/webhooks/retry-batch#

Reenvia entregas falhadas em lote, selecionadas por filtro.

Auth: Superadmin

Request:

json
{
  "webhook_id": 21,
  "event_type": "message.received",
  "max_retries": 20
}

Todos os campos são opcionais. webhook_id e event_type filtram quais falhas reenviar; max_retries limita o lote (default 20, max 100).

Resposta 200:

json
{
  "retried": 3
}

GET/v1/admin/instances/{instanceId}/diagnostics#

Snapshot profundo de uma instância: estado de pareamento, perfil de fingerprint, binding de proxy e catalogo de versão do app. Campos densos e voltados a infraestrutura — mantidos fora do DTO público de GET /v1/instances por design.

Auth: Superadmin

Resposta 200:

json
{
  "instance_id": "84c2e480-...",
  "company_id": 14,
  "name": "EJ Whats",
  "pairing": {
    "status": "CONNECTED",
    "desired_state": "CONNECTED",
    "meta_paired_at": "2026-04-20T10:00:00Z",
    "last_seen": "2026-04-23T13:22:22Z"
  },
  "fingerprint": {
    "profile_id": 3,
    "platform": "android",
    "manufacturer": "Samsung",
    "device": "SM-M546B",
    "os_version": "14",
    "mcc": "724",
    "mnc": "11",
    "locale": "pt_BR",
    "country": "BR",
    "ddd": "11",
    "timezone": "America/Sao_Paulo",
    "utls_spec": "safari-mac-17"
  },
  "proxy": {
    "id": 11,
    "ip_address": "200.239.204.138",
    "city": "br-saopaulo",
    "zone": "isp_br",
    "last_health_ok": true
  },
  "catalog": {
    "app_version": "2.3000.1034566421"
  }
}

Erros: 400 BAD_REQUEST (instanceId vazio), 404 INSTANCE_NOT_FOUND (instância inexistente em qualquer tenant DB ativo), 401 UNAUTHORIZED, 500, 503.


GET/v1/admin/companies/{companyId}/autopilot#

Retorna a instância de autopilot configurada para a empresa (ou null).

Auth: Superadmin

Resposta 200:

json
{
  "company_id": 14,
  "instance_id": "84c2e480-..."
}

instance_id vem null quando a empresa não tem autopilot configurado.


PATCH/v1/admin/companies/{companyId}/autopilot#

Define (ou limpa) a instância de autopilot da empresa.

Auth: Superadmin

Request:

json
{
  "instance_id": "84c2e480-..."
}
Campo Tipo Obrigatório Descricao
instance_id string | null sim ID da instância. null ou "" limpa o autopilot. Um valor não vazio e validado contra o tenant DB da empresa.

Resposta 200:

json
{
  "company_id": 14,
  "instance_id": "84c2e480-..."
}

Erros: 400 INVALID_JSON (corpo inválido), 400 MISSING_FIELD (instance_id ausente — use ""/null para limpar), 400 INSTANCE_NOT_FOUND (a instância não pertence a está empresa), 404 NOT_FOUND (empresa inexistente), 500, 503.


GET/v1/admin/event-deliveries#

Lista delivery logs agrupados por event_id. Mesma resposta de GET /v1/event-deliveries (ver seção 15), porém sem restrição de empresa — abrange toda a plataforma.

Auth: Superadmin


POST/v1/admin/users/set-password#

Substitui diretamente a senha de um usuário. Bypass operacional do fluxo de reset por email.

Auth: Superadmin

Request:

json
{
  "email": "owner@empresa.com",
  "password": "NovaSenhaForte123"
}
Campo Tipo Obrigatório Descricao
email string sim Email do usuário alvo
password string sim Nova senha (mínimo 12 caracteres)

Resposta 204: Sem corpo.

Erros: 400 (JSON inválido, campos ausentes ou senha com menos de 12 caracteres), 404 (usuário não encontrado), 500.

Trocar a senha inválida todos os JWTs e refresh tokens vigentes do usuário (claim pwd_changed_at).


GET/v1/admin/whatsmeow-health#

Metricas de saúde do whatsmeow/AppState da frota: totais de sync, contagem de recoveries e erros de decrypt.

Auth: Superadmin

Resposta 200:

json
{
  "appstate_sync_total": 1240,
  "appstate_sync_success": 1218,
  "appstate_sync_recovery": 18,
  "appstate_sync_failed": 4,
  "decrypt_errors": 2
}

O payload e o mapa retornado por observability.WhatsmeowHealthStats(). Alimenta os cards "Erros WhatsApp" e "Recoveries AppState" no dashboard superadmin.


GET/v1/admin/infrastructure#

Snapshot detalhado de runtime dos dois processos (api + worker), recursos compartilhados e metricas por instância.

Auth: Superadmin

Resposta 200:

json
{
  "processes": {
    "api": {
      "uptime_seconds": 86400,
      "goroutines": 64,
      "memory": { "alloc_mb": 128, "sys_mb": 256 },
      "num_cpu": 4
    },
    "worker": {
      "reachable": true,
      "error": "",
      "uptime_seconds": 86200,
      "goroutines": 312,
      "memory": { "alloc_mb": 480, "sys_mb": 720 }
    }
  },
  "shared": {
    "mysql": { "ok": true, "latency_ms": 3 },
    "redis": { "ok": true, "latency_ms": 1 },
    "disk": { "total_gb": 80, "used_gb": 22, "free_gb": 58 },
    "queue": { "default": { "pending": 5, "active": 1 } }
  },
  "instances": [
    {
      "instance_id": "84c2e480-...",
      "company_id": 14,
      "status": "CONNECTED",
      "proxy_ip": "200.239.204.138",
      "bytes_in": 1048576,
      "bytes_out": 524288
    }
  ],
  "summary": {
    "total_instances": 25,
    "connected": 23
  }
}

O bloco processes.worker traz reachable/error — quando o worker está inacessível via RPC, reachable e false e os demais campos do worker ficam vazios. O payload também repete campos legados de topo (system, process, memory, database, disk) por compatibilidade.


NOC / Command Center#

Endpoints de painel operacional (Network Operations Center) para o console superadmin.

GET /v1/admin/noc/uptime#

Disponibilidade agregada da plataforma e de cada dependencia.

Auth: Superadmin

Resposta 200:

json
{
  "overall": "healthy",
  "services": {
    "api": "up",
    "mysql": "up",
    "redis": "up",
    "worker": "up",
    "s3": "up"
  }
}

GET /v1/admin/noc/latency#

Latencias observadas e ponteiro para o Prometheus.

Auth: Superadmin

Resposta 200:

json
{
  "metrics": {
    "mysql_p50_ms": 3,
    "redis_p50_ms": 1
  },
  "prometheus_url": "http://localhost:9090",
  "uptime_seconds": 86400
}

GET /v1/admin/noc/errors#

Erros recentes da plataforma agregados para o painel NOC.

Auth: Superadmin

Resposta 200:

json
{
  "errors": [],
  "note": "Erros agregados das ultimas horas."
}

POST/v1/admin/instances/{instanceId}/temperature/backfill#

Dispara o backfill assincrono dos contadores de temperatura de contato da instância. Endpoint superadmin — documentado em detalhe na seção 11 (Contatos), POST /v1/admin/instances/{instanceId}/temperature/backfill. Retorna 202 {status:"queued", task_id}.

Auth: Superadmin


Incidents (operacional)#

CRUD de incidentes operacionais (tabela incidents no master DB). Distinto do endpoint público de incident-recorder GET /v1/monitoring/errors/{id} (seção 16).

GET /v1/admin/incidents#

Lista incidentes operacionais.

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
status string Filtrar por status (open, mitigated, resolved)
page int 1 Página
limit int 20 Itens por página

Resposta 200:

json
{
  "data": [
    {
      "id": 7,
      "title": "Latencia elevada no envio",
      "severity": "P2",
      "status": "open",
      "impact": "...",
      "owner": "noc@catcher.one",
      "created_at": "2026-04-23T13:00:00Z"
    }
  ],
  "total": 3,
  "page": 1,
  "limit": 20
}

POST /v1/admin/incidents#

Cria um incidente operacional.

Auth: Superadmin

Request:

json
{
  "title": "Latencia elevada no envio",
  "severity": "P2",
  "impact": "Envios atrasados para parte da frota",
  "owner": "noc@catcher.one",
  "runbook_ref": "RUNBOOK-12"
}
Campo Tipo Obrigatório Descricao
title string sim Titulo do incidente
severity string não P1, P2, P3, P4. Padrão: P2
impact string não Descricao do impacto
owner string não Responsável
runbook_ref string não Referência ao runbook

Resposta 201: Incidente criado.

PATCH /v1/admin/incidents/{incidentId}#

Atualiza um incidente. Mudar status para mitigated ou resolved carimba automaticamente mitigated_at / resolved_at.

Auth: Superadmin

Request (todos opcionais):

json
{
  "status": "mitigated",
  "impact": "...",
  "root_cause": "...",
  "timeline": "...",
  "owner": "noc@catcher.one"
}

Resposta 200: Incidente atualizado. 404 se o incidente não existe.

GET /v1/admin/incidents/active#

Retorna o incidente ativo de maior severidade (se houver).

Auth: Superadmin

Resposta 200:

json
{
  "active": true,
  "incident": {
    "id": 7,
    "title": "Latencia elevada no envio",
    "severity": "P2",
    "status": "open"
  }
}

active e false e incident e null quando não ha incidente em aberto.


GET/v1/admin/connectivity/metrics#

Visão geral de conectividade da frota.

Auth: Superadmin

Resposta 200:

json
{
  "total_instances": 42,
  "connected": 38,
  "disconnected": 3,
  "banned": 1,
  "connectivity_rate": 90.48,
  "flapping": [
    { "instance_id": "84c2e480-...", "name": "EJ Whats", "disconnects": 6 }
  ],
  "banned_instances": [
    { "instance_id": "f35157b4-...", "name": "Catcher", "ban_expiry": "2026-04-24T00:00:00Z" }
  ]
}

GET/v1/admin/connectivity/qr-diagnostics#

Instâncias presas em pareamento (QR pendente / conectando).

Auth: Superadmin

Resposta 200:

json
{
  "qr_pending": 2,
  "connecting": 1,
  "waiting_for_qr": [
    {
      "instance_id": "84c2e480-...",
      "name": "Nova instancia",
      "status": "QR_PENDING",
      "waiting_seconds": 320
    }
  ]
}

A superficie por instância (/v1/admin/connectivity/instances e .../instances/{id}/timeline) está documentada na seção 17.AA.


Delivery Reliability#

Endpoints de confiabilidade de entrega de mensagens para o console superadmin.

GET /v1/admin/delivery/funnel#

Funil de entrega (KPIs: enfileiradas -> enviadas -> entregues -> lidas).

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
company_id int Limita a uma empresa
instance_id string Limita a uma instância
hours int 24 Janela de tempo em horas

Resposta 200:

json
{
  "period_hours": 24,
  "queued": 1200,
  "sent": 1180,
  "delivered": 1150,
  "read": 980,
  "failed": 20
}

GET /v1/admin/delivery/failures#

Falhas de entrega agrupadas por causa.

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
hours int 24 Janela de tempo em horas

Resposta 200:

json
{
  "period_hours": 24,
  "failures": [
    { "reason": "not connected", "count": 12 },
    { "reason": "rate limited", "count": 8 }
  ]
}

POST /v1/admin/delivery/retry-batch#

Reenfileira mensagens falhadas da DLQ em lote.

Auth: Superadmin

Request:

json
{
  "company_id": 14,
  "instance_id": "84c2e480-...",
  "max_retries": 50
}
Campo Tipo Obrigatório Descricao
company_id int não Limita a uma empresa
instance_id string não Limita a uma instância
max_retries int não Máximo de tasks reenfileiradas

Resposta 200:

json
{
  "retried": 12
}

Queue & Throughput#

Controle de fila por instância (distinto dos endpoints por instância em /v1/instances/{id}/queue/*).

GET /v1/admin/queue/per-tenant#

Profundidade de fila agregada por instância.

Auth: Superadmin

Resposta 200:

json
{
  "instances": [
    {
      "instance_id": "84c2e480-...",
      "company_id": 14,
      "pending": 5,
      "active": 1,
      "failed": 0
    }
  ],
  "total": 25
}

POST /v1/admin/queue/pause#

Pausa a fila de envio de uma instância.

Auth: Superadmin

Request:

json
{
  "instance_id": "84c2e480-..."
}
Campo Tipo Obrigatório Descricao
instance_id string sim ID da instância

Resposta 200:

json
{
  "instance_id": "84c2e480-...",
  "paused": true
}

Erros: 400 (instance_id ausente), 503 (throttler indisponível).

POST /v1/admin/queue/resume#

Retoma a fila de envio de uma instância.

Auth: Superadmin

Request:

json
{
  "instance_id": "84c2e480-..."
}
Campo Tipo Obrigatório Descricao
instance_id string sim ID da instância

Resposta 200:

json
{
  "instance_id": "84c2e480-...",
  "resumed": true
}

Erros: 400 (instance_id ausente), 503 (throttler indisponível).


GET/v1/admin/tenants/health#

Health score 0-100 por tenant, com fatores de risco.

Auth: Superadmin

Resposta 200:

json
{
  "tenants": [
    {
      "company_id": 14,
      "name": "EJ ESTETICA",
      "status": "active",
      "health_score": 92,
      "instances": 3,
      "connected": 3,
      "messages_sent_24h": 1180,
      "failed_msgs_24h": 20,
      "webhook_fails_24h": 2,
      "risk_factors": ["webhook_failures"]
    }
  ],
  "total": 10
}

health_score parte de 100 e sofre deducoes por instâncias offline, mensagens falhadas e falhas de webhook nas últimas 24h. risk_factors lista as deducoes aplicadas.


Security & Compliance#

Endpoints de seguranca/compliance para o console superadmin.

GET /v1/admin/audit#

Lista o log de auditoria da plataforma.

Auth: Superadmin

Query Parameters:

Parametro Tipo Padrão Descricao
action string Filtrar por ação auditada
page int 1 Página
limit int 20 Itens por página

Resposta 200:

json
{
  "data": [
    {
      "id": 100,
      "action": "company.suspend",
      "actor": "admin@catcher.one",
      "created_at": "2026-04-23T13:00:00Z"
    }
  ],
  "total": 50,
  "page": 1,
  "limit": 20
}

GET /v1/admin/sessions#

Sessões ativas (tokens) por usuário.

Auth: Superadmin

Resposta 200:

json
{
  "users": [
    {
      "user_id": 5,
      "email": "owner@empresa.com",
      "company_id": 14,
      "active_tokens": 2
    }
  ],
  "total_users": 12,
  "active_tokens": 30
}

POST /v1/admin/sessions/revoke#

Revoga tokens em massa, por empresa ou globalmente.

Auth: Superadmin

Request:

json
{
  "company_id": 14,
  "scope": "all"
}
Campo Tipo Obrigatório Descricao
company_id int condicional Limita a revogacao a uma empresa
scope string condicional all revoga toda a plataforma

E obrigatório informar company_id OU scope=all — o endpoint retorna 400 se nenhum dos dois for enviado.

Resposta 200:

json
{
  "revoked": 18
}

GET /v1/admin/security/config-check#

Auditoria de configuração de seguranca da plataforma.

Auth: Superadmin

Resposta 200:

json
{
  "overall": "ok",
  "checks": [
    { "name": "jwt_secret_length", "status": "ok" },
    { "name": "cors_origins", "status": "ok" }
  ]
}

Data Integrity#

Verificação e reconciliacao de integridade de dados por tenant.

GET /v1/admin/integrity/check#

Detecta inconsistencias de dados por tenant.

Auth: Superadmin

Resposta 200:

json
{
  "tenants": [
    {
      "company_id": 14,
      "name": "EJ ESTETICA",
      "orphaned_media": 0,
      "incomplete_status": 1,
      "scheduled_stuck": 0
    }
  ],
  "checked": 10
}

POST /v1/admin/integrity/reconcile#

Corrige as inconsistencias detectadas. Suporta dry-run.

Auth: Superadmin

Request:

json
{
  "company_id": 14,
  "dry_run": true
}
Campo Tipo Obrigatório Descricao
company_id int não Limita a uma empresa
dry_run bool não Quando true, apenas lista o que seria corrigido

Resposta 200:

json
{
  "dry_run": true,
  "fixes": [
    { "company_id": 14, "type": "incomplete_status", "count": 1 }
  ]
}

Finance / Ops#

Metricas financeiras e de capacidade da plataforma.

GET /v1/admin/finance/costs#

Volume de mensagens e mídia por tenant.

Auth: Superadmin

Resposta 200:

json
{
  "tenants": [
    {
      "company_id": 14,
      "name": "EJ ESTETICA",
      "messages": 15000,
      "media": 1200
    }
  ],
  "total": 10
}

GET /v1/admin/finance/capacity#

Capacidade e crescimento da plataforma.

Auth: Superadmin

Resposta 200:

json
{
  "companies": 10,
  "instances": 25,
  "messages_7d": 84000,
  "messages_30d": 320000,
  "daily_avg_7d": 12000,
  "daily_avg_30d": 10666,
  "growth_rate_pct": 12.5
}

Alerting#

Regras de alerta (CRUD), lista de alertas disparados e avaliacao manual.

GET /v1/admin/alerts#

Lista os alertas disparados.

Auth: Superadmin

Query Parameters:

Parametro Tipo Descricao
status string Filtrar por status
severity string Filtrar por severidade

Resposta 200:

json
{
  "data": [
    {
      "id": 30,
      "rule": "InstancesOfflineHigh",
      "metric": "instances_offline_count",
      "value": 5,
      "severity": "warning",
      "status": "firing",
      "created_at": "2026-04-23T13:00:00Z"
    }
  ]
}

POST /v1/admin/alerts/evaluate#

Forca a avaliacao imediata de todas as regras de alerta.

Auth: Superadmin

Resposta 200:

json
{
  "evaluated": 2,
  "triggered": 1
}

GET /v1/admin/alerts/rules#

Lista as regras de alerta configuradas.

Auth: Superadmin

Resposta 200:

json
{
  "rules": [
    {
      "id": 1,
      "name": "InstancesOfflineHigh",
      "metric": "instances_offline_count",
      "operator": ">",
      "threshold": 3,
      "severity": "warning",
      "enabled": true
    }
  ]
}

POST /v1/admin/alerts/rules#

Cria uma regra de alerta.

Auth: Superadmin

Request:

json
{
  "name": "QueueDepthHigh",
  "metric": "queue_depth",
  "operator": ">",
  "threshold": 500,
  "severity": "warning",
  "enabled": true
}
Campo Tipo Obrigatório Descricao
name string sim Nome único da regra
metric string sim Metrica avaliada (ver lista abaixo)
operator string sim Operador de comparacao (>, <, >=, <=, ==)
threshold number não Limiar de disparo
severity string não Severidade do alerta
enabled bool não Se a regra está ativa

Metricas suportadas: queue_depth, queue_failed, webhook_failures, active_instances, instances_offline_count, instances_critical_offline_count.

Resposta 201: Regra criada. 409 se já existe uma regra com o mesmo name.

PATCH /v1/admin/alerts/rules/{ruleId}#

Atualiza uma regra de alerta.

Auth: Superadmin

Request (todos opcionais):

json
{
  "threshold": 600,
  "severity": "critical",
  "enabled": false,
  "operator": ">="
}

Resposta 200: Regra atualizada. 404 se a regra não existe.

DELETE /v1/admin/alerts/rules/{ruleId}#

Remove uma regra de alerta.

Auth: Superadmin

Resposta 204: Sem corpo. 404 se a regra não existe.


GET/v1/admin/instance-health#

Rollup de saúde das instâncias por tier. Endpoint canonico consumido pela função health.EvaluateTier.

Auth: Superadmin

Resposta 200:

json
{
  "generated_at": "2026-04-23T13:30:00Z",
  "total": 25,
  "summary": {
    "healthy": { "count": 20, "examples": ["84c2e480-..."] },
    "stale": { "count": 1, "examples": ["..."] },
    "degraded": { "count": 1, "examples": ["..."] },
    "offline": { "count": 2, "examples": ["..."] },
    "critical_offline": { "count": 0, "examples": [] },
    "intentional": { "count": 1, "examples": ["..."] },
    "pending": { "count": 0, "examples": [] },
    "banned": { "count": 0, "examples": [] }
  },
  "instances": [
    {
      "instance_id": "84c2e480-...",
      "company_id": 14,
      "name": "EJ Whats",
      "tier": "offline",
      "status": "DISCONNECTED",
      "offline_duration_seconds": 1320,
      "offline_duration_human": "22m"
    }
  ]
}

O bloco summary traz sempre as 8 tiers (healthy, stale, degraded, offline, critical_offline, intentional, pending, banned), com count=0 quando vazias. Instâncias offline trazem offline_duration_seconds e offline_duration_human.



Nota: Os endpoints do Security Dashboard (/v1/admin/security/dashboard, /threats, /ip-reputation, /hackers) foram removidos. A deteccao de ameacas agora e gerenciada pela biblioteca compartilhada Sentinel (github.com/ronszcka/sentinel), que possui sua própria interface de administração.