Login

The unified SCA login replaces the three per-factor login endpoints. You pick the factor on start and submit the matching shape on complete.

POST /user/login/start
Authorization: <HMAC>

{
  "userId": "<uuid>",
  "verificationMethod": "sms" | "totp" | "passkey"
}
  • sms returns { ok: true, challengeId: "<uuid>" } and dispatches an OTP via Twilio (sandbox uses magic code 123456).
  • passkey returns a WebAuthn assertion request to feed navigator.credentials.get().
  • totp returns { ok: true }. There is no server-side challenge — the user reads the current code from their authenticator app.
POST /user/login/complete
Authorization: <HMAC>

{
  "userId": "<uuid>",
  "verificationMethod": "sms" | "totp" | "passkey",
  "ip": "203.0.113.42",
  // SMS:
  "challengeId": "<uuid>",
  "code": "123456",
  // TOTP:
  "code": "123456",
  // Passkey:
  "origin": "https://app.example.com",
  "credential": { /* PublicKeyCredential serialised */ }
}

Returns { status: "success" }. A successful complete grants a new 180-day SCA session, revoking any prior session for this user.