Tenant User Operations

Tenant-scoped user endpoints manage users within a specific tenant. These endpoints can be accessed with either a Global API Key or a Tenant API Key.

Authentication

API Key Type Access
Global API Key Can access any tenant
Tenant API Key Can only access its own tenant

List Users for Tenant

GET /api/tenant/{tenantId}/user

Retrieves users assigned to a specific tenant.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier

Query Parameters

Parameter Type Default Description
page integer 1 Page number for pagination
pageSize integer 50 Number of items per page (max: 1000)
includeDisabled boolean false Include disabled users
role string null Filter by role name
search string null Search by email or display name

Response (200 OK)

Same structure as the global List All Users, but filtered to the specified tenant.


Create User in Tenant

POST /api/tenant/{tenantId}/user

Creates a new user AND assigns them to the tenant, or assigns an existing user to the tenant.

Note: If a user with the specified email already exists, they will be assigned to the tenant instead of creating a duplicate.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier

Request Body

{
  "email": "john.smith@example.com",
  "displayName": "John Smith",
  "firstName": "John",
  "lastName": "Smith",
  "roleName": "Analyst"
}

Request Fields

Field Type Required Description
email string Yes User's email address
displayName string Yes Display name (2-100 characters)
firstName string No First name (max 50 characters)
lastName string No Last name (max 50 characters)
roleName string Yes Role name (see Roles & Permissions)

Capacity Validation

The operation validates tenant capacity limits:

  • MaxUsers limit is checked for all roles
  • MaxAnalyst limit is checked for Analyst roles

Response (201 Created)

{
  "userId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "email": "john.smith@example.com",
  "displayName": "John Smith",
  "message": "User created and assigned to tenant successfully"
}

Error Responses

Conflict (409):

{
  "error": "User is already assigned to this tenant"
}

Capacity Exceeded (400):

{
  "error": "Cannot add user: tenant has reached its maximum user limit (100)",
  "hint": "Increase the tenant's user or analyst limit to add more users"
}

Get User in Tenant

GET /api/tenant/{tenantId}/user/{userId}

Retrieves a specific user within the tenant context.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier
userId GUID Yes The user identifier

Response (200 OK)

Returns the user object if they are assigned to the tenant.


Get User by Email in Tenant

GET /api/tenant/{tenantId}/user/by-email/{email}

Retrieves a user by email within the tenant context.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier
email string Yes The user's email (URL encoded)

Response (200 OK)

Returns the user object if they are assigned to the tenant.


Assign Existing User to Tenant

POST /api/tenant/{tenantId}/user/{userId}

Assigns an existing user to a tenant.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier
userId GUID Yes The user identifier

Request Body (Optional)

{
  "roleName": "Analyst"
}

Response (200 OK)

{
  "message": "User assigned to tenant successfully"
}

Update User in Tenant

PUT /api/tenant/{tenantId}/user/{userId}

Updates a user's properties within the tenant context.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier
userId GUID Yes The user identifier

Request Body

{
  "displayName": "Updated Name",
  "roleName": "TenantAdmin"
}

Response (200 OK)

{
  "message": "User updated successfully"
}

Remove User from Tenant

DELETE /api/tenant/{tenantId}/user/{userId}

Removes a user's assignment from a tenant. This does NOT delete the user from the system.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier
userId GUID Yes The user identifier

Response (200 OK)

{
  "message": "User removed from tenant successfully"
}

Error Responses

Not Found (404):

{
  "error": "User is not assigned to this tenant"
}

Implementation Examples

cURL

# List users for a tenant (Tenant API key works)
curl -X GET "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user" \
  -H "Authorization: Bearer YOUR_TENANT_API_KEY"

# Search users in tenant
curl -X GET "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user?search=john" \
  -H "Authorization: Bearer YOUR_TENANT_API_KEY"

# Create user in tenant (creates user AND assigns)
curl -X POST "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user" \
  -H "Authorization: Bearer YOUR_TENANT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "new.user@example.com",
    "displayName": "New User",
    "roleName": "Analyst"
  }'

# Assign existing user to tenant
curl -X POST "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer YOUR_TENANT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"roleName": "Analyst"}'

# Remove user from tenant
curl -X DELETE "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer YOUR_TENANT_API_KEY"

Python

import requests

BASE_URL = 'https://your-mindzie-instance.com'

class TenantUserManager:
    def __init__(self, api_key, tenant_id):
        """
        Initialize with an API key and tenant ID.
        Works with either Global or Tenant API keys.
        """
        self.headers = {
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        }
        self.tenant_id = tenant_id

    def list_users(self, page=1, page_size=50, role=None, search=None):
        """List users assigned to this tenant."""
        url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user'
        params = {'page': page, 'pageSize': page_size}
        if role:
            params['role'] = role
        if search:
            params['search'] = search

        response = requests.get(url, headers=self.headers, params=params)
        response.raise_for_status()
        return response.json()

    def create_user(self, email, display_name, role_name,
                    first_name=None, last_name=None):
        """Create a user and assign to tenant (or assign existing user)."""
        url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user'
        payload = {
            'email': email,
            'displayName': display_name,
            'roleName': role_name
        }
        if first_name:
            payload['firstName'] = first_name
        if last_name:
            payload['lastName'] = last_name

        response = requests.post(url, json=payload, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def assign_user(self, user_id, role_name=None):
        """Assign an existing user to this tenant."""
        url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user/{user_id}'
        payload = {}
        if role_name:
            payload['roleName'] = role_name

        response = requests.post(url, json=payload, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def remove_user(self, user_id):
        """Remove a user from this tenant (does not delete the user)."""
        url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user/{user_id}'
        response = requests.delete(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def get_user(self, user_id):
        """Get a specific user in this tenant."""
        url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user/{user_id}'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

# Usage with Tenant API key
tenant_id = '12345678-1234-1234-1234-123456789012'
manager = TenantUserManager('your-tenant-api-key', tenant_id)

# List all analysts in tenant
analysts = manager.list_users(role='Analyst')
print(f"Tenant has {analysts['totalCount']} analysts")

for user in analysts['users']:
    print(f"  - {user['displayName']} ({user['email']})")

# Add a new analyst
new_user = manager.create_user(
    email='new.analyst@example.com',
    display_name='New Analyst',
    role_name='Analyst'
)
print(f"Added user: {new_user['userId']}")

# Remove user from tenant (user still exists in system)
manager.remove_user(new_user['userId'])
print("User removed from tenant")

JavaScript/Node.js

const BASE_URL = 'https://your-mindzie-instance.com';

class TenantUserManager {
  constructor(apiKey, tenantId) {
    this.headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    };
    this.tenantId = tenantId;
  }

  async listUsers(options = {}) {
    const params = new URLSearchParams({
      page: options.page || 1,
      pageSize: options.pageSize || 50
    });
    if (options.role) params.append('role', options.role);
    if (options.search) params.append('search', options.search);

    const url = `${BASE_URL}/api/tenant/${this.tenantId}/user?${params}`;
    const response = await fetch(url, { headers: this.headers });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return await response.json();
  }

  async createUser(email, displayName, roleName) {
    const url = `${BASE_URL}/api/tenant/${this.tenantId}/user`;
    const response = await fetch(url, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({ email, displayName, roleName })
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return await response.json();
  }

  async assignUser(userId, roleName = null) {
    const url = `${BASE_URL}/api/tenant/${this.tenantId}/user/${userId}`;
    const body = roleName ? { roleName } : {};
    const response = await fetch(url, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify(body)
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return await response.json();
  }

  async removeUser(userId) {
    const url = `${BASE_URL}/api/tenant/${this.tenantId}/user/${userId}`;
    const response = await fetch(url, {
      method: 'DELETE',
      headers: this.headers
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return await response.json();
  }
}

// Usage
const tenantId = '12345678-1234-1234-1234-123456789012';
const manager = new TenantUserManager('your-tenant-api-key', tenantId);

// List users
const users = await manager.listUsers();
console.log(`Tenant has ${users.totalCount} users`);

// Add new user
const newUser = await manager.createUser(
  'new@example.com',
  'New User',
  'Analyst'
);
console.log(`Added: ${newUser.userId}`);

Best Practices

  1. Use Tenant API Keys: For most operations, tenant-scoped keys are more secure
  2. Check Capacity: Verify tenant limits before bulk user creation
  3. Remove vs Delete: Removing from tenant keeps user in system for other tenants
  4. Search Before Create: Check if user exists before creating to avoid duplicates