Endpoints publicos do portal consumidos pelo BrutusForge Client durante o boot/phone-home. Ambos exigem Content-Type: application/json.
POST /api/licenses/activate
Primeira ativacao de licenca. Vincula HWID, retorna JWT Ed25519 assinado. Rate limit: 5 req/min por IP.
Body
{
"licenseKey": "BF-XXXX-XXXX-XXXX-XXXX",
"hwid": "sha256:<hex>",
"instanceId": "<uuid>",
"version": "0.1.0"
}Response 200
{
"token": "<JWT Ed25519>",
"signingKeyId": "ed25519-2026-04-18"
}Erros
403 UNAUTHORIZED— licenca nao existe, HWID diverge ou status invalido403 HWID_MISMATCH— licenca vinculada a outra maquina (use minha conta pra transferir)400— body invalido (Zod)429— rate limit
POST /api/licenses/validate
Phone-home diario. Verifica status remotamente, rotaciona JWT (TTL 1 dia). Rate limit: 30 req/min por IP.
Body
{
"tenantId": "<cuid>",
"token": "<JWT anterior>",
"hwid": "sha256:<hex>"
}Response 200
{
"token": "<JWT renovado>",
"signingKeyId": "ed25519-2026-04-18"
}Erros
403 REVOKED— licenca revogada no portal403 SUSPENDED— licenca suspensa temporariamente403 EXPIRED— passou do vencimento403 HWID_MISMATCH— HWID nao bate
JWT Claims
{
"iss": "brutusforge.io",
"aud": "brutusforge-api",
"sub": "<licenseId>",
"iat": 1234567890,
"exp": 1234654290,
"tier": "L1",
"tenantId": "<cuid>",
"hwid": "sha256:<hex>",
"features": ["*"],
"maxClusters": null,
"buyerEmail": "<email>",
"purchaseId": "<gatewayOrderId>"
}Header inclui kid (key id) pra rotacao futura. Cliente verifica assinatura com LICENSE_SERVER_PUBLIC_KEY (Ed25519 32 bytes base64url).