Skip to main content

Auth Endpoints

All auth + OTP + password reset endpoints. Routes live under src/app/api/auth/** (consumer + seller) and src/app/api/doctor/auth/ (doctor).

For the conceptual flow + token-storage conventions see Authentication feature.

Sign up + sign in

POST /api/auth/consumer-register

Create a new consumer + send email verification OTP.

Body: { email, password, name, phone?, referralCode? } Response (200): { consumer: { id, name, email }, message: "..." } Errors: 400 (validation), 409 (email exists), 429 (rate limit)

POST /api/auth/consumer-login

Body: { email, password } Response (200): { consumer, token }. Caller stores token in localStorage["ka26_consumer_token"] (web) or SecureStore (mobile). Errors: 401 (bad creds), 429

POST /api/auth/register (seller)

Body: { email, password, name, whatsappNumber, sellerType? } Response (200): { seller, message: "Verify your email..." }. Token NOT issued yet (must verify email first).

POST /api/auth/login (seller)

Body: { email, password } Response (200): Sets seller_token httpOnly cookie. Body: { seller }.

POST /api/doctor/auth

Single endpoint for doctor signup OR login (action field).

Body (signup): { action: "register", email, password, name, phone?, specialization?, licenseNumber? } Body (login): { action: "login", email, password }

Email verification (OTP)

POST /api/auth/send-verification

Send a 6-digit OTP to the user's email/phone.

Body: { consumerId? | sellerId? | doctorId?, type: "email" | "phone" } Response (200): { success: true, message: "Verification code sent to si***@gmail.com" } Errors:

  • 400 — already verified, no email/phone on file
  • 429 — { error: "Please wait Ns before requesting another code.", retryAfterSeconds: N } (per-user 60s cooldown)
  • 429 — IP rate limit (3 sends per 5 min)
  • 503 — SMTP not configured (will return false from sendEmailVerification)

POST /api/auth/verify-email

Validate the OTP.

Body: { consumerId? | sellerId? | doctorId?, type, code } Response (200): { success: true, message: "Email verified..." }. For seller, also sets seller_token cookie. Errors (400): precise reason field — { error: "...", reason: "invalid" | "used" | "expired" }. UI uses reason for actionable messaging.

Password reset

POST /api/auth/forgot-password

Generate a 32-byte hex reset token + email link. Always returns success (prevents enumeration).

Body: { email, type?: "consumer" | "seller" | "doctor" } (default: seller) Response (200): { message: "If an account with that email exists, a password reset link has been sent." }

Email goes via central email lib (sendPasswordReset). Reset link format:

  • Consumer: ${APP_URL}/consumer-reset-password?token=...&type=consumer
  • Seller: ${APP_URL}/seller/reset-password?token=...&type=seller
  • Doctor: ${APP_URL}/doctor/reset-password?token=...&type=doctor

Token expiry: 15 min (PASSWORD_RESET_EXPIRY_MS).

POST /api/auth/reset-password

Apply new password using a valid token.

Body: { token, password } Response (200): { message: "Password reset successfully...", type } Errors (400): Invalid or expired reset link (wrong/expired token), validation errors

The endpoint resolves the token across all 3 user tables (seller → consumer → doctor) so the same code path serves all types.

OAuth

POST /api/auth/google

Consumer Google OAuth callback.

Body: { idToken } (from Google Sign-In) Response (200): { consumer, token }

POST /api/auth/seller-google

Seller Google OAuth.

POST /api/auth/doctor-google

Doctor Google OAuth.

Logout

POST /api/auth/logout

Clears the seller_token cookie. (Consumer logout is purely client-side — they just clear localStorage.)

Rate limits

EndpointLimit
/api/auth/login20 req/min per IP (middleware)
/api/auth/register (and consumer-register)3 per 10 min per IP
/api/auth/forgot-password3 per 10 min per IP
/api/auth/reset-password3 per 10 min per IP
/api/auth/send-verification3 per 5 min per IP + 60s per-user cooldown
/api/auth/verify-email10 per 5 min per IP

See src/middleware.ts (auth-only middleware rate limit) and src/lib/security.ts (per-endpoint app-level limits).

Common headers

All auth-required endpoints accept either:

  • Authorization: Bearer <token> (consumer flow)
  • Cookie: seller_token=<token> (seller flow, httpOnly cookie auto-sent)

Helpers: resolveConsumerId(request) from @/lib/consumer-auth, getAuthenticatedSeller() from @/lib/seller-auth.