Autenticação
Duas credenciais, para dois usos diferentes — e uma terceira prova, amarrada a uma operação só.
Chave de API
É a credencial de integração servidor-a-servidor. Vai no cabeçalho X-API-Key, em toda requisição:
X-API-Key: lume_sk_sandbox_k7m2p9qr4tvxaz3n6hjd8swy5cbe2fgk4mpqO cabeçalho é próprio, e não Authorization: chave e token de sessão são credenciais diferentes, com validades e revogações diferentes. Empilhá-las no mesmo lugar obrigaria a adivinhar qual é qual pelo formato, e é assim que um token expirado vira “chave inválida” no atendimento.
O que a chave carrega
- O ambiente, escrito no próprio texto.
lume_sk_sandbox_oulume_sk_live_. Quem lê um log, uma captura de tela ou um repositório público reconhece na hora se aquilo é credencial de brinquedo ou de dinheiro. - A conta em nome de quem ela age. Uma chave sem conta não existe: toda chamada desta API é sobre o dinheiro de alguém.
- Os escopos. Uma chave só alcança o que os escopos dela permitem. A maior parte das integrações consulta saldo e extrato e nunca precisou transferir — e uma chave que só lê, vazada, não move dinheiro nenhum.
Escopos
| Escopo | O que abre |
|---|---|
accounts:read | Perfil, saldo, extrato, transação, limites, beneficiários, trilha de segurança e tabela e cotação de tarifas |
pix:read | Listar chaves, consultar o DICT, ler um BR Code, listar cobranças por QR Code |
pix:write | Transferir, pagar e emitir BR Code, criar e excluir cobrança por QR Code |
pix:keys:write | Cadastrar chave PIX. Excluir é só de sessão. |
beneficiaries:write | Cadastrar e excluir beneficiário |
A chave de sandbox nasce com todos: o ambiente existe para ser exercitado inteiro, e restringir aqui esconderia metade do produto sem proteger nada. A chave de produção nasce só com accounts:read, e o banco emite no máximo os escopos de leitura (accounts:read e pix:read): chave de produção que move dinheiro não é emitida. A emissão fica registrada com o nome de quem emitiu e de quem aprovou.
Falta de escopo devolve 403 com FORBIDDEN. É diferente de 401: 403 significa que a credencial vale e não alcança esta operação; 401 significa que ela não vale mais.
Validade e revogação
- Não expira por tempo; expira por 30 dias sem uso. Quem avaliou o produto em março não deve continuar com credencial válida em dezembro.
- Pode ser revogada a qualquer momento, e a revogação vale na requisição seguinte — não quando alguma sessão expirar.
- O segredo aparece uma única vez, na emissão. Não há endpoint que o mostre de novo: guardá-lo para poder reexibi-lo transformaria o banco de dados numa lista de credenciais em claro. Perdeu, emite outra.
Sessão interativa
É a credencial de quem está numa tela — o internet banking, o aplicativo, ou um painel que você construa para o titular da conta. Duas etapas, sempre:
POST /v1/auth/login
{ "document": "123.456.789-09", "password": "…", "deviceFingerprint": "b7f3c1e9a2d84f60" }
→ { "mfaToken": "…", "mfaRequired": true, "newDevice": false }POST /v1/auth/mfa
{ "mfaToken": "…", "code": "482913" }
→ { "accessToken": "…", "refreshToken": "…", "expiresIn": 900, "accountId": "acc_u1" }A senha sozinha nunca abre sessão. O mfaToken vale cinco minutos e só serve para apresentar o segundo fator.
O token de acesso vale 15 minutos e vai em Authorization: Bearer. O de renovação vale 30 dias e é de uso único: cada renovação devolve um par novo e gasta o anterior. Um token já gasto que reaparece derruba a linhagem inteira nascida daquele login — é o sinal clássico de credencial copiada.
Duas respostas iguais de propósito
Documento inexistente e senha errada devolvem a mesma resposta, e levam o mesmo tempo. Responder diferente entregaria quem é cliente do banco a qualquer pessoa com uma lista de CPFs.
Step-up
Algumas operações exigem uma prova adicional de segundo fator, mesmo com credencial válida. O token de step-up é amarrado a uma operação e vale cinco minutos: aprovar uma transferência de R$ 50 não autoriza a próxima de R$ 50 mil.
| Operação | purpose | Quando |
|---|---|---|
| Transferência PIX | transfer | A partir de R$ 1.000,00, inclusive, por operação — ou quando a soma das saídas de Pix do dia chega a esse valor. |
| Cadastro de chave PIX | pix_key | Sempre. Uma chave sequestrada redireciona todo dinheiro que alguém tentar enviar ao titular. |
| Enviar TED | ted | Sempre, qualquer que seja o valor. O token de transfer não vale. |
| Liberar transferência retida | review | Só para liberar. Bloquear não exige — travar a saída nunca pode ser mais difícil do que autorizá-la. |
| Contestar um Pix enviado (MED) | dispute | Sempre. |
| Aderir a um plano, trocá-lo, trocar o dia de cobrança ou cancelá-lo | subscription | Sempre: a adesão debita a primeira mensalidade na hora. |
| Ver o número do cartão ou desbloqueá-lo | card | Sempre. |
| Segurança da conta: biometria facial, aumento de limite, senha, proteções e avisos, remover aparelho, bloquear a própria conta | biometrics, limits, password, preferences, devices, account_block | Cada uma com o seu; nas proteções e avisos, só para desligar. São rotas de tela, só de sessão. |
POST /v1/auth/step-up
{ "code": "482913", "purpose": "transfer" }
→ { "stepUpToken": "…", "expiresIn": 300 }
# e então, na chamada que a exige:
X-Step-Up: <stepUpToken>Quando a instalação exige também a biometria facial para valor alto, a operação responde 403 BIOMETRIC_REQUIRED. Emita a prova de novo com o campo selfie (imagem em base64) e repita com o novo X-Step-Up.
Step-up numa integração sem tela
O código de seis dígitos é um TOTP comum (RFC 6238). Na emissão da chave de sandbox você recebe o segredo da conta — qualquer biblioteca de TOTP calcula o código a partir dele, sem telefone nenhum envolvido. A rota do step-up é de sessão: ela pede o Authorization: Bearer de POST /v1/auth/login e POST /v1/auth/mfa, e não aceita X-API-Key. No sandbox, o login usa as credentials devolvidas na emissão da chave. O token que sai dela vale na chamada seguinte mesmo quando essa usa a chave de API — é assim que o cadastro de chave PIX e o Pix a partir de R$ 1.000,00 dependem dele. Em produção, o token vem de uma sessão do próprio titular.
import { TOTP } from 'otpauth'
const totp = new TOTP({ secret: process.env.LUME_TOTP_SECRET })
const code = totp.generate()
const prova = await fetch(base + '/v1/auth/step-up', {
method: 'POST',
headers: { Authorization: 'Bearer ' + tokenDeAcesso, 'Content-Type': 'application/json' },
body: JSON.stringify({ code, purpose: 'transfer' }),
}).then((r) => r.json())
// prova.stepUpToken vale 5 minutos, e só para 'transfer'.Quando a credencial não é aceita
Todo erro de autenticação responde 401 com o código UNAUTHORIZED. A mensagem distingue o motivo: chave inválida, revogada, expirada por inatividade, ainda aguardando a aprovação do banco, ou de outro ambiente. A tabela completa está em Erros.
Com a conta bloqueada ou encerrada, a chave continua válida e não alcança nada: toda chamada responde 403 com FORBIDDEN. Se a conta for reativada, a mesma chave volta a valer.