POST /oauth/register. Issuer: https://api.notifique.dev.
A tela de login e consentimento fica no painel Notifique. Seu app só abre a URL de autorização no browser e trata o callback — você não constrói UI de consentimento.
Tipos de cliente
PKCE é sempre obrigatório — mesmo em clientes confidenciais.
Caminhos recomendados
Antes de codar, decida:-
Registro fixo vs DCR
- Pré-registrado (painel ou
POST /oauth/registeruma vez) — apps web e integrações conhecidas. - DCR em runtime — MCP hosts e CLIs que não sabem redirect/porta antes de rodar.
- Pré-registrado (painel ou
-
Remoto vs local
- Remoto — redirect
https://seuapp.com/oauth/callback, backend guardastateecode_verifierna sessão. - Local — loopback
http://127.0.0.1:<porta>/callback, servidor temporário na máquina do usuário.
- Remoto — redirect
Escopos
Peça o mínimo no registro e no authorize. Escopos omitidos no DCR podem ser interpretados de forma ampla — declare explicitamente. Exemplos Notifique:- Só e-mail:
email:send - WhatsApp:
whatsapp:send - Vários:
email:send contacts:read(separados por espaço, URL-encoded na query)
Encoding e endpoints
Cliente confidencial autentica token/revoke com HTTP Basic (
client_id:client_secret), não repita client_id no body se usar -u.
Metadados: GET /.well-known/oauth-authorization-server (RFC 8414).
Gerar PKCE e state
Antes do authorize, gere três valores:code_verifier— string aleatória de alta entropia; fica só no cliente até o token.code_challenge—BASE64URL(SHA256(code_verifier)).state— aleatório; deve voltar igual no callback (proteção CSRF).
state e codeVerifier na sessão do usuário antes do redirect.
Local: mantenha em memória enquanto o servidor loopback estiver ativo.
Cliente remoto pré-registrado
Redirect HTTPS fixo, ex.:https://example.com/oauth/callback.
Registre como confidencial (client_secret_basic). O client_secret aparece uma vez — guarde em cofre de secrets, nunca no frontend.
Checklist do callback
Trate como falha se:- Faltar
code statenão bater com o salvo- Vier
errorna query (access_denied, etc.)
URL de autorização (exemplo)
Trocar o code
Cliente local (loopback)
Redirect em127.0.0.1 com porta efêmera, ex.: http://127.0.0.1:49152/oauth/callback.
Registre como público (token_endpoint_auth_method: none). Faça bind em 127.0.0.1 ou [::1] — não use 0.0.0.0.
DCR para CLI
http://127.0.0.1:49152/oauth/callback) se o path base foi registrado com flexibilidade de porta — host e path devem bater com o cadastro.
Abrir authorize (Node)
Token (público)
Refresh token rotativo
Cada refresh bem-sucedido devolve um novorefresh_token. O anterior invalida.
client_id no body em vez de Basic auth.
Chamar /v1 com access token
Access token é JWT (~15 min, EdDSA). Envie como Bearer:
GET /.well-known/jwks.json.

