VenddorDocumentação API
API atualAPI legada
Guia rápidoReferência completa
Carregando índice…
API atual/Referência completa/Autenticação avançada

Login por código (OTP)

Entra sem senha com um código de 6 dígitos enviado por e-mail, SMS ou WhatsApp.

O login por código serve para o cliente que não lembra a senha ou que prefere não ter uma. Você chama duas rotas em sequência: primeiro pede o código para um identificador (e-mail ou telefone), depois devolve o código que o cliente recebeu e recebe os tokens de sessão, exatamente como no login com senha.

O recurso depende do módulo otp-verification da loja. Com o módulo desligado, as duas rotas respondem 403 com module_disabled. Os canais (e-mail, SMS, WhatsApp) também são ligados loja a loja; peça ao administrador da loja para conferir.

Pontos principais
  • A resposta do passo 1 é a mesma exista ou não conta para o identificador. Não use essa rota para descobrir se um cliente existe.
  • O código tem 6 dígitos. Erros repetidos no passo 2 bloqueiam o identificador por um tempo (429 account_locked), em um contador separado do login com senha.
  • O resultado do passo 2 tem o mesmo formato do login: access_token, refresh_token e expires_at.
  • Os dois passos são públicos (sem token) e entram no limite de requisições da família /api/v1/auth/.
POST/api/v1/auth/otp-login/requestPública

Pedir o código de login

Gera e envia o código. A plataforma não informa se o identificador existe: a resposta é 200 nos dois casos.

Corpo da requisição

identifierstringobrigatório
E-mail ou telefone do cliente. Espaços nas pontas são removidos.
channelstringpadrão: email
emailsmswhatsapp
Canal de entrega. Maiúsculas são aceitas. Vazio vale email.

Exemplo de requisição

bash
curl -X POST "$BASE_URL/api/v1/auth/otp-login/request" \
  -H "Content-Type: application/json" \
  -d '{
  "identifier": "maria.souza@example.com",
  "channel": "email"
}'

Resposta

200Código solicitado
json
{
  "success": true,
  "channel": "email"
}

Campos da resposta

successboolean
Sempre true quando a requisição foi aceita.
channelstring
Canal que a loja usa para esse tipo de envio. Vem da configuração da loja, não da conta do cliente, então não revela se a conta existe.

Erros

StatusQuandoExemplo de corpo
400Identificador vazio.{"error":"identifier is required","detail":"provide an email or phone"}
400Canal fora de email, sms e whatsapp.{"error":"invalid_channel","detail":"channel must be email, sms or whatsapp"}
403Módulo de OTP desligado na loja.{"error":"module_disabled","module":"otp-verification"}
409Canal WhatsApp com a janela de conversa fechada.{"error":"whatsapp_window_closed"}
429Muitos pedidos de código para o mesmo identificador, ou limite de requisições da API.{"error":"rate_limited","detail":"too many ..."}
POST/api/v1/auth/otp-login/verifyPública

Trocar o código por tokens de sessão

Confere o código e, se estiver certo, abre a sessão. Use os mesmos tokens do login com senha.

Corpo da requisição

identifierstringobrigatório
O mesmo identificador usado no passo 1.
codestringobrigatório
Código de 6 dígitos recebido pelo cliente.

Exemplo de requisição

bash
curl -X POST "$BASE_URL/api/v1/auth/otp-login/verify" \
  -H "Content-Type: application/json" \
  -d '{
  "identifier": "maria.souza@example.com",
  "code": "482915"
}'

Resposta

200Sessão aberta
json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "rt_9f2c1d7e4b...",
  "expires_at": "2026-10-11T21:30:00Z"
}

Campos da resposta

access_tokenstring
JWT de acesso, curto. Envie em Authorization: Bearer. Veja Tokens.
refresh_tokenstring
Token opaco para obter um novo par em POST /api/v1/auth/refresh.
expires_atstring
Quando o access_token expira (RFC 3339, UTC).

Erros

StatusQuandoExemplo de corpo
400Falta identifier ou code.{"error":"identifier and code are required"}
401Código errado, expirado, ou identificador sem conta. Os três casos têm a mesma resposta.{"error":"invalid_otp"}
403A conta pertence ao painel da plataforma, não à loja.{"error":"wrong_panel","detail":"this account belongs to the platform admin panel"}
403Subconta suspensa.{"error":"subaccount_suspended"}
429Tentativas erradas demais. O cabeçalho Retry-After traz os segundos de espera.{"error":"account_locked","detail":"too many failed login attempts, please try again later"}
Trate o 401 como um só erro

Mostre ao cliente uma mensagem única ("código inválido ou expirado") e deixe pedir um código novo. Distinguir "conta inexistente" de "código errado" não é possível pela API, de propósito.

Veja também

  • Autenticação avançada
  • Tokens e escopos
  • Limites de requisições
Anterior
Autenticação avançada
Próxima
Login com passkey
Nesta página
  • Exemplo de requisição
  • Resposta
  • Erros
  • Exemplo de requisição
  • Resposta
  • Erros
  • Veja também