Auth Endpoints
Overview
Section titled “Overview”Auth endpoints are grouped under:
/api/v1/auth
Current flow:
- Register user.
- Verify email.
- Login (get JWT).
- Access protected endpoints with
Authorization: Bearer <token>. - Manage API key for integrations (
X-API-Key). - Manage account security (change password / delete account).
- Recover password with forgot/reset flow when needed.
Rate-limited auth endpoints (per IP):
POST /auth/login:10/15 minPOST /auth/register:5/15 minPOST /auth/forgot-password:5/15 minPOST /auth/reset-password:10/15 minPOST /auth/api-key/regenerate:5/15 min
POST /auth/register
Section titled “POST /auth/register”Request Body
Section titled “Request Body”{ "email": "user@example.com", "password": "securepassword123", "name": "Jane Doe"}Success Response (201)
Section titled “Success Response (201)”{ "message": "Registration successful. Please check your email to verify your account."}Error Responses
Section titled “Error Responses”200OK (existing unverified email): verification email is resent.409Conflict (existing verified email): email already in use.503Service Unavailable: verification email could not be sent.- Note: if email delivery fails, user creation is rolled back (no partial account is kept).
Existing unverified email (200)
Section titled “Existing unverified email (200)”{ "message": "Account pending verification. We sent a new verification email."}GET /auth/verify/:token
Section titled “GET /auth/verify/:token”Success Response (200)
Section titled “Success Response (200)”{ "message": "Email verified successfully"}Repeated valid token (idempotent):
{ "message": "Email already verified. You can sign in."}Error Responses
Section titled “Error Responses”404Not Found: invalid or expired verification token.
POST /auth/forgot-password
Section titled “POST /auth/forgot-password”Request a password reset link.
Request Body
Section titled “Request Body”{ "email": "user@example.com"}Success Response (200)
Section titled “Success Response (200)”Returned for both existing and non-existing emails:
{ "message": "If an account with that email exists, we sent password reset instructions."}Error Responses
Section titled “Error Responses”400Bad Request: validation failed (invalid email format).
POST /auth/reset-password
Section titled “POST /auth/reset-password”Reset password using the token sent by email.
Request Body
Section titled “Request Body”{ "token": "0f2f7c1b-8eaf-4f2f-b3bb-3dc4fbf39811", "newPassword": "newPassword123", "confirmPassword": "newPassword123"}Success Response (200)
Section titled “Success Response (200)”{ "message": "Password reset successfully"}Error Responses
Section titled “Error Responses”400Bad Request: invalid or expired reset token.400Bad Request: validation failed (for example, passwords do not match).
- Successful reset marks the account as verified (
isVerified = true). - Reset tokens are one-time use and are cleared after success.
Invalid/expired token example:
{ "statusCode": 400, "error": "Bad Request", "message": "Invalid or expired password reset token"}POST /auth/login
Section titled “POST /auth/login”Request Body
Section titled “Request Body”{ "email": "user@example.com", "password": "securepassword123"}Success Response (200)
Section titled “Success Response (200)”{ "message": "Welcome back, Jane Doe", "accessToken": "<jwt>", "user": { "id": 1, "email": "user@example.com", "name": "Jane Doe", "isVerified": true }}Error Responses
Section titled “Error Responses”401Unauthorized: invalid credentials or unverified account.
GET /auth/me (protected)
Section titled “GET /auth/me (protected)”Headers
Section titled “Headers”Authorization: Bearer <token>Success Response (200)
Section titled “Success Response (200)”{ "user": { "id": 1, "email": "user@example.com", "name": "Jane Doe", "isVerified": true }}GET /auth/api-key (protected)
Section titled “GET /auth/api-key (protected)”Bearer token required (Authorization: Bearer <token>). X-API-Key is not accepted for this endpoint.
Success Response (200)
Section titled “Success Response (200)”{ "apiKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}Or:
{ "apiKey": null}POST /auth/api-key/regenerate (protected)
Section titled “POST /auth/api-key/regenerate (protected)”Headers
Section titled “Headers”Authorization: Bearer <token>X-API-Key is not accepted for this endpoint.
Success Response (200)
Section titled “Success Response (200)”{ "message": "API Key regenerated successfully", "apiKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}If user had no previous key:
{ "message": "API Key created successfully", "apiKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}POST /auth/change-password (protected)
Section titled “POST /auth/change-password (protected)”Headers
Section titled “Headers”Authorization: Bearer <token>Request Body
Section titled “Request Body”{ "currentPassword": "oldPassword123", "newPassword": "newPassword123"}Success Response (200)
Section titled “Success Response (200)”{ "message": "Password changed successfully"}Error Responses
Section titled “Error Responses”401Unauthorized: current password is incorrect.400Bad Request: new password equals current password, or account is OAuth-only.
DELETE /auth/account (protected)
Section titled “DELETE /auth/account (protected)”Headers
Section titled “Headers”Authorization: Bearer <token>Success Response (200)
Section titled “Success Response (200)”{ "message": "Account deleted successfully"}- This operation permanently deletes the user and owned URLs.