Admin API
Common Information
Base URL
/api/v1/adminAuthentication Header
Authorization: Bearer <access_token>Required Roles
All endpoints in this API require one of the following roles:
ADMIN- Standard admin accessSUPER_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:
// 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
interface PaginationMeta {
total: number;
page: number;
pageSize: number;
totalPages: number;
hasNext: boolean;
hasPrevious: boolean;
}Rate Limits
| Endpoint | Limit |
|---|---|
| General admin endpoints | 200/min |
| POST /commissions/:id/adjust | 10/min |
| POST /payouts/:id/process | 5/min |
| Bulk operations | 30/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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 100 (optional) |
| status | string | Filter: 'PENDING_VERIFICATION', 'ACTIVE', 'SUSPENDED', 'BANNED', 'ALL' (optional) |
| role | string | Filter by role: 'USER', 'ADMIN', 'SUPER_ADMIN' (optional) |
| kycStatus | string | Filter by KYC status (optional) |
| search | string | Search by email, name, or phone (optional) |
| dateFrom | string | Registration date from (ISO 8601) (optional) |
| dateTo | string | Registration date to (ISO 8601) (optional) |
| sortBy | string | Sort field: 'createdAt', 'email', 'status', 'lastLoginAt' (optional) |
| sortOrder | string | Sort direction: 'asc', 'desc' (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid query parameters |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
Example
Request:
curl -X GET "https://api.iwm-platform.com/api/v1/admin/users?status=ACTIVE&page=1&pageSize=20" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response:
{
"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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | User ID |
Request Body
None
Query Parameters
None
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | USER_NOT_FOUND | User not found |
Example
Request:
curl -X GET https://api.iwm-platform.com/api/v1/admin/users/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response:
{
"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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | User ID |
Request Body
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)
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
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid input data |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 403 | CANNOT_MODIFY_SUPER_ADMIN | Cannot modify SUPER_ADMIN user |
| 404 | USER_NOT_FOUND | User not found |
| 409 | EMAIL_ALREADY_EXISTS | Email is already in use |
Example
Request:
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:
{
"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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | User ID |
Request Body
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)
interface SuspendUserResponse {
userId: string;
status: 'SUSPENDED';
reason: string;
suspendedAt: string;
suspendedBy: string;
suspendedUntil: string | null;
sessionsRevoked: number;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Reason not provided |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 403 | CANNOT_SUSPEND_ADMIN | Cannot suspend admin user |
| 404 | USER_NOT_FOUND | User not found |
| 400 | ALREADY_SUSPENDED | User is already suspended |
Example
Request:
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:
{
"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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | User ID |
Request Body
interface ActivateUserRequest {
note?: string; // Optional note
notifyUser?: boolean; // Send notification email
}Query Parameters
None
Response (200 OK)
interface ActivateUserResponse {
userId: string;
status: 'ACTIVE';
activatedAt: string;
activatedBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | USER_NOT_FOUND | User not found |
| 400 | NOT_SUSPENDED | User is not suspended |
Example
Request:
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:
{
"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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 50 (optional) |
| status | string | Filter: 'SUBMITTED', 'UNDER_REVIEW', 'NEEDS_INFO' (optional) |
| priority | string | Filter: 'HIGH', 'NORMAL', 'LOW' (optional) |
| sortBy | string | Sort field: 'submittedAt', 'priority' (optional) |
| sortOrder | string | Sort direction: 'asc', 'desc' (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
Example
Request:
curl -X GET "https://api.iwm-platform.com/api/v1/admin/kyc/queue?status=SUBMITTED&sortBy=submittedAt&sortOrder=asc" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Response:
{
"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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | KYC verification ID |
Request Body
None
Query Parameters
None
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | KYC_NOT_FOUND | KYC 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | KYC verification ID |
Request Body
interface ApproveKycRequest {
level: 'BASIC' | 'STANDARD' | 'ENHANCED';
note?: string;
expiresAt?: string; // Override default expiry (ISO 8601)
}Query Parameters
None
Response (200 OK)
interface ApproveKycResponse {
id: string;
userId: string;
status: 'APPROVED';
level: string;
approvedAt: string;
approvedBy: string;
expiresAt: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid level |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | KYC_NOT_FOUND | KYC verification not found |
| 400 | NOT_REVIEWABLE | KYC is not in reviewable status |
Example
Request:
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:
{
"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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | KYC verification ID |
Request Body
interface RejectKycRequest {
reason: string; // Rejection reason
rejectedDocuments?: {
documentId: string;
reason: string;
}[];
allowResubmission?: boolean; // Allow user to resubmit
}Query Parameters
None
Response (200 OK)
interface RejectKycResponse {
id: string;
userId: string;
status: 'REJECTED';
reason: string;
rejectedAt: string;
rejectedBy: string;
canResubmit: boolean;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Reason not provided |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | KYC_NOT_FOUND | KYC verification not found |
| 400 | NOT_REVIEWABLE | KYC 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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 100 (optional) |
| status | string | Filter: 'ACTIVE', 'SUSPENDED', 'TERMINATED', 'ALL' (optional) |
| rank | string | Filter by rank code (optional) |
| search | string | Search by name or referral code (optional) |
| sortBy | string | Sort field: 'createdAt', 'totalEarned', 'networkSize' (optional) |
| sortOrder | string | Sort direction: 'asc', 'desc' (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Partner ID |
Request Body
None
Query Parameters
None
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | PARTNER_NOT_FOUND | Partner 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Partner ID |
Request Body
None
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| depth | number | Maximum depth level, 1-10 (optional) |
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 100 (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | PARTNER_NOT_FOUND | Partner 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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 100 (optional) |
| status | string | Filter: 'PENDING', 'APPROVED', 'PAID', 'HELD', 'REVERSED', 'ALL' (optional) |
| sourceType | string | Filter: 'ORDER', 'INVESTMENT', 'BONUS', 'RANK_BONUS' (optional) |
| partnerId | string | Filter by partner UUID (optional) |
| dateFrom | string | Start date (ISO 8601) (optional) |
| dateTo | string | End date (ISO 8601) (optional) |
| minAmount | number | Minimum amount filter (optional) |
| sortBy | string | Sort field: 'createdAt', 'amount', 'status' (optional) |
| sortOrder | string | Sort direction: 'asc', 'desc' (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Commission ID |
Request Body
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)
interface AdjustCommissionResponse {
id: string;
previousStatus: string;
newStatus: string;
previousAmount: number | null;
newAmount: number | null;
adjustedAt: string;
adjustedBy: string;
reason: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid action or reason not provided |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | COMMISSION_NOT_FOUND | Commission not found |
| 400 | CANNOT_ADJUST | Commission 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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 100 (optional) |
| status | string | Filter: 'PENDING', 'APPROVED', 'PROCESSING', 'COMPLETED', 'REJECTED', 'CANCELLED', 'ALL' (optional) |
| partnerId | string | Filter by partner UUID (optional) |
| dateFrom | string | Start date (ISO 8601) (optional) |
| dateTo | string | End date (ISO 8601) (optional) |
| minAmount | number | Minimum amount filter (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Payout request ID |
Request Body
interface ApprovePayoutRequest {
note?: string;
}Query Parameters
None
Response (200 OK)
interface ApprovePayoutResponse {
id: string;
status: 'APPROVED';
approvedAt: string;
approvedBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | PAYOUT_NOT_FOUND | Payout request not found |
| 400 | NOT_PENDING | Payout 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Payout request ID |
Request Body
interface RejectPayoutRequest {
reason: string; // Rejection reason
returnToBalance?: boolean; // Return funds to partner balance
}Query Parameters
None
Response (200 OK)
interface RejectPayoutResponse {
id: string;
status: 'REJECTED';
reason: string;
rejectedAt: string;
rejectedBy: string;
fundsReturned: boolean;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Reason not provided |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | PAYOUT_NOT_FOUND | Payout request not found |
| 400 | NOT_REJECTABLE | Payout 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Payout request ID |
Request Body
interface ProcessPayoutRequest {
externalReference?: string; // External transaction reference
}Query Parameters
None
Response (200 OK)
interface ProcessPayoutResponse {
id: string;
status: 'PROCESSING' | 'COMPLETED';
externalReference: string | null;
processedAt: string;
processedBy: string;
estimatedCompletion: string | null;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | PAYOUT_NOT_FOUND | Payout request not found |
| 400 | NOT_APPROVED | Payout must be approved first |
| 400 | PAYMENT_FAILED | Payment 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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 100 (optional) |
| status | string | Filter by order status (optional) |
| paymentStatus | string | Filter by payment status (optional) |
| userId | string | Filter by user UUID (optional) |
| dateFrom | string | Start date (ISO 8601) (optional) |
| dateTo | string | End date (ISO 8601) (optional) |
| search | string | Search by order number or user email (optional) |
Response (200 OK)
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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Order ID |
Request Body
interface AdminUpdateOrderRequest {
status?: 'PROCESSING' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED';
trackingNumber?: string;
trackingUrl?: string;
note?: string;
notifyCustomer?: boolean;
}Query Parameters
None
Response (200 OK)
interface AdminUpdateOrderResponse {
id: string;
orderNumber: string;
status: string;
trackingNumber: string | null;
updatedAt: string;
updatedBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid status transition |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | ORDER_NOT_FOUND | Order 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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 100 (optional) |
| status | string | Filter: 'ACTIVE', 'DRAFT', 'ARCHIVED', 'OUT_OF_STOCK', 'ALL' (optional) |
| categoryId | string | Filter by category (optional) |
| search | string | Search by name or SKU (optional) |
Response (200 OK)
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
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)
interface CreateProductResponse {
id: string;
name: string;
slug: string;
sku: string;
status: string;
createdAt: string;
createdBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid input data |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 409 | SKU_ALREADY_EXISTS | SKU 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Product ID |
Request Body
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)
interface UpdateProductResponse {
id: string;
name: string;
sku: string;
status: string;
updatedAt: string;
updatedBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid input data |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | PRODUCT_NOT_FOUND | Product not found |
| 409 | SKU_ALREADY_EXISTS | SKU 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Product ID |
Request Body
None
Query Parameters
None
Response (200 OK)
interface DeleteProductResponse {
id: string;
status: 'ARCHIVED';
deletedAt: string;
deletedBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | PRODUCT_NOT_FOUND | Product not found |
| 400 | HAS_PENDING_ORDERS | Cannot 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
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (optional) |
| pageSize | number | Items per page, max 50 (optional) |
| status | string | Filter: 'ACTIVE', 'PAUSED', 'CLOSED', 'ALL' (optional) |
| categoryId | string | Filter by category (optional) |
Response (200 OK)
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
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)
interface CreateStrategyResponse {
id: string;
name: string;
slug: string;
status: string;
createdAt: string;
createdBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid input data |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Requires SUPER_ADMIN role |
| 404 | CATEGORY_NOT_FOUND | Category 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
| Parameter | Type | Description |
|---|---|---|
| id | string (UUID) | Strategy ID |
Request Body
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)
interface UpdateStrategyResponse {
id: string;
name: string;
status: string;
updatedAt: string;
updatedBy: string;
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid input data |
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | STRATEGY_NOT_FOUND | Strategy not found |
| 400 | HAS_ACTIVE_PARTICIPATIONS | Cannot 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
| Parameter | Type | Description |
|---|---|---|
| period | string | Time period: 'TODAY', 'WEEK', 'MONTH', 'QUARTER', 'YEAR' (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient 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
| Parameter | Type | Description |
|---|---|---|
| period | string | Time period: 'WEEK', 'MONTH', 'QUARTER', 'YEAR' (optional) |
| granularity | string | Data granularity: 'DAY', 'WEEK', 'MONTH' (optional) |
| categoryId | string | Filter by product category (optional) |
Response (200 OK)
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
| Parameter | Type | Description |
|---|---|---|
| period | string | Time period: 'WEEK', 'MONTH', 'QUARTER', 'YEAR' (optional) |
| granularity | string | Data granularity: 'DAY', 'WEEK', 'MONTH' (optional) |
Response (200 OK)
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
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or expired access token |
| 403 | FORBIDDEN | Insufficient permissions |