Skip to content

Admin User Management API

👑 Admin User Management

The Admin API provides comprehensive user management capabilities for superuser administrators. All endpoints require superuser privileges and allow full CRUD operations on user accounts, including activation/deactivation and privilege management.

Base URL

All admin endpoints are prefixed with:

/api/v1/admin/users/

Authentication

All admin endpoints require superuser authentication. Include the Bearer token in the Authorization header:

Authorization: Bearer <superuser_jwt_token>

Note: Only accounts with is_superuser: true can access these endpoints.

Data Models

UserCreate

Used for creating new users with full admin control.

{
  "email": "john.doe@example.com",
  "password": "secure_password123",
  "full_name": "John Doe",
  "is_active": true,
  "is_superuser": false
}

UserUpdate

Used for updating existing user information.

{
  "email": "john.updated@example.com",
  "full_name": "John Updated",
  "is_active": true,
  "is_superuser": false
}

UserResponse

Standard user response format.

{
  "id": 123,
  "email": "john.doe@example.com",
  "full_name": "John Doe",
  "is_active": true,
  "is_superuser": false,
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:00Z"
}

Endpoints

Create User (Admin)

Create a new user account with full admin control over all fields.

POST /api/v1/admin/users/

Request Body

{
  "email": "newuser@example.com",
  "password": "secure_password123",
  "full_name": "New User",
  "is_active": true,
  "is_superuser": false
}

Response

Status Code: 201 Created

{
  "id": 124,
  "email": "newuser@example.com",
  "full_name": "New User",
  "is_active": true,
  "is_superuser": false,
  "created_at": "2025-01-15T11:00:00Z",
  "updated_at": "2025-01-15T11:00:00Z"
}

Error Responses

400 Bad Request - Validation error (e.g., email already exists)

{
  "detail": "Email already registered"
}


Get All Users

Retrieve a paginated list of all users in the system.

GET /api/v1/admin/users/

Query Parameters

Parameter Type Required Default Description
skip integer No 0 Number of users to skip (pagination)
limit integer No 100 Maximum number of users to return (1-1000)

Example Request

GET /api/v1/admin/users/?skip=0&limit=50

Response

Status Code: 200 OK

[
  {
    "id": 1,
    "email": "admin@example.com",
    "full_name": "System Admin",
    "is_active": true,
    "is_superuser": true,
    "created_at": "2025-01-01T00:00:00Z",
    "updated_at": "2025-01-01T00:00:00Z"
  },
  {
    "id": 2,
    "email": "user@example.com",
    "full_name": "Regular User",
    "is_active": true,
    "is_superuser": false,
    "created_at": "2025-01-10T12:00:00Z",
    "updated_at": "2025-01-10T12:00:00Z"
  }
]

Get User by ID

Retrieve detailed information about a specific user.

GET /api/v1/admin/users/{user_id}

Path Parameters

Parameter Type Description
user_id integer The ID of the user to retrieve

Response

Status Code: 200 OK

{
  "id": 123,
  "email": "john.doe@example.com",
  "full_name": "John Doe",
  "is_active": true,
  "is_superuser": false,
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:00Z"
}

Error Responses

404 Not Found - User does not exist

{
  "detail": "User not found"
}


Update User

Update user information with full admin privileges.

PUT /api/v1/admin/users/{user_id}

Path Parameters

Parameter Type Description
user_id integer The ID of the user to update

Request Body

{
  "email": "updated.email@example.com",
  "full_name": "Updated Name",
  "is_active": true,
  "is_superuser": false
}

Response

Status Code: 200 OK

{
  "id": 123,
  "email": "updated.email@example.com",
  "full_name": "Updated Name",
  "is_active": true,
  "is_superuser": false,
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T12:00:00Z"
}

Error Responses

400 Bad Request - Validation error

{
  "detail": "Email already in use by another user"
}

404 Not Found - User does not exist

{
  "detail": "User not found"
}


Delete User

Permanently delete a user account from the system.

DELETE /api/v1/admin/users/{user_id}

Path Parameters

Parameter Type Description
user_id integer The ID of the user to delete

Response

Status Code: 200 OK

{
  "message": "User deleted successfully"
}

Error Responses

400 Bad Request - Cannot delete own account

{
  "detail": "Cannot delete your own account"
}

404 Not Found - User does not exist

{
  "detail": "User not found"
}


Activate User

Activate a deactivated user account.

PATCH /api/v1/admin/users/{user_id}/activate

Path Parameters

Parameter Type Description
user_id integer The ID of the user to activate

Response

Status Code: 200 OK

{
  "id": 123,
  "email": "john.doe@example.com",
  "full_name": "John Doe",
  "is_active": true,
  "is_superuser": false,
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T12:30:00Z"
}

Error Responses

404 Not Found - User does not exist

{
  "detail": "User not found"
}


Deactivate User

Deactivate an active user account, preventing login.

PATCH /api/v1/admin/users/{user_id}/deactivate

Path Parameters

Parameter Type Description
user_id integer The ID of the user to deactivate

Response

Status Code: 200 OK

{
  "id": 123,
  "email": "john.doe@example.com",
  "full_name": "John Doe",
  "is_active": false,
  "is_superuser": false,
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T12:45:00Z"
}

Security Restrictions

400 Bad Request - Cannot deactivate own account

{
  "detail": "Cannot deactivate your own account"
}

404 Not Found - User does not exist

{
  "detail": "User not found"
}

Integration Examples

Python Example

import requests
from typing import List, Dict, Any, Optional

class QuantbotAdminClient:
    def __init__(self, base_url: str, superuser_token: str):
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {superuser_token}",
            "Content-Type": "application/json"
        }

    def create_user(self, email: str, password: str, full_name: str, 
                   is_active: bool = True, is_superuser: bool = False) -> Dict[str, Any]:
        """Create a new user"""
        response = requests.post(
            f"{self.base_url}/api/v1/admin/users/",
            headers=self.headers,
            json={
                "email": email,
                "password": password,
                "full_name": full_name,
                "is_active": is_active,
                "is_superuser": is_superuser
            }
        )
        response.raise_for_status()
        return response.json()

    def get_all_users(self, skip: int = 0, limit: int = 100) -> List[Dict[str, Any]]:
        """Get paginated list of all users"""
        response = requests.get(
            f"{self.base_url}/api/v1/admin/users/",
            headers=self.headers,
            params={"skip": skip, "limit": limit}
        )
        response.raise_for_status()
        return response.json()

    def get_user(self, user_id: int) -> Dict[str, Any]:
        """Get user by ID"""
        response = requests.get(
            f"{self.base_url}/api/v1/admin/users/{user_id}",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def update_user(self, user_id: int, **updates) -> Dict[str, Any]:
        """Update user information"""
        response = requests.put(
            f"{self.base_url}/api/v1/admin/users/{user_id}",
            headers=self.headers,
            json=updates
        )
        response.raise_for_status()
        return response.json()

    def delete_user(self, user_id: int) -> Dict[str, Any]:
        """Delete user account"""
        response = requests.delete(
            f"{self.base_url}/api/v1/admin/users/{user_id}",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def activate_user(self, user_id: int) -> Dict[str, Any]:
        """Activate user account"""
        response = requests.patch(
            f"{self.base_url}/api/v1/admin/users/{user_id}/activate",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

    def deactivate_user(self, user_id: int) -> Dict[str, Any]:
        """Deactivate user account"""
        response = requests.patch(
            f"{self.base_url}/api/v1/admin/users/{user_id}/deactivate",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

# Usage
admin_client = QuantbotAdminClient("http://localhost:8000", "superuser_access_token")

# Create a new user
new_user = admin_client.create_user(
    email="newuser@company.com",
    password="secure_password123",
    full_name="New Company User",
    is_active=True,
    is_superuser=False
)
print(f"✅ Created user: {new_user['email']} (ID: {new_user['id']})")

# Get all users with pagination
users = admin_client.get_all_users(skip=0, limit=50)
print(f"📊 Found {len(users)} users")

# Update user information
updated_user = admin_client.update_user(
    user_id=new_user['id'],
    full_name="Updated User Name",
    is_active=True
)
print(f"✏️ Updated user: {updated_user['full_name']}")

# Deactivate user
deactivated_user = admin_client.deactivate_user(new_user['id'])
print(f"🚫 Deactivated user: {deactivated_user['email']}")

# Reactivate user
activated_user = admin_client.activate_user(new_user['id'])
print(f"✅ Reactivated user: {activated_user['email']}")

TypeScript Example

interface User {
  id: number;
  email: string;
  full_name: string;
  is_active: boolean;
  is_superuser: boolean;
  created_at: string;
  updated_at: string;
}

interface CreateUserRequest {
  email: string;
  password: string;
  full_name: string;
  is_active?: boolean;
  is_superuser?: boolean;
}

interface UpdateUserRequest {
  email?: string;
  full_name?: string;
  is_active?: boolean;
  is_superuser?: boolean;
}

class QuantbotAdminAPI {
  constructor(private baseURL: string, private superuserToken: string) {}

  private get headers() {
    return {
      'Authorization': `Bearer ${this.superuserToken}`,
      'Content-Type': 'application/json'
    };
  }

  async createUser(userData: CreateUserRequest): Promise<User> {
    const response = await fetch(`${this.baseURL}/api/v1/admin/users/`, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({
        is_active: true,
        is_superuser: false,
        ...userData
      })
    });

    if (!response.ok) {
      throw new Error(`Failed to create user: ${response.statusText}`);
    }

    return await response.json();
  }

  async getAllUsers(skip: number = 0, limit: number = 100): Promise<User[]> {
    const params = new URLSearchParams({
      skip: skip.toString(),
      limit: limit.toString()
    });

    const response = await fetch(
      `${this.baseURL}/api/v1/admin/users/?${params}`, 
      {
        method: 'GET',
        headers: this.headers
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to get users: ${response.statusText}`);
    }

    return await response.json();
  }

  async getUser(userId: number): Promise<User> {
    const response = await fetch(
      `${this.baseURL}/api/v1/admin/users/${userId}`, 
      {
        method: 'GET',
        headers: this.headers
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to get user: ${response.statusText}`);
    }

    return await response.json();
  }

  async updateUser(userId: number, updates: UpdateUserRequest): Promise<User> {
    const response = await fetch(
      `${this.baseURL}/api/v1/admin/users/${userId}`, 
      {
        method: 'PUT',
        headers: this.headers,
        body: JSON.stringify(updates)
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to update user: ${response.statusText}`);
    }

    return await response.json();
  }

  async deleteUser(userId: number): Promise<{message: string}> {
    const response = await fetch(
      `${this.baseURL}/api/v1/admin/users/${userId}`, 
      {
        method: 'DELETE',
        headers: this.headers
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to delete user: ${response.statusText}`);
    }

    return await response.json();
  }

  async activateUser(userId: number): Promise<User> {
    const response = await fetch(
      `${this.baseURL}/api/v1/admin/users/${userId}/activate`, 
      {
        method: 'PATCH',
        headers: this.headers
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to activate user: ${response.statusText}`);
    }

    return await response.json();
  }

  async deactivateUser(userId: number): Promise<User> {
    const response = await fetch(
      `${this.baseURL}/api/v1/admin/users/${userId}/deactivate`, 
      {
        method: 'PATCH',
        headers: this.headers
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to deactivate user: ${response.statusText}`);
    }

    return await response.json();
  }
}

// Usage
const adminAPI = new QuantbotAdminAPI('http://localhost:8000', 'superuser_token');

// Create user
adminAPI.createUser({
  email: 'developer@company.com',
  password: 'dev_password_123',
  full_name: 'Developer Account',
  is_active: true,
  is_superuser: false
})
.then(user => console.log('✅ User created:', user.email))
.catch(error => console.error('❌ Creation failed:', error));

// Get all users
adminAPI.getAllUsers(0, 25)
.then(users => console.log(`📊 Retrieved ${users.length} users`))
.catch(error => console.error('❌ Failed to get users:', error));

// Bulk user operations
async function manageUsers() {
  try {
    // Get user list
    const users = await adminAPI.getAllUsers();

    // Find inactive users
    const inactiveUsers = users.filter(user => !user.is_active);
    console.log(`Found ${inactiveUsers.length} inactive users`);

    // Activate inactive users (excluding superusers)
    for (const user of inactiveUsers) {
      if (!user.is_superuser) {
        await adminAPI.activateUser(user.id);
        console.log(`✅ Activated user: ${user.email}`);
      }
    }
  } catch (error) {
    console.error('❌ Bulk operation failed:', error);
  }
}

Security Considerations

Access Control

  • Superuser Only: All endpoints require is_superuser: true
  • Self-Protection: Admins cannot delete or deactivate their own accounts
  • Audit Logging: All admin actions are logged with timestamps and admin identification

Data Privacy

  • Secure Storage: Passwords are hashed using secure algorithms
  • No Password Exposure: Password fields are never returned in responses
  • Sensitive Data: Admin operations are logged for security auditing

Best Practices

  • Regular Audits: Monitor admin API usage through logs
  • Strong Authentication: Use long-lived, secure tokens for admin operations
  • Principle of Least Privilege: Grant superuser status only when necessary

Error Handling

Common Error Responses

401 Unauthorized - Invalid or missing authentication

{
  "detail": "Could not validate credentials"
}

403 Forbidden - Insufficient permissions (not a superuser)

{
  "detail": "Forbidden - Admin access required"
}

404 Not Found - User not found

{
  "detail": "User not found"
}

422 Unprocessable Entity - Invalid request data

{
  "detail": [
    {
      "loc": ["body", "email"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

500 Internal Server Error - Server error

{
  "detail": "Internal server error occurred"
}