17. Administração (Superadmin)#
Rotas exclusivas para administradores da plataforma.
GET/v1/admin/system#
Informações do sistema.
Auth: Superadmin
Resposta 200:
{
"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:
{
"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:
{
"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:
{
"company_id": 1,
"status": "suspended"
}
POST/v1/admin/companies/{companyId}/unsuspend#
Reativa uma empresa suspensa.
Auth: Superadmin
Resposta 200:
{
"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:
{
"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:
{
"instance_id": "84c2e480-...",
"disconnected": true
}
POST/v1/admin/instances#
Cria uma nova instância para qualquer empresa.
Auth: Superadmin
Request:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
# 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:
{
"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:
{
"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:
[
{
"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:
{
"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:
{
"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:
{
"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_rawcontem o corpo completo enviado ao webhook. So disponível para entregas falhadas (deliveries com sucesso tempayload_rawlimpo 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:
{
"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):
{
"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:
{
"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_nameeinstance_namesão enriquecidos a partir das tabelascompaniesetenant_instances. Se o webhook não está filtrado por instância,instance_ideinstance_nameficam 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:
{
"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:
{
"webhook_id": 21,
"event_type": "message.received",
"max_retries": 20
}
Todos os campos são opcionais.
webhook_ideevent_typefiltram quais falhas reenviar;max_retrieslimita o lote (default 20, max 100).
Resposta 200:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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.workertrazreachable/error— quando o worker está inacessível via RPC,reachableefalsee 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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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):
{
"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:
{
"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:
{
"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:
{
"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/instancese.../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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"instance_id": "84c2e480-..."
}
| Campo | Tipo | Obrigatório | Descricao |
|---|---|---|---|
instance_id |
string | sim | ID da instância |
Resposta 200:
{
"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:
{
"instance_id": "84c2e480-..."
}
| Campo | Tipo | Obrigatório | Descricao |
|---|---|---|---|
instance_id |
string | sim | ID da instância |
Resposta 200:
{
"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:
{
"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_scoreparte de 100 e sofre deducoes por instâncias offline, mensagens falhadas e falhas de webhook nas últimas 24h.risk_factorslista 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:
{
"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:
{
"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:
{
"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_idOUscope=all— o endpoint retorna400se nenhum dos dois for enviado.
Resposta 200:
{
"revoked": 18
}
GET /v1/admin/security/config-check#
Auditoria de configuração de seguranca da plataforma.
Auth: Superadmin
Resposta 200:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"evaluated": 2,
"triggered": 1
}
GET /v1/admin/alerts/rules#
Lista as regras de alerta configuradas.
Auth: Superadmin
Resposta 200:
{
"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:
{
"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):
{
"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:
{
"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
summarytraz sempre as 8 tiers (healthy,stale,degraded,offline,critical_offline,intentional,pending,banned), comcount=0quando vazias. Instâncias offline trazemoffline_duration_secondseoffline_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.