Skip to content

Admin API

Common Information

Base URL

/api/v1/admin

Authentication Header

Authorization: Bearer <access_token>

Required Roles

All endpoints in this API require one of the following roles:

  • ADMIN - Standard admin access
  • SUPER_ADMIN - Full administrative access

Some endpoints may require SUPER_ADMIN specifically. This is noted in the endpoint documentation.

Response Envelope

All responses follow the standard format:

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

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

Pagination Format

typescript
interface PaginationMeta {
  total: number;
  page: number;
  pageSize: number;
  totalPages: number;
  hasNext: boolean;
  hasPrevious: boolean;
}

Rate Limits

EndpointLimit
General admin endpoints200/min
POST /commissions/:id/adjust10/min
POST /payouts/:id/process5/min
Bulk operations30/min

Audit Logging

All admin operations are logged with:

  • Admin user ID
  • Timestamp
  • Action performed
  • Affected entity ID
  • Previous and new values (for updates)
  • IP address

User Management Endpoints

GET /api/v1/admin/users

List all users with filters.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 100 (optional)
statusstringFilter: 'PENDING_VERIFICATION', 'ACTIVE', 'SUSPENDED', 'BANNED', 'ALL' (optional)
rolestringFilter by role: 'USER', 'ADMIN', 'SUPER_ADMIN' (optional)
kycStatusstringFilter by KYC status (optional)
searchstringSearch by email, name, or phone (optional)
dateFromstringRegistration date from (ISO 8601) (optional)
dateTostringRegistration date to (ISO 8601) (optional)
sortBystringSort field: 'createdAt', 'email', 'status', 'lastLoginAt' (optional)
sortOrderstringSort direction: 'asc', 'desc' (optional)

Response (200 OK)

typescript
interface AdminUsersResponse {
  users: AdminUser[];
}

interface AdminUser {
  id: string;
  email: string;
  phone: string | null;
  status: string;
  profile: {
    firstName: string;
    lastName: string;
    avatarUrl: string | null;
  };
  kyc: {
    status: string;
    level: string;
  };
  roles: string[];
  isPartner: boolean;
  stats: {
    ordersCount: number;
    totalSpent: number;
    investmentsCount: number;
    totalInvested: number;
  };
  lastLoginAt: string | null;
  createdAt: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid query parameters
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions

Example

Request:

bash
curl -X GET "https://api.iwm-platform.com/api/v1/admin/users?status=ACTIVE&page=1&pageSize=20" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response:

json
{
  "success": true,
  "data": {
    "users": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "email": "user@example.com",
        "phone": "+79991234567",
        "status": "ACTIVE",
        "profile": {
          "firstName": "John",
          "lastName": "Doe",
          "avatarUrl": "https://cdn.iwm-platform.com/avatars/550e8400.jpg"
        },
        "kyc": {
          "status": "APPROVED",
          "level": "STANDARD"
        },
        "roles": ["USER"],
        "isPartner": true,
        "stats": {
          "ordersCount": 15,
          "totalSpent": 125000,
          "investmentsCount": 3,
          "totalInvested": 150000
        },
        "lastLoginAt": "2024-01-15T14:00:00Z",
        "createdAt": "2024-01-01T10:00:00Z"
      }
    ]
  },
  "meta": {
    "pagination": {
      "total": 1250,
      "page": 1,
      "pageSize": 20,
      "totalPages": 63,
      "hasNext": true,
      "hasPrevious": false
    }
  }
}

GET /api/v1/admin/users/:id

Get detailed user information.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)User ID

Request Body

None

Query Parameters

None

Response (200 OK)

typescript
interface AdminUserDetailResponse {
  id: string;
  email: string;
  phone: string | null;
  status: string;
  profile: {
    firstName: string;
    lastName: string;
    middleName: string | null;
    dateOfBirth: string | null;
    avatarUrl: string | null;
    language: string;
    timezone: string;
  };
  kyc: {
    id: string;
    status: string;
    level: string;
    submittedAt: string | null;
    reviewedAt: string | null;
    reviewedBy: string | null;
    expiresAt: string | null;
    documents: {
      id: string;
      type: string;
      status: string;
      uploadedAt: string;
    }[];
  } | null;
  roles: string[];
  partner: {
    id: string;
    referralCode: string;
    status: string;
    rank: string | null;
    sponsorId: string | null;
    sponsorName: string | null;
    balance: {
      available: number;
      pending: number;
    };
  } | null;
  security: {
    twoFactorEnabled: boolean;
    twoFactorMethod: string | null;
    emailVerifiedAt: string | null;
    phoneVerifiedAt: string | null;
    passwordChangedAt: string | null;
    activeSessions: number;
  };
  stats: {
    ordersCount: number;
    totalSpent: number;
    investmentsCount: number;
    totalInvested: number;
    commissionsEarned: number;
    referralsCount: number;
  };
  addresses: {
    id: string;
    label: string;
    isDefault: boolean;
    city: string;
    country: string;
  }[];
  recentActivity: {
    type: string;
    description: string;
    timestamp: string;
  }[];
  notes: {
    id: string;
    content: string;
    createdBy: string;
    createdAt: string;
  }[];
  lastLoginAt: string | null;
  createdAt: string;
  updatedAt: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404USER_NOT_FOUNDUser not found

Example

Request:

bash
curl -X GET https://api.iwm-platform.com/api/v1/admin/users/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response:

json
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "phone": "+79991234567",
    "status": "ACTIVE",
    "profile": {
      "firstName": "John",
      "lastName": "Doe",
      "middleName": null,
      "dateOfBirth": "1990-05-15",
      "avatarUrl": "https://cdn.iwm-platform.com/avatars/550e8400.jpg",
      "language": "ru",
      "timezone": "Europe/Moscow"
    },
    "kyc": {
      "id": "kyc-001",
      "status": "APPROVED",
      "level": "STANDARD",
      "submittedAt": "2024-01-10T14:00:00Z",
      "reviewedAt": "2024-01-12T09:30:00Z",
      "reviewedBy": "Admin User",
      "expiresAt": "2025-01-12T09:30:00Z",
      "documents": [
        { "id": "doc-001", "type": "PASSPORT", "status": "VERIFIED", "uploadedAt": "2024-01-10T14:00:00Z" },
        { "id": "doc-002", "type": "SELFIE", "status": "VERIFIED", "uploadedAt": "2024-01-10T14:05:00Z" }
      ]
    },
    "roles": ["USER"],
    "partner": {
      "id": "cc0e8400-e29b-41d4-a716-446655440000",
      "referralCode": "DEF456ZW",
      "status": "ACTIVE",
      "rank": "Silver Partner",
      "sponsorId": "dd0e8400-e29b-41d4-a716-446655440000",
      "sponsorName": "Jane Smith",
      "balance": {
        "available": 45000,
        "pending": 15000
      }
    },
    "security": {
      "twoFactorEnabled": true,
      "twoFactorMethod": "TOTP",
      "emailVerifiedAt": "2024-01-01T10:30:00Z",
      "phoneVerifiedAt": null,
      "passwordChangedAt": "2024-01-01T10:00:00Z",
      "activeSessions": 2
    },
    "stats": {
      "ordersCount": 15,
      "totalSpent": 125000,
      "investmentsCount": 3,
      "totalInvested": 150000,
      "commissionsEarned": 75000,
      "referralsCount": 25
    },
    "addresses": [
      { "id": "addr-001", "label": "Home", "isDefault": true, "city": "Moscow", "country": "RU" }
    ],
    "recentActivity": [
      { "type": "LOGIN", "description": "Logged in from Moscow, RU", "timestamp": "2024-01-15T14:00:00Z" },
      { "type": "ORDER", "description": "Placed order #ORD-2024-00001234", "timestamp": "2024-01-14T18:00:00Z" }
    ],
    "notes": [],
    "lastLoginAt": "2024-01-15T14:00:00Z",
    "createdAt": "2024-01-01T10:00:00Z",
    "updatedAt": "2024-01-15T12:00:00Z"
  }
}

PATCH /api/v1/admin/users/:id

Update user information.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)User ID

Request Body

typescript
interface AdminUpdateUserRequest {
  email?: string;
  phone?: string | null;
  profile?: {
    firstName?: string;
    lastName?: string;
    middleName?: string | null;
    dateOfBirth?: string;
    language?: string;
    timezone?: string;
  };
  roles?: string[];                 // Requires SUPER_ADMIN
  note?: string;                    // Add admin note
}

Query Parameters

None

Response (200 OK)

typescript
interface AdminUpdateUserResponse {
  id: string;
  email: string;
  phone: string | null;
  status: string;
  profile: {
    firstName: string;
    lastName: string;
    middleName: string | null;
    dateOfBirth: string | null;
    language: string;
    timezone: string;
  };
  roles: string[];
  updatedAt: string;
  updatedBy: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
403CANNOT_MODIFY_SUPER_ADMINCannot modify SUPER_ADMIN user
404USER_NOT_FOUNDUser not found
409EMAIL_ALREADY_EXISTSEmail is already in use

Example

Request:

bash
curl -X PATCH https://api.iwm-platform.com/api/v1/admin/users/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "profile": {
      "firstName": "Jonathan"
    },
    "note": "Updated name at user request"
  }'

Response:

json
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "phone": "+79991234567",
    "status": "ACTIVE",
    "profile": {
      "firstName": "Jonathan",
      "lastName": "Doe",
      "middleName": null,
      "dateOfBirth": "1990-05-15",
      "language": "ru",
      "timezone": "Europe/Moscow"
    },
    "roles": ["USER"],
    "updatedAt": "2024-01-15T21:00:00Z",
    "updatedBy": "Admin User"
  }
}

POST /api/v1/admin/users/:id/suspend

Suspend a user account.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)User ID

Request Body

typescript
interface SuspendUserRequest {
  reason: string;                   // Reason for suspension
  duration?: number;                // Duration in days (null = indefinite)
  notifyUser?: boolean;             // Send notification email
}

Query Parameters

None

Response (200 OK)

typescript
interface SuspendUserResponse {
  userId: string;
  status: 'SUSPENDED';
  reason: string;
  suspendedAt: string;
  suspendedBy: string;
  suspendedUntil: string | null;
  sessionsRevoked: number;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORReason not provided
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
403CANNOT_SUSPEND_ADMINCannot suspend admin user
404USER_NOT_FOUNDUser not found
400ALREADY_SUSPENDEDUser is already suspended

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/admin/users/550e8400-e29b-41d4-a716-446655440000/suspend \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Suspicious activity detected",
    "duration": 7,
    "notifyUser": true
  }'

Response:

json
{
  "success": true,
  "data": {
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "status": "SUSPENDED",
    "reason": "Suspicious activity detected",
    "suspendedAt": "2024-01-15T21:00:00Z",
    "suspendedBy": "Admin User",
    "suspendedUntil": "2024-01-22T21:00:00Z",
    "sessionsRevoked": 2
  }
}

POST /api/v1/admin/users/:id/activate

Activate a suspended user account.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)User ID

Request Body

typescript
interface ActivateUserRequest {
  note?: string;                    // Optional note
  notifyUser?: boolean;             // Send notification email
}

Query Parameters

None

Response (200 OK)

typescript
interface ActivateUserResponse {
  userId: string;
  status: 'ACTIVE';
  activatedAt: string;
  activatedBy: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404USER_NOT_FOUNDUser not found
400NOT_SUSPENDEDUser is not suspended

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/admin/users/550e8400-e29b-41d4-a716-446655440000/activate \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "note": "Investigation completed, no violation found",
    "notifyUser": true
  }'

Response:

json
{
  "success": true,
  "data": {
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "status": "ACTIVE",
    "activatedAt": "2024-01-16T10:00:00Z",
    "activatedBy": "Admin User"
  }
}

KYC Management Endpoints

GET /api/v1/admin/kyc/queue

Get KYC submissions pending review.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 50 (optional)
statusstringFilter: 'SUBMITTED', 'UNDER_REVIEW', 'NEEDS_INFO' (optional)
prioritystringFilter: 'HIGH', 'NORMAL', 'LOW' (optional)
sortBystringSort field: 'submittedAt', 'priority' (optional)
sortOrderstringSort direction: 'asc', 'desc' (optional)

Response (200 OK)

typescript
interface KycQueueResponse {
  submissions: KycQueueItem[];
  stats: {
    pending: number;
    underReview: number;
    needsInfo: number;
    averageProcessingTime: number;   // Hours
  };
}

interface KycQueueItem {
  id: string;
  user: {
    id: string;
    email: string;
    name: string;
  };
  status: string;
  level: string;
  priority: 'HIGH' | 'NORMAL' | 'LOW';
  submittedAt: string;
  assignedTo: string | null;
  documentsCount: number;
  waitingTime: number;               // Hours
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions

Example

Request:

bash
curl -X GET "https://api.iwm-platform.com/api/v1/admin/kyc/queue?status=SUBMITTED&sortBy=submittedAt&sortOrder=asc" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response:

json
{
  "success": true,
  "data": {
    "submissions": [
      {
        "id": "kyc-002",
        "user": {
          "id": "660e8400-e29b-41d4-a716-446655440000",
          "email": "newuser@example.com",
          "name": "Alice Smith"
        },
        "status": "SUBMITTED",
        "level": "STANDARD",
        "priority": "NORMAL",
        "submittedAt": "2024-01-15T10:00:00Z",
        "assignedTo": null,
        "documentsCount": 2,
        "waitingTime": 11
      }
    ],
    "stats": {
      "pending": 12,
      "underReview": 5,
      "needsInfo": 3,
      "averageProcessingTime": 24
    }
  },
  "meta": {
    "pagination": {
      "total": 12,
      "page": 1,
      "pageSize": 20,
      "totalPages": 1,
      "hasNext": false,
      "hasPrevious": false
    }
  }
}

GET /api/v1/admin/kyc/:id

Get KYC submission details.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)KYC verification ID

Request Body

None

Query Parameters

None

Response (200 OK)

typescript
interface KycDetailResponse {
  id: string;
  user: {
    id: string;
    email: string;
    name: string;
    phone: string | null;
    createdAt: string;
  };
  status: string;
  level: string;
  personalInfo: {
    firstName: string;
    lastName: string;
    middleName: string | null;
    dateOfBirth: string;
    nationality: string;
    documentNumber: string;
    documentType: string;
    documentIssueDate: string;
    documentExpiryDate: string;
    address: {
      country: string;
      region: string;
      city: string;
      street: string;
      building: string;
      apartment: string | null;
      postalCode: string;
    };
  };
  documents: {
    id: string;
    type: string;
    fileName: string;
    fileUrl: string;
    thumbnailUrl: string;
    status: string;
    ocrData: Record<string, string> | null;
    uploadedAt: string;
  }[];
  history: {
    action: string;
    performedBy: string | null;
    note: string | null;
    timestamp: string;
  }[];
  submittedAt: string;
  reviewedAt: string | null;
  reviewedBy: string | null;
  rejectionReason: string | null;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404KYC_NOT_FOUNDKYC verification not found

POST /api/v1/admin/kyc/:id/approve

Approve KYC submission.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)KYC verification ID

Request Body

typescript
interface ApproveKycRequest {
  level: 'BASIC' | 'STANDARD' | 'ENHANCED';
  note?: string;
  expiresAt?: string;               // Override default expiry (ISO 8601)
}

Query Parameters

None

Response (200 OK)

typescript
interface ApproveKycResponse {
  id: string;
  userId: string;
  status: 'APPROVED';
  level: string;
  approvedAt: string;
  approvedBy: string;
  expiresAt: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid level
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404KYC_NOT_FOUNDKYC verification not found
400NOT_REVIEWABLEKYC is not in reviewable status

Example

Request:

bash
curl -X POST https://api.iwm-platform.com/api/v1/admin/kyc/kyc-002/approve \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "level": "STANDARD",
    "note": "All documents verified successfully"
  }'

Response:

json
{
  "success": true,
  "data": {
    "id": "kyc-002",
    "userId": "660e8400-e29b-41d4-a716-446655440000",
    "status": "APPROVED",
    "level": "STANDARD",
    "approvedAt": "2024-01-15T21:30:00Z",
    "approvedBy": "Admin User",
    "expiresAt": "2025-01-15T21:30:00Z"
  }
}

POST /api/v1/admin/kyc/:id/reject

Reject KYC submission.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)KYC verification ID

Request Body

typescript
interface RejectKycRequest {
  reason: string;                   // Rejection reason
  rejectedDocuments?: {
    documentId: string;
    reason: string;
  }[];
  allowResubmission?: boolean;      // Allow user to resubmit
}

Query Parameters

None

Response (200 OK)

typescript
interface RejectKycResponse {
  id: string;
  userId: string;
  status: 'REJECTED';
  reason: string;
  rejectedAt: string;
  rejectedBy: string;
  canResubmit: boolean;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORReason not provided
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404KYC_NOT_FOUNDKYC verification not found
400NOT_REVIEWABLEKYC is not in reviewable status

Partner Management Endpoints

GET /api/v1/admin/partners

List all partners.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 100 (optional)
statusstringFilter: 'ACTIVE', 'SUSPENDED', 'TERMINATED', 'ALL' (optional)
rankstringFilter by rank code (optional)
searchstringSearch by name or referral code (optional)
sortBystringSort field: 'createdAt', 'totalEarned', 'networkSize' (optional)
sortOrderstringSort direction: 'asc', 'desc' (optional)

Response (200 OK)

typescript
interface AdminPartnersResponse {
  partners: AdminPartner[];
}

interface AdminPartner {
  id: string;
  user: {
    id: string;
    email: string;
    name: string;
  };
  referralCode: string;
  status: string;
  rank: {
    name: string;
    code: string;
  } | null;
  sponsor: {
    id: string;
    name: string;
  } | null;
  stats: {
    directReferrals: number;
    networkSize: number;
    totalEarned: number;
    totalWithdrawn: number;
    availableBalance: number;
    pendingBalance: number;
  };
  joinedAt: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions

GET /api/v1/admin/partners/:id

Get partner details.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Partner ID

Request Body

None

Query Parameters

None

Response (200 OK)

typescript
interface AdminPartnerDetailResponse {
  id: string;
  user: {
    id: string;
    email: string;
    name: string;
    phone: string | null;
    status: string;
  };
  referralCode: string;
  status: string;
  rank: {
    id: string;
    name: string;
    code: string;
    level: number;
  } | null;
  highestRank: {
    name: string;
    code: string;
    achievedAt: string;
  } | null;
  sponsor: {
    id: string;
    name: string;
    referralCode: string;
  } | null;
  balance: {
    available: number;
    pending: number;
    totalEarned: number;
    totalWithdrawn: number;
    careerPointsTotal: number;
    careerPointsPeriod: number;
    currency: string;
  };
  stats: {
    directReferrals: number;
    networkSize: number;
    treeDepth: number;
    activeReferrals: number;
    commissionsCount: number;
    payoutsCount: number;
  };
  payoutDetails: {
    method: string;
    maskedDetails: string;
    lastUpdated: string;
  } | null;
  recentCommissions: {
    id: string;
    amount: number;
    sourceType: string;
    status: string;
    createdAt: string;
  }[];
  recentPayouts: {
    id: string;
    amount: number;
    status: string;
    createdAt: string;
  }[];
  joinedAt: string;
  activatedAt: string | null;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404PARTNER_NOT_FOUNDPartner not found

GET /api/v1/admin/partners/:id/network

Get partner's network tree.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Partner ID

Request Body

None

Query Parameters

ParameterTypeDescription
depthnumberMaximum depth level, 1-10 (optional)
pagenumberPage number (optional)
pageSizenumberItems per page, max 100 (optional)

Response (200 OK)

typescript
interface AdminPartnerNetworkResponse {
  partnerId: string;
  partnerName: string;
  network: NetworkNode[];
  stats: {
    totalSize: number;
    byLevel: {
      level: number;
      count: number;
      volume: number;
    }[];
  };
}

interface NetworkNode {
  id: string;
  name: string;
  email: string;
  referralCode: string;
  level: number;
  status: string;
  rank: string | null;
  directReferrals: number;
  totalVolume: number;
  joinedAt: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404PARTNER_NOT_FOUNDPartner not found

Commission Management Endpoints

GET /api/v1/admin/commissions

List all commission transactions.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 100 (optional)
statusstringFilter: 'PENDING', 'APPROVED', 'PAID', 'HELD', 'REVERSED', 'ALL' (optional)
sourceTypestringFilter: 'ORDER', 'INVESTMENT', 'BONUS', 'RANK_BONUS' (optional)
partnerIdstringFilter by partner UUID (optional)
dateFromstringStart date (ISO 8601) (optional)
dateTostringEnd date (ISO 8601) (optional)
minAmountnumberMinimum amount filter (optional)
sortBystringSort field: 'createdAt', 'amount', 'status' (optional)
sortOrderstringSort direction: 'asc', 'desc' (optional)

Response (200 OK)

typescript
interface AdminCommissionsResponse {
  commissions: AdminCommission[];
  summary: {
    totalPending: number;
    totalApproved: number;
    totalPaid: number;
    totalReversed: number;
  };
}

interface AdminCommission {
  id: string;
  partner: {
    id: string;
    name: string;
    referralCode: string;
  };
  sourceType: string;
  sourceId: string;
  sourcePartner: {
    id: string;
    name: string;
  } | null;
  levelDepth: number | null;
  grossAmount: number;
  netAmount: number;
  careerPoints: number;
  currency: string;
  status: string;
  periodId: string | null;
  processedAt: string | null;
  approvedBy: string | null;
  createdAt: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions

POST /api/v1/admin/commissions/:id/adjust

Adjust a commission transaction.

Authentication: Required (ADMIN)

Rate Limit: 10 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Commission ID

Request Body

typescript
interface AdjustCommissionRequest {
  action: 'APPROVE' | 'HOLD' | 'REVERSE' | 'ADJUST_AMOUNT';
  newAmount?: number;               // For ADJUST_AMOUNT action
  reason: string;                   // Reason for adjustment
}

Query Parameters

None

Response (200 OK)

typescript
interface AdjustCommissionResponse {
  id: string;
  previousStatus: string;
  newStatus: string;
  previousAmount: number | null;
  newAmount: number | null;
  adjustedAt: string;
  adjustedBy: string;
  reason: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid action or reason not provided
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404COMMISSION_NOT_FOUNDCommission not found
400CANNOT_ADJUSTCommission cannot be adjusted in current status

Payout Management Endpoints

GET /api/v1/admin/payouts

List all payout requests.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 100 (optional)
statusstringFilter: 'PENDING', 'APPROVED', 'PROCESSING', 'COMPLETED', 'REJECTED', 'CANCELLED', 'ALL' (optional)
partnerIdstringFilter by partner UUID (optional)
dateFromstringStart date (ISO 8601) (optional)
dateTostringEnd date (ISO 8601) (optional)
minAmountnumberMinimum amount filter (optional)

Response (200 OK)

typescript
interface AdminPayoutsResponse {
  payouts: AdminPayout[];
  summary: {
    pendingCount: number;
    pendingAmount: number;
    processingCount: number;
    processingAmount: number;
  };
}

interface AdminPayout {
  id: string;
  partner: {
    id: string;
    name: string;
    referralCode: string;
  };
  amount: number;
  currency: string;
  method: {
    type: string;
    maskedDetails: string;
  };
  status: string;
  rejectionReason: string | null;
  externalReference: string | null;
  processedBy: string | null;
  processedAt: string | null;
  completedAt: string | null;
  createdAt: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions

POST /api/v1/admin/payouts/:id/approve

Approve a payout request.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Payout request ID

Request Body

typescript
interface ApprovePayoutRequest {
  note?: string;
}

Query Parameters

None

Response (200 OK)

typescript
interface ApprovePayoutResponse {
  id: string;
  status: 'APPROVED';
  approvedAt: string;
  approvedBy: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404PAYOUT_NOT_FOUNDPayout request not found
400NOT_PENDINGPayout is not in pending status

POST /api/v1/admin/payouts/:id/reject

Reject a payout request.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Payout request ID

Request Body

typescript
interface RejectPayoutRequest {
  reason: string;                   // Rejection reason
  returnToBalance?: boolean;        // Return funds to partner balance
}

Query Parameters

None

Response (200 OK)

typescript
interface RejectPayoutResponse {
  id: string;
  status: 'REJECTED';
  reason: string;
  rejectedAt: string;
  rejectedBy: string;
  fundsReturned: boolean;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORReason not provided
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404PAYOUT_NOT_FOUNDPayout request not found
400NOT_REJECTABLEPayout cannot be rejected in current status

POST /api/v1/admin/payouts/:id/process

Process a payout (initiate payment).

Authentication: Required (ADMIN)

Rate Limit: 5 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Payout request ID

Request Body

typescript
interface ProcessPayoutRequest {
  externalReference?: string;       // External transaction reference
}

Query Parameters

None

Response (200 OK)

typescript
interface ProcessPayoutResponse {
  id: string;
  status: 'PROCESSING' | 'COMPLETED';
  externalReference: string | null;
  processedAt: string;
  processedBy: string;
  estimatedCompletion: string | null;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404PAYOUT_NOT_FOUNDPayout request not found
400NOT_APPROVEDPayout must be approved first
400PAYMENT_FAILEDPayment processing failed

Order Management Endpoints

GET /api/v1/admin/orders

List all orders.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 100 (optional)
statusstringFilter by order status (optional)
paymentStatusstringFilter by payment status (optional)
userIdstringFilter by user UUID (optional)
dateFromstringStart date (ISO 8601) (optional)
dateTostringEnd date (ISO 8601) (optional)
searchstringSearch by order number or user email (optional)

Response (200 OK)

typescript
interface AdminOrdersResponse {
  orders: AdminOrder[];
  summary: {
    totalOrders: number;
    totalRevenue: number;
    pendingPayment: number;
    processing: number;
    shipped: number;
  };
}

interface AdminOrder {
  id: string;
  orderNumber: string;
  user: {
    id: string;
    email: string;
    name: string;
  };
  status: string;
  paymentStatus: string;
  itemCount: number;
  total: number;
  currency: string;
  shippingMethod: string;
  createdAt: string;
  updatedAt: string;
}

PATCH /api/v1/admin/orders/:id

Update order.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Order ID

Request Body

typescript
interface AdminUpdateOrderRequest {
  status?: 'PROCESSING' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED';
  trackingNumber?: string;
  trackingUrl?: string;
  note?: string;
  notifyCustomer?: boolean;
}

Query Parameters

None

Response (200 OK)

typescript
interface AdminUpdateOrderResponse {
  id: string;
  orderNumber: string;
  status: string;
  trackingNumber: string | null;
  updatedAt: string;
  updatedBy: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid status transition
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404ORDER_NOT_FOUNDOrder not found

Product Management Endpoints

GET /api/v1/admin/products

List products with admin details.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 100 (optional)
statusstringFilter: 'ACTIVE', 'DRAFT', 'ARCHIVED', 'OUT_OF_STOCK', 'ALL' (optional)
categoryIdstringFilter by category (optional)
searchstringSearch by name or SKU (optional)

Response (200 OK)

typescript
interface AdminProductsResponse {
  products: AdminProduct[];
}

interface AdminProduct {
  id: string;
  name: string;
  sku: string;
  status: string;
  price: number;
  compareAtPrice: number | null;
  stockQuantity: number | null;
  category: string | null;
  ordersCount: number;
  totalRevenue: number;
  commissionPercentage: number;
  createdAt: string;
  updatedAt: string;
}

POST /api/v1/admin/products

Create a new product.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

typescript
interface CreateProductRequest {
  name: string;
  description: string;
  shortDescription?: string;
  price: number;
  compareAtPrice?: number;
  sku: string;
  categoryId?: string;
  status: 'ACTIVE' | 'DRAFT' | 'ARCHIVED';
  stockQuantity?: number;
  trackInventory?: boolean;
  weight?: number;
  dimensions?: {
    length: number;
    width: number;
    height: number;
  };
  attributes?: Record<string, string>;
  tags?: string[];
  commissionPercentage: number;
  careerPointsPercentage: number;
}

Query Parameters

None

Response (201 Created)

typescript
interface CreateProductResponse {
  id: string;
  name: string;
  slug: string;
  sku: string;
  status: string;
  createdAt: string;
  createdBy: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
409SKU_ALREADY_EXISTSSKU is already in use

PATCH /api/v1/admin/products/:id

Update a product.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Product ID

Request Body

typescript
interface UpdateProductRequest {
  name?: string;
  description?: string;
  shortDescription?: string;
  price?: number;
  compareAtPrice?: number | null;
  sku?: string;
  categoryId?: string | null;
  status?: 'ACTIVE' | 'DRAFT' | 'ARCHIVED' | 'OUT_OF_STOCK';
  stockQuantity?: number | null;
  trackInventory?: boolean;
  weight?: number | null;
  dimensions?: {
    length: number;
    width: number;
    height: number;
  } | null;
  attributes?: Record<string, string>;
  tags?: string[];
  commissionPercentage?: number;
  careerPointsPercentage?: number;
}

Query Parameters

None

Response (200 OK)

typescript
interface UpdateProductResponse {
  id: string;
  name: string;
  sku: string;
  status: string;
  updatedAt: string;
  updatedBy: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404PRODUCT_NOT_FOUNDProduct not found
409SKU_ALREADY_EXISTSSKU is already in use

DELETE /api/v1/admin/products/:id

Delete a product (soft delete).

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Product ID

Request Body

None

Query Parameters

None

Response (200 OK)

typescript
interface DeleteProductResponse {
  id: string;
  status: 'ARCHIVED';
  deletedAt: string;
  deletedBy: string;
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404PRODUCT_NOT_FOUNDProduct not found
400HAS_PENDING_ORDERSCannot delete product with pending orders

Strategy Management Endpoints

GET /api/v1/admin/strategies

List strategies with admin details.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
pagenumberPage number (optional)
pageSizenumberItems per page, max 50 (optional)
statusstringFilter: 'ACTIVE', 'PAUSED', 'CLOSED', 'ALL' (optional)
categoryIdstringFilter by category (optional)

Response (200 OK)

typescript
interface AdminStrategiesResponse {
  strategies: AdminStrategy[];
}

interface AdminStrategy {
  id: string;
  name: string;
  status: string;
  riskLevel: string;
  returnRate: {
    min: number;
    max: number;
    expected: number;
  };
  capacity: {
    total: number | null;
    used: number;
    available: number | null;
  };
  participants: {
    total: number;
    active: number;
  };
  financials: {
    totalInvested: number;
    totalReturnsDistributed: number;
    pendingReturns: number;
  };
  createdAt: string;
  updatedAt: string;
}

POST /api/v1/admin/strategies

Create a new strategy.

Authentication: Required (SUPER_ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

typescript
interface CreateStrategyRequest {
  name: string;
  description: string;
  shortDescription: string;
  categoryId: string;
  returnRate: {
    min: number;
    max: number;
    expected: number;
    type: 'FIXED' | 'VARIABLE';
    payoutFrequency: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'END_OF_TERM';
  };
  duration: {
    minDays: number;
    maxDays: number;
    lockPeriodDays: number;
  };
  investment: {
    minAmount: number;
    maxAmount: number | null;
    currency: string;
    totalCapacity: number | null;
  };
  riskLevel: 'LOW' | 'MEDIUM' | 'HIGH';
  riskDisclosure: string;
  terms: {
    earlyWithdrawalAllowed: boolean;
    earlyWithdrawalPenalty: number | null;
    compoundingAvailable: boolean;
    automaticReinvestment: boolean;
  };
  commissionPercentage: number;
  careerPointsPercentage: number;
  status: 'ACTIVE' | 'PAUSED' | 'CLOSED';
}

Query Parameters

None

Response (201 Created)

typescript
interface CreateStrategyResponse {
  id: string;
  name: string;
  slug: string;
  status: string;
  createdAt: string;
  createdBy: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENRequires SUPER_ADMIN role
404CATEGORY_NOT_FOUNDCategory not found

PATCH /api/v1/admin/strategies/:id

Update a strategy.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Path Parameters

ParameterTypeDescription
idstring (UUID)Strategy ID

Request Body

typescript
interface UpdateStrategyRequest {
  name?: string;
  description?: string;
  shortDescription?: string;
  categoryId?: string;
  returnRate?: {
    min?: number;
    max?: number;
    expected?: number;
  };
  investment?: {
    minAmount?: number;
    maxAmount?: number | null;
    totalCapacity?: number | null;
  };
  riskDisclosure?: string;
  terms?: {
    earlyWithdrawalAllowed?: boolean;
    earlyWithdrawalPenalty?: number | null;
    compoundingAvailable?: boolean;
    automaticReinvestment?: boolean;
  };
  commissionPercentage?: number;
  careerPointsPercentage?: number;
  status?: 'ACTIVE' | 'PAUSED' | 'CLOSED';
}

Query Parameters

None

Response (200 OK)

typescript
interface UpdateStrategyResponse {
  id: string;
  name: string;
  status: string;
  updatedAt: string;
  updatedBy: string;
}

Error Responses

StatusCodeDescription
400VALIDATION_ERRORInvalid input data
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions
404STRATEGY_NOT_FOUNDStrategy not found
400HAS_ACTIVE_PARTICIPATIONSCannot close strategy with active participations

Analytics Endpoints

GET /api/v1/admin/analytics/dashboard

Get dashboard statistics.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
periodstringTime period: 'TODAY', 'WEEK', 'MONTH', 'QUARTER', 'YEAR' (optional)

Response (200 OK)

typescript
interface DashboardResponse {
  period: string;
  periodStart: string;
  periodEnd: string;
  users: {
    total: number;
    newInPeriod: number;
    active: number;
    suspended: number;
    growth: number;              // Percentage
  };
  partners: {
    total: number;
    newInPeriod: number;
    active: number;
    growth: number;
  };
  orders: {
    total: number;
    inPeriod: number;
    revenue: number;
    averageOrderValue: number;
    growth: number;
  };
  investments: {
    totalParticipations: number;
    inPeriod: number;
    totalInvested: number;
    activeInvestments: number;
    growth: number;
  };
  commissions: {
    totalPaid: number;
    paidInPeriod: number;
    pending: number;
    growth: number;
  };
  payouts: {
    totalProcessed: number;
    processedInPeriod: number;
    pending: number;
    pendingAmount: number;
  };
  quickStats: {
    conversionRate: number;
    averagePartnerEarnings: number;
    partnerRetentionRate: number;
    investmentRetentionRate: number;
  };
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions

GET /api/v1/admin/analytics/sales

Get sales analytics.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
periodstringTime period: 'WEEK', 'MONTH', 'QUARTER', 'YEAR' (optional)
granularitystringData granularity: 'DAY', 'WEEK', 'MONTH' (optional)
categoryIdstringFilter by product category (optional)

Response (200 OK)

typescript
interface SalesAnalyticsResponse {
  period: string;
  periodStart: string;
  periodEnd: string;
  summary: {
    totalRevenue: number;
    totalOrders: number;
    averageOrderValue: number;
    totalCustomers: number;
    newCustomers: number;
    repeatCustomers: number;
  };
  timeline: {
    date: string;
    revenue: number;
    orders: number;
    averageOrderValue: number;
  }[];
  byCategory: {
    categoryId: string;
    categoryName: string;
    revenue: number;
    orders: number;
    percentage: number;
  }[];
  topProducts: {
    productId: string;
    productName: string;
    revenue: number;
    quantity: number;
  }[];
  byPaymentMethod: {
    method: string;
    count: number;
    amount: number;
    percentage: number;
  }[];
  byRegion: {
    region: string;
    revenue: number;
    orders: number;
  }[];
}

GET /api/v1/admin/analytics/commissions

Get commission analytics.

Authentication: Required (ADMIN)

Rate Limit: 200 requests per minute

Request Headers

Authorization: Bearer <access_token>

Request Body

None

Query Parameters

ParameterTypeDescription
periodstringTime period: 'WEEK', 'MONTH', 'QUARTER', 'YEAR' (optional)
granularitystringData granularity: 'DAY', 'WEEK', 'MONTH' (optional)

Response (200 OK)

typescript
interface CommissionAnalyticsResponse {
  period: string;
  periodStart: string;
  periodEnd: string;
  summary: {
    totalGenerated: number;
    totalPaid: number;
    totalPending: number;
    totalReversed: number;
    averageCommission: number;
    partnersEarning: number;
  };
  timeline: {
    date: string;
    generated: number;
    paid: number;
    reversed: number;
  }[];
  bySource: {
    sourceType: string;
    total: number;
    count: number;
    percentage: number;
  }[];
  byLevel: {
    level: number;
    total: number;
    count: number;
    averageAmount: number;
  }[];
  byRank: {
    rankCode: string;
    rankName: string;
    partnersCount: number;
    totalEarned: number;
    averageEarned: number;
  }[];
  topEarners: {
    partnerId: string;
    partnerName: string;
    rank: string | null;
    totalEarned: number;
    commissionsCount: number;
  }[];
  payoutStats: {
    totalRequested: number;
    totalApproved: number;
    totalProcessed: number;
    averageProcessingTime: number;   // Hours
  };
}

Error Responses

StatusCodeDescription
401UNAUTHORIZEDInvalid or expired access token
403FORBIDDENInsufficient permissions