Skip to content

Authentication API

Common Information

Base URL

/api/v1/auth

Authentication Header

Authorization: Bearer <access_token>

Response Envelope

All responses follow the standard format:

typescript
// Success response
interface SuccessResponse<T> {
  success: true;
  data: T;
  meta?: {
    [key: string]: unknown;
  };
}

// Error response
interface ErrorResponse {
  success: false;
  error: {
    code: string;
    message: string;
    details?: Record<string, string[]>;
  };
}

Rate Limits

EndpointLimit
POST /register5/min
POST /login5/min
POST /forgot-password3/hour
POST /reset-password3/hour
Other auth endpoints100/min

Rate Limit Headers

X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
X-RateLimit-Reset: 1705329600

Endpoints

POST /api/v1/auth/register

Register a new user account.

Authentication: Public

Rate Limit: 5 requests per minute

Request Body

typescript
interface RegisterRequest {
  email: string;           // Valid email address
  password: string;        // Min 8 chars, 1 uppercase, 1 lowercase, 1 number
  firstName: string;       // 2-100 characters
  lastName: string;        // 2-100 characters
  phone?: string;          // Optional, E.164 format
  referralCode?: string;   // Optional, sponsor's referral code
  acceptTerms: boolean;    // Must be true
  acceptPrivacy: boolean;  // Must be true
}

Query Parameters

None

Response (201 Created)

typescript
interface RegisterResponse {
  id: string;              // UUID
  email: string;
  status: 'PENDING_VERIFICATION';
  profile: {
    firstName: string;
    lastName: string;
  };
  createdAt: string;       // ISO 8601
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
409EMAIL_ALREADY_EXISTSEmail is already registered
409PHONE_ALREADY_EXISTSPhone number is already registered
404INVALID_REFERRAL_CODEReferral code does not exist
429RATE_LIMIT_EXCEEDEDToo many registration attempts

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "SecurePass123",
    "firstName": "John",
    "lastName": "Doe",
    "referralCode": "ABC123XY",
    "acceptTerms": true,
    "acceptPrivacy": true
  }'

Response:

json
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "status": "PENDING_VERIFICATION",
    "profile": {
      "firstName": "John",
      "lastName": "Doe"
    },
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

POST /api/v1/auth/login

Authenticate user and receive access tokens.

Authentication: Public

Rate Limit: 5 requests per minute

Request Body

typescript
interface LoginRequest {
  email: string;
  password: string;
  deviceFingerprint?: string;  // For session tracking
  twoFactorCode?: string;      // Required if 2FA is enabled
}

Query Parameters

None

Response (200 OK)

typescript
interface LoginResponse {
  accessToken: string;         // JWT, expires in 15 minutes
  refreshToken: string;        // Opaque token, expires in 7 days
  expiresIn: number;           // Seconds until access token expires
  tokenType: 'Bearer';
  user: {
    id: string;
    email: string;
    status: string;
    profile: {
      firstName: string;
      lastName: string;
      avatarUrl: string | null;
    };
    roles: string[];
    requiresTwoFactor: boolean;
  };
}

Response (200 OK - 2FA Required)

typescript
interface TwoFactorRequiredResponse {
  requiresTwoFactor: true;
  tempToken: string;           // Temporary token for 2FA verification
  methods: ('TOTP' | 'SMS' | 'EMAIL')[];
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
401INVALID_CREDENTIALSEmail or password is incorrect
401TWO_FACTOR_REQUIRED2FA code is required
401INVALID_TWO_FACTOR_CODE2FA code is incorrect
403ACCOUNT_NOT_VERIFIEDEmail has not been verified
403ACCOUNT_SUSPENDEDAccount is suspended
403ACCOUNT_BANNEDAccount is banned
429RATE_LIMIT_EXCEEDEDToo many login attempts

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "SecurePass123"
  }'

Response:

json
{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
    "expiresIn": 900,
    "tokenType": "Bearer",
    "user": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "user@example.com",
      "status": "ACTIVE",
      "profile": {
        "firstName": "John",
        "lastName": "Doe",
        "avatarUrl": "https://cdn.iwm-platform.com/avatars/550e8400.jpg"
      },
      "roles": ["USER"],
      "requiresTwoFactor": false
    }
  }
}

POST /api/v1/auth/logout

Invalidate the current session and refresh token.

Authentication: Required

Rate Limit: 100 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

typescript
interface LogoutRequest {
  refreshToken: string;      // The refresh token to invalidate
  allDevices?: boolean;      // If true, logout from all devices
}

Query Parameters

None

Response (200 OK)

typescript
interface LogoutResponse {
  message: string;
  sessionsRevoked: number;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
400INVALID_REFRESH_TOKENRefresh token is invalid or already revoked

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/logout \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
    "allDevices": false
  }'

Response:

json
{
  "success": true,
  "data": {
    "message": "Successfully logged out",
    "sessionsRevoked": 1
  }
}

POST /api/v1/auth/refresh

Refresh the access token using a valid refresh token.

Authentication: Public (uses refresh token)

Rate Limit: 100 requests per minute

Request Body

typescript
interface RefreshTokenRequest {
  refreshToken: string;
}

Query Parameters

None

Response (200 OK)

typescript
interface RefreshTokenResponse {
  accessToken: string;
  refreshToken: string;        // New refresh token (rotation)
  expiresIn: number;
  tokenType: 'Bearer';
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORRefresh token not provided
401INVALID_REFRESH_TOKENRefresh token is invalid
401REFRESH_TOKEN_EXPIREDRefresh token has expired
401SESSION_REVOKEDSession has been revoked

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
  }'

Response:

json
{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "bmV3IHJlZnJlc2ggdG9rZW4...",
    "expiresIn": 900,
    "tokenType": "Bearer"
  }
}

POST /api/v1/auth/verify-email

Verify user email address with the verification token.

Authentication: Public

Rate Limit: 100 requests per minute

Request Body

typescript
interface VerifyEmailRequest {
  token: string;              // Email verification token from email link
}

Query Parameters

None

Response (200 OK)

typescript
interface VerifyEmailResponse {
  message: string;
  user: {
    id: string;
    email: string;
    status: 'ACTIVE';
    emailVerifiedAt: string;
  };
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORToken not provided
400INVALID_TOKENVerification token is invalid
400TOKEN_EXPIREDVerification token has expired
409ALREADY_VERIFIEDEmail is already verified

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/verify-email \
  -H "Content-Type: application/json" \
  -d '{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'

Response:

json
{
  "success": true,
  "data": {
    "message": "Email successfully verified",
    "user": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "user@example.com",
      "status": "ACTIVE",
      "emailVerifiedAt": "2024-01-15T10:35:00Z"
    }
  }
}

POST /api/v1/auth/resend-verification

Resend email verification link.

Authentication: Public

Rate Limit: 3 requests per hour

Request Body

typescript
interface ResendVerificationRequest {
  email: string;
}

Query Parameters

None

Response (200 OK)

typescript
interface ResendVerificationResponse {
  message: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid email format
404USER_NOT_FOUNDNo account with this email
409ALREADY_VERIFIEDEmail is already verified
429RATE_LIMIT_EXCEEDEDToo many resend attempts

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/resend-verification \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'

Response:

json
{
  "success": true,
  "data": {
    "message": "Verification email sent if account exists"
  }
}

POST /api/v1/auth/forgot-password

Request a password reset link.

Authentication: Public

Rate Limit: 3 requests per hour

Request Body

typescript
interface ForgotPasswordRequest {
  email: string;
}

Query Parameters

None

Response (200 OK)

typescript
interface ForgotPasswordResponse {
  message: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid email format
429RATE_LIMIT_EXCEEDEDToo many reset attempts

Note: For security reasons, this endpoint always returns success even if the email doesn't exist.

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'

Response:

json
{
  "success": true,
  "data": {
    "message": "Password reset email sent if account exists"
  }
}

POST /api/v1/auth/reset-password

Reset password using the reset token.

Authentication: Public

Rate Limit: 3 requests per hour

Request Body

typescript
interface ResetPasswordRequest {
  token: string;              // Password reset token from email link
  password: string;           // New password (same requirements as registration)
  confirmPassword: string;    // Must match password
}

Query Parameters

None

Response (200 OK)

typescript
interface ResetPasswordResponse {
  message: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
400PASSWORD_MISMATCHPasswords do not match
400INVALID_TOKENReset token is invalid
400TOKEN_EXPIREDReset token has expired
400PASSWORD_TOO_WEAKPassword does not meet requirements
400PASSWORD_RECENTLY_USEDCannot use a recently used password

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "password": "NewSecurePass456",
    "confirmPassword": "NewSecurePass456"
  }'

Response:

json
{
  "success": true,
  "data": {
    "message": "Password successfully reset"
  }
}

POST /api/v1/auth/2fa/setup

Initialize two-factor authentication setup.

Authentication: Required

Rate Limit: 100 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

typescript
interface TwoFactorSetupRequest {
  method: 'TOTP' | 'SMS' | 'EMAIL';
}

Query Parameters

None

Response (200 OK)

typescript
interface TwoFactorSetupResponse {
  method: 'TOTP' | 'SMS' | 'EMAIL';
  // For TOTP method
  secret?: string;             // Base32 encoded secret
  qrCode?: string;             // Data URL for QR code image
  manualEntryKey?: string;     // For manual entry in authenticator app
  // For SMS/EMAIL methods
  maskedDestination?: string;  // e.g., "+7***1234" or "u***@example.com"
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid method
401UNAUTHORIZEDInvalid or expired access token
409TWO_FACTOR_ALREADY_ENABLED2FA is already enabled
400PHONE_NOT_VERIFIEDPhone must be verified for SMS method
400EMAIL_NOT_VERIFIEDEmail must be verified for EMAIL method

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/2fa/setup \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "method": "TOTP"
  }'

Response:

json
{
  "success": true,
  "data": {
    "method": "TOTP",
    "secret": "JBSWY3DPEHPK3PXP",
    "qrCode": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
    "manualEntryKey": "JBSWY3DPEHPK3PXP"
  }
}

POST /api/v1/auth/2fa/verify

Verify and enable two-factor authentication.

Authentication: Required

Rate Limit: 100 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

typescript
interface TwoFactorVerifyRequest {
  code: string;               // 6-digit verification code
}

Query Parameters

None

Response (200 OK)

typescript
interface TwoFactorVerifyResponse {
  enabled: true;
  method: 'TOTP' | 'SMS' | 'EMAIL';
  backupCodes: string[];       // One-time recovery codes
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid code format
400INVALID_CODEVerification code is incorrect
400CODE_EXPIREDVerification code has expired
401UNAUTHORIZEDInvalid or expired access token
400SETUP_NOT_INITIATEDMust call /2fa/setup first

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/2fa/verify \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "code": "123456"
  }'

Response:

json
{
  "success": true,
  "data": {
    "enabled": true,
    "method": "TOTP",
    "backupCodes": [
      "ABCD-1234-EFGH",
      "IJKL-5678-MNOP",
      "QRST-9012-UVWX",
      "YZAB-3456-CDEF",
      "GHIJ-7890-KLMN",
      "OPQR-1234-STUV",
      "WXYZ-5678-ABCD",
      "EFGH-9012-IJKL"
    ]
  }
}

POST /api/v1/auth/2fa/disable

Disable two-factor authentication.

Authentication: Required

Rate Limit: 100 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

typescript
interface TwoFactorDisableRequest {
  password: string;           // Current account password
  code: string;               // Current 2FA code or backup code
}

Query Parameters

None

Response (200 OK)

typescript
interface TwoFactorDisableResponse {
  disabled: true;
  message: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input
401UNAUTHORIZEDInvalid or expired access token
401INVALID_PASSWORDPassword is incorrect
401INVALID_CODE2FA code is incorrect
400TWO_FACTOR_NOT_ENABLED2FA is not currently enabled

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/auth/2fa/disable \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "password": "SecurePass123",
    "code": "123456"
  }'

Response:

json
{
  "success": true,
  "data": {
    "disabled": true,
    "message": "Two-factor authentication has been disabled"
  }
}

GET /api/v1/auth/sessions

List all active sessions for the current user.

Authentication: Required

Rate Limit: 100 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 50 (optional)

Response (200 OK)

typescript
interface SessionsResponse {
  sessions: Session[];
}

interface Session {
  id: string;
  deviceFingerprint: string | null;
  ipAddress: string;
  userAgent: string;
  location: {
    country: string | null;
    city: string | null;
  };
  isCurrent: boolean;
  createdAt: string;
  lastActiveAt: string;
  expiresAt: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token

Example

Request:

bash
curl -X GET "https://api.iwm-platform.com/api/v1/auth/sessions?page=1&pageSize=10" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response:

json
{
  "success": true,
  "data": {
    "sessions": [
      {
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "deviceFingerprint": "abc123def456",
        "ipAddress": "192.168.1.1",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
        "location": {
          "country": "Russia",
          "city": "Moscow"
        },
        "isCurrent": true,
        "createdAt": "2024-01-15T10:30:00Z",
        "lastActiveAt": "2024-01-15T14:45:00Z",
        "expiresAt": "2024-01-22T10:30:00Z"
      },
      {
        "id": "660e8400-e29b-41d4-a716-446655440002",
        "deviceFingerprint": "xyz789ghi012",
        "ipAddress": "192.168.1.2",
        "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0)...",
        "location": {
          "country": "Russia",
          "city": "Saint Petersburg"
        },
        "isCurrent": false,
        "createdAt": "2024-01-14T08:00:00Z",
        "lastActiveAt": "2024-01-14T12:30:00Z",
        "expiresAt": "2024-01-21T08:00:00Z"
      }
    ]
  },
  "meta": {
    "pagination": {
      "total": 2,
      "page": 1,
      "pageSize": 10,
      "totalPages": 1,
      "hasNext": false,
      "hasPrevious": false
    }
  }
}

DELETE /api/v1/auth/sessions/:id

Revoke a specific session.

Authentication: Required

Rate Limit: 100 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Session ID to revoke

Request Body

None

Query Parameters

None

Response (200 OK)

typescript
interface RevokeSessionResponse {
  message: string;
  sessionId: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
404SESSION_NOT_FOUNDSession not found or belongs to another user
400CANNOT_REVOKE_CURRENTCannot revoke current session (use /logout instead)

Example

Request:

bash
curl -X DELETE https://api.iwm-platform.com/api/v1/auth/sessions/660e8400-e29b-41d4-a716-446655440002 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response:

json
{
  "success": true,
  "data": {
    "message": "Session revoked successfully",
    "sessionId": "660e8400-e29b-41d4-a716-446655440002"
  }
}