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
falsefromsendEmailVerification)
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
| Endpoint | Limit |
|---|---|
/api/auth/login | 20 req/min per IP (middleware) |
/api/auth/register (and consumer-register) | 3 per 10 min per IP |
/api/auth/forgot-password | 3 per 10 min per IP |
/api/auth/reset-password | 3 per 10 min per IP |
/api/auth/send-verification | 3 per 5 min per IP + 60s per-user cooldown |
/api/auth/verify-email | 10 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.