Pular para o conteúdo

API Reference

A API do x17 segue o padrão REST usando Next.js App Router API Routes. Todas as rotas estão em src/app/api/.

Base URL: /api/*

A maioria das rotas exige autenticação via Supabase session cookie. O helper getAuthContext() (em src/lib/api/auth.ts) extrai userId, accountId e role do request.

interface AuthContext {
userId: string
accountId: string
role: string // "owner" | "admin" | "member" | "viewer"
}

Rotas administrativas usam getAdminContext() (em src/lib/api/admin-auth.ts), que valida se o email do usuário está na lista PLATFORM_ADMIN_EMAILS (env var).

Roles disponíveis: owner, admin, member, viewer. O helper requireRole(ctx, ["owner", "admin"]) lança AuthError se o role não for permitido.

Todas as rotas usam o wrapper withErrorHandling() (em src/lib/api/response.ts) que captura exceções e retorna respostas padronizadas via formatApiError().

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Dados inválidos",
"details": {}
}
}
CódigoHTTP StatusDescrição
AUTH_ERROR401Não autenticado ou sem permissão
NOT_FOUND404Recurso não encontrado
VALIDATION_ERROR422Dados inválidos (inclui erros Zod)
WHATSAPP_ERROR502Erro na API do WhatsApp/Meta
VPS_ERROR502Erro na VPS (AI proxy)
RATE_LIMIT429Limite de requisições excedido
INTERNAL_ERROR500Erro não mapeado
  • AppError(message, code, statusCode, details) — erro base
  • AuthError(message?) — 401
  • NotFoundError(resource) — 404
  • ValidationError(message, details?) — 422
  • WhatsAppError(message, details?) — 502
  • VPSError(message, details?) — 502

Implementado com Upstash Redis sliding window (src/lib/api/rate-limit.ts). Fail-open: se Redis estiver indisponível, o request e permitido.

PresetLimiteJanela
webhook1001 minuto
api301 minuto
auth51 minuto
callback201 minuto
ai201 hora
send601 minuto
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1708000000000
Retry-After: 60

Fire-and-forget via logAudit() (em src/lib/api/audit.ts). Usa createAdminClient() para bypass RLS. Nunca bloqueia a resposta.

logAudit({
accountId: string,
userId?: string,
action: "create" | "update" | "delete" | "restore" | "login" | "export",
entityType: string,
entityId?: string,
changes?: Record<string, unknown>,
ip?: string,
})

Tabela: audit_logs.

  • success(data, status=200){ data: T } com status 200
  • created(data){ data: T } com status 201
  • noContent() — status 204, sem body
  • error(err) — formata erro via formatApiError()
GET /api/resource?page=1&limit=20

Resposta:

{
"data": {
"data": [...],
"total": 100,
"page": 1,
"totalPages": 5
}
}
GET /api/resource?cursor=uuid&limit=20

Resposta:

{
"data": {
"data": [...],
"nextCursor": "uuid-or-null"
}
}
  • JSON em todas as respostas
  • Body de request em JSON (exceto uploads que usam FormData)
  • IDs são UUIDs
  • Timestamps em ISO 8601
  • Soft delete: campo deleted_at (RLS filtra automaticamente)
  • Multi-tenant: todas as queries scoped por account_id
  • Zod para validação de input em todas as rotas de escrita
ArquivoRotasDescrição
admin9Painel administrativo da plataforma
ai5Chat IA, sugestoes, geração de fluxo e copy
analytics14Métricas, dashboards, exportação, RFM
automations12CRUD automações, steps, execuções, blueprints
billing10Planos, assinaturas, pagamentos (ASAAS), brand context
auth6Contas, auth, API keys, audit logs