SuperdindaDocs
Auth

Finish sign-in with the code or link

POST
/auth/otp/verify

Either { email, code } or { token } from the magic link. A refusal is 401 with a code saying why. Code: OTP_INVALID (wrong code — details.attemptsLeft; an unknown address answers exactly the same), OTP_LOCKED (OTP_MAX_ATTEMPTS wrong codes, default 5 — ask for a new code, which unlocks), OTP_EXPIRED (right code, ran out or replaced by a newer one), OTP_USED (right code, already used). Link: OTP_LINK_INVALID (not a link we sent), OTP_LINK_EXPIRED (ran out or replaced), OTP_LINK_USED — the last two can ask for a new link with POST /auth/otp/resend. Limit: RATE_OTP_VERIFY_PER_IP (default 40 per hour).

Request Body

application/json
  1. body
email*string

the email the code was sent to

Formatemail
Lengthlength <= 254
code*string

the six digits from the email

Match^\d{6}$

Response Body

Access JWT in the envelope; refresh token in an httpOnly cookie

application/json
  1. response
success*true
Value intrue
data*
Example Request
curl -X POST 'http://localhost:3000/auth/otp/verify' \  -H 'Content-Type: application/json' \  -d '{  "email": "user@example.com",  "code": "string"}'
Example Response
{  "success": true,  "data": {    "accessToken": "string",    "expiresAtMs": "string"  }}