Kelova Docs

Autenticación

Login, JWT, segundo factor (OTP) y cambio de password

Kelova usa autenticación por email + password, con JWT como token de sesión. Los usuarios con verificación en dos pasos (otp_required) hacen un paso adicional de OTP antes de recibir el token.

Login

curl -X POST https://api.kelova.app/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@tuempresa.com",
    "password": "tu-password"
  }'

Respuesta — sin segundo factor (200):

{
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

Respuesta — con segundo factor activo (200): Kelova envía un OTP de 6 dígitos por email y responde sin token todavía.

{
  "requires_otp": true,
  "email": "admin@tuempresa.com"
}

Completa el login con el OTP recibido:

curl -X POST https://api.kelova.app/auth/login/verify-otp \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@tuempresa.com",
    "otp": "482913"
  }'
{
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

Si tu cuenta tiene el segundo factor activo, POST /auth/otp/verify (login passwordless) queda bloqueado — responde 403 TWO_FACTOR_REQUIRED. Debes usar el flujo de arriba: password primero, OTP después.

Usar el token

Incluye el JWT en cada request autenticado:

curl https://api.kelova.app/tenants/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Estructura del JWT

El token codifica el usuario, el tenant y el rol — no necesitas enviar tenant_id en ningún request, el backend lo extrae del token:

{
  "sub": "user-uuid",
  "email": "admin@tuempresa.com",
  "tenant_id": "tenant-uuid",
  "tenant_slug": "tuempresa",
  "role": "admin",
  "exp": 1234567890
}

Roles posibles: admin, member, viewer, api_user. El token expira 8 horas después de emitido — no hay refresh token; el cliente vuelve a hacer login.

Cambiar el password

Requiere JWT. Verifica el password actual antes de aceptar el nuevo.

curl -X PUT https://api.kelova.app/auth/change-password \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "current_password": "password-actual",
    "new_password": "password-nuevo-min-8-chars"
  }'
{
  "message": "password changed"
}

Recuperar acceso (password olvidado)

Flujo de dos pasos, sin autenticación previa:

Solicita el código. Siempre responde 200, incluso si el email no existe (evita enumeración de cuentas).

curl -X POST https://api.kelova.app/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@tuempresa.com"}'

Resetea el password con el OTP recibido por email.

curl -X POST https://api.kelova.app/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@tuempresa.com",
    "otp": "482913",
    "password": "password-nuevo-min-8-chars"
  }'
{
  "message": "password reset — you can now log in"
}

OTP genérico

POST /auth/otp/send y POST /auth/otp/verify son los endpoints base de OTP, usados internamente por signup y reset. Body de send: {"email": "...", "purpose": "login|signup|reset_password"}. verify acepta {"email": "...", "code": "...", "purpose": "..."} y — para purpose=login sin segundo factor — devuelve directamente {"token": "..."}.

Todos los endpoints de OTP y password aplican rate limiting por IP y por email, y bloquean tras varios intentos fallidos consecutivos. Un 429 TOO_MANY_REQUESTS es la señal de que debes esperar antes de reintentar — ver Errores.

On this page