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
- Use Tenant API Keys: For most operations, tenant-scoped keys are more secure
- Check Capacity: Verify tenant limits before bulk user creation
- Remove vs Delete: Removing from tenant keeps user in system for other tenants
- Search Before Create: Check if user exists before creating to avoid duplicates