API REST
Versionada em /api/v1/licensing. A especificação OpenAPI é gerada a partir do código.
Envelope de resposta
// Sucesso
{ "ok": true, "data": { ... } }
// Falha
{ "ok": false, "error": { "code": "license_expired", "message": "Licença expirada.", "details": { ... } } }Decida pelo code, não pelo status HTTP
code é contrato e nunca muda; a message é texto para humano e pode mudar a qualquer momento.Autenticação
| Grupo | Como autentica | Quem chama |
|---|---|---|
| Cliente | A própria chave de licença, no corpo | O SDK, do servidor do comprador |
| Comprador | Cookie de sessão | O painel, no navegador |
| Desenvolvedor | Authorization: Bearer lsk_live_… | O seu servidor, ou o painel |
| Chaves públicas | nenhuma | Qualquer um |
Escopos de chave de API
| Escopo | Permite |
|---|---|
plugins:read | Ler plugins |
plugins:write | Criar e alterar plugins |
licenses:read | Ler licenças |
licenses:write | Emitir, revogar e suspender licenças |
Chave de API nunca entra em um .jar
Explorador
As rotas abertas podem ser executadas daqui. As autenticadas vêm com o curl pronto para o seu terminal.
/api/v1/licensing/.well-known/keyssem credencialAberto. É daqui que o SDK baixa as chaves com que verifica as assinaturas. Execute agora mesmo.
curl https://179.66.142.109/api/v1/licensing/.well-known/keysEndpoints
Cliente — chamados pelo SDK
| Método | Caminho | O que faz |
|---|---|---|
| POST | /licenses/activate | Registra a instalação, consome vaga, devolve a primeira autorização. |
| POST | /licenses/validate | Renova uma instalação já ativa. Não cria instalação. |
| POST | /licenses/heartbeat | Sinal de vida. Só assina quando a sessão está perto de vencer. |
| POST | /licenses/deactivate | Libera a instalação a partir do servidor. |
| GET | /.well-known/keys | Chaves públicas de verificação. Aberto. |
Comprador — sessão
| Método | Caminho | O que faz |
|---|---|---|
| GET | /licenses/me | Licenças da conta autenticada. |
| GET | /licenses/:id | Detalhe de uma licença própria. |
| GET | /licenses/:id/installations | Instalações da licença. |
| POST | /licenses/:id/reset-installation | Desvincula uma instalação, liberando a vaga. |
Desenvolvedor — chave de API ou sessão
| Método | Caminho | Escopo |
|---|---|---|
| GET | /developer/plugins | plugins:read |
| POST | /developer/plugins | plugins:write |
| GET | /developer/plugins/:id | plugins:read |
| PATCH | /developer/plugins/:id | plugins:write |
| GET | /developer/plugins/:id/licenses | licenses:read |
| POST | /developer/licenses | licenses:write |
| POST | /developer/licenses/:id/revoke | licenses:write |
| POST | /developer/licenses/:id/suspend | licenses:write |
| POST | /developer/licenses/:id/reactivate | licenses:write |
Autorização é por recurso
Ter credencial válida não é permissão. Toda leitura e toda escrita carregam o recurso com o sellerId do contexto dentro da consulta — não carregam e depois comparam.
Um identificador de outro vendedor simplesmente não encontra linha, e a resposta é 404, não 403: dizer “existe, mas não é seu” confirmaria a existência do recurso alheio.
Paginação
GET /developer/plugins?page=2&pageSize=50&status=ACTIVE&q=aurum{
"ok": true,
"data": {
"items": [ ... ],
"page": 2,
"pageSize": 50,
"total": 137,
"totalPages": 3
}
}pageSize tem teto de 100. Sem teto, um cliente pede tudo e derruba a consulta.
Rate limits
| Rota | Por IP | Por chave |
|---|---|---|
| activate | 60 / 15 min | 20 / 15 min |
| validate | 300 / 15 min | 120 / 15 min |
| heartbeat | 600 / 15 min | — |
| deactivate | 60 / 15 min | — |
| developer (leitura) | 600 / 15 min | 600 / 15 min |
| developer (escrita) | 120 / 15 min | 120 / 15 min |
O limite por chave é o que importa de verdade. Uma chave legítima ativa uma vez por servidor por boot; vinte tentativas em quinze minutos com a mesma chave é redistribuição ou laço de erro.
Ao estourar, a resposta é 429 com Retry-After em segundos. O SDK já respeita esse cabeçalho.
Versionamento
- O caminho carrega a versão:
/api/v1/licensing. Uma v2 coexistiria com a v1 enquanto houvesse cliente usando. - O protocolo de autorização tem versão própria, dentro do documento assinado. O prefixo
LSA1entra na assinatura, então um documento da versão 1 nunca pode ser reapresentado como de uma versão futura. - Acrescentar campo à resposta não é mudança de versão. Remover campo, mudar significado ou mudar código de erro, sim.
- Toda resposta leva
X-Licensing-Version.
OpenAPI
A especificação completa está em /api/v1/licensing/openapi. Ela é gerada: os códigos de erro, os escopos e os eventos de webhook são importados dos módulos que os definem, então acrescentar um código de erro o faz aparecer na especificação sozinho.
# Gerar um cliente a partir da especificação
npx @openapitools/openapi-generator-cli generate \
-i https://179.66.142.109/api/v1/licensing/openapi \
-g typescript-fetch \
-o ./lodestone-client