User Management API
User Management API reference — create, update, and manage users, roles, and application permissions across Synthreo tenant instances via REST API.
Overview
Section titled “Overview”The User Management API provides comprehensive functionality for managing users, their permissions, and access to applications within the Synthreo platform. This includes adding users to companies, managing application permissions, and controlling user access across the tenant hierarchy.
Base URL
Section titled “Base URL”https://auth.synthreo.ai```text## Authentication
**Description**: All endpoints require authentication via JWT Bearer token.
**URL**: `POST /auth/token`
**Request Body**:
```json{ "email": "example@company.com", "password": "password", "customerId": 123}```text**Field Descriptions**:
| Field | Type | Required | Description ||-------|------|----------|-------------|| `email` | string | Yes | Your email address || `password` | string | Yes | Your password || `customerId` | integer | No | The customer you want to generate a token for. If omitted, generates a token for your default customer. |
**Example Response**:
```json{ "token": "token here", "customerOptions": [ { "customerId": 123, "displayName": "MyCompany", "roleName": "Admin", "isOwner": false } ]}```textThe value in Token is your JWT token.The list of customers is the customers you have access to.
**Append the following to your header in all future calls**
```textAuthorization: Bearer your_jwt_token```text---
## User Management Endpoints
### Get Users in Company
**Description**: Retrieves all users associated with a company and their detailed permission information.
**URL**: `GET /tenant/users/{cid?}`
**Requirements**:
- Authentication required
**Parameters**:
- `cid` (optional): Company ID. If omitted, returns users for the company you generated a token for.
**Example Request**:
```httpGET /tenant/users/123 HTTP/1.1Host: auth.synthreo.aiAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...```text**Example Response**:
```json[ { "id": 456, "firstName": "John", "lastName": "Doe", "email": "john.doe@company.com", "createdAt": "2024-01-15T10:30:00Z", "hasPassword": true, "otpMethod": "Email", "lastAccess": "2024-08-28T09:15:00Z", "name": "John Doe", "permissions": [ { "id": 1, "lastAccess": "2025-08-28T18:16:24.330121", "disabled": false, "createdAt": "2025-08-20T17:53:49.876681", "role": { ... }, "account": { ... }, "instanceActive": true, "application": { ... }, "region": { ... } } ] }]```text### Add User to Company
**Description**: Creates a new user account and adds them to the specified company with Threo access.
**URL**: `POST /tenant/user`
**Requirements**:
- Authentication required
**Request Body**:
```json{ "email": "newuser@company.com", "firstName": "Jane", "lastName": "Smith", "name": "Jane Smith"}```text**Field Descriptions**:
| Field | Type | Required | Description ||-------|------|----------|-------------|| `customerId` | integer | No | Company ID (defaults to current company if omitted) || `email` | string | Yes | Valid email address for the new user || `firstName` | string | No | First name of the user || `lastName` | string | No | Last name of the user || `name` | string | No | Full name (automatically splits into firstName/lastName if other fields are empty) |
**Example Request**:
```httpPOST /tenant/user HTTP/1.1Host: auth.synthreo.aiContent-Type: application/jsonAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{ "customerId": 123, "email": "newuser@company.com", "firstName": "Jane", "lastName": "Smith"}```text**Response**: `201 Created` on success
### Reinitiate User Account
**Description**: Resends the initial setup email to a user who hasn't completed account setup (users without passwords).
**URL**: `POST /tenant/user/init`
**Requirements**:
- Authentication required
**Request Body**:
```json{ "id": 456}```text**Example Request**:
```httpPOST /tenant/user/init HTTP/1.1Host: auth.synthreo.aiContent-Type: application/jsonAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{ "id": 456}```text**Response**: `204 No Content` on success
**Notes**:
- Only works for users who haven't set up their password yet- Returns 400 error if user has already initiated their account- For password reset of existing users, use the `/auth/reset` endpoint instead
---
## Permission Management Endpoints
### Get Permission Options
**Description**: Retrieves available options for creating permissions including applications, regions, accounts, roles, and users.
**URLs**:`GET /permission/options?{queryparameters}` - Shows list of applications with their values`GET /permission/options/{type}?{queryparameters}` - Shows list of regions with their values`GET /permission/options/{type}/{region}?{queryparameters}` - Shows list of accounts with their values`GET /permission/options/{type}/{region}/{account}?{queryparameters}` - Shows roles and users
**Requirements**:
- Authentication required
**Route Parameters**:
| Field | Type | Description ||---|---|---|| `type` | string | Application value || `region` | integer | Region value || `account` | string | account value |
**Query Parameters**:
| Field | Type | Required | Description ||---|---|---|---|| `cid` | integer | No | customerId || `all` | boolean | No | Include disabled accounts |
**Example Request**:
```httpGET /permission/options/1/1/101?cid=123 HTTP/1.1Host: auth.synthreo.aiAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...```text**Example Response**:
```json{ "applications": [ { "value": 1, "title": "TheoBuilder", "selected": true }, { "value": 2, "title": "ThreoAI", "selected": false }, { "value": 3, "title": "Tenant management", "selected": false } ], "regions": [ { "value": 1, "title": "US East", "selected": true }, { "value": 2, "title": "US West", "selected": false } ], "accounts": [ { "value": 101, "title": "Builder Production (id: builder_prod_123)", "selected": true } ], "roles": [ { "value": 1, "title": "Admin", "selected": false }, { "value": 2, "title": "User", "selected": false } ], "users": [ { "value": 456, "title": "John Doe (john.doe@company.com)", "selected": false }, { "value": 457, "title": "Jane Smith (jane.smith@company.com)", "selected": false } ]}```text### Create Account Permission
**Description**: Creates a new permission granting a user access to an application account with a specific role.
**URL**: `POST /permission`
**Requirements**:
- Authentication required
**Request Body**:
```json{ "appAccountId": 101, "appRoleId": 2, "userIdentityId": 456, "disabled": false}```text**Field Descriptions**:
| Field | Type | Required | Description ||-------|------|----------|-------------|| `appAccountId` | integer | Yes | ID of the application account to grant access to || `appRoleId` | integer | Yes | ID of the role to assign || `userIdentityId` | integer | Yes | User ID || `disabled` | boolean | No | Whether permission is disabled (default: false) |
**Example Request**:
```httpPOST /permission HTTP/1.1Host: auth.synthreo.aiContent-Type: application/jsonAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{ "appAccountId": 101, "appRoleId": 2, "userIdentityId": 456, "disabled": false}```text**Example Response**:
```json{ "id": 789, "appAccountId": 101, "userIdentityId": 456, "appRoleId": 2, "lastAccess": null, "disabled": false, "createdAt": "2024-08-28T15:30:00Z", "createdBy": "{\"id\":123,\"email\":\"admin@company.com\"}"}```text### Update Account Permission
**Description**: Updates an existing permission's role assignment.
**URL**: `PUT /permission`
**Requirements**:
- Authentication required
**Request Body**:
```json{ "id": 789, "appRoleId": 123}```text**Example Request**:
```httpPUT /permission HTTP/1.1Host: auth.synthreo.aiContent-Type: application/jsonAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{ "id": 789, "appRoleId": 1}```text**Response**: `204 No Content` on success
### Toggle Account Permission
**Description**: Enables or disables an existing account permission.
**URL**: `PATCH /permission/{permId}`
**Requirements**:
- Authentication required
**Parameters**:
- `permId` (integer): Permission ID to toggle
**Example Request**:
```httpPATCH /permission/789 HTTP/1.1Host: auth.synthreo.aiAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...```text**Response**: `204 No Content` on success
### Delete Account Permission
**Description**: Permanently deletes an account permission, removing user access to the application account.
**URL**: `DELETE /permission/{permId}`
**Requirements**:
- Authentication required
**Parameters**:
- `permId` (integer): Permission ID to delete
**Example Request**:
```httpDELETE /permission/789 HTTP/1.1Host: auth.synthreo.aiAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...```text**Response**: `204 No Content` on success
---
### Permission and Access Rules
**User Access Requirements**:
- Users can only be managed within companies you have access to (your company or its descendants)- Account permissions can only be created for application accounts belonging to accessible companies- Role assignments must belong to the same company as the application account or be system-wide roles
**Permission Management Rules**:
- Cannot create duplicate permissions for the same user and application account- Disabled permissions preserve the relationship but prevent access- Deleting permissions permanently removes user access to the application account- Role changes require the new role to be valid for the application type
---
## Code Examples
### Add User (Python)
```pythonimport requests
def add_user_to_company(customer_id, email, first_name, last_name): url = "https://auth.synthreo.ai/tenant/user"
headers = { "Authorization": f"Bearer {access_token}" }
data = { "customerId": customer_id, "email": email, "firstName": first_name, "lastName": last_name }
try: response = requests.post(url, headers=headers, json=data)
if not response.ok: error_detail = response.json().get('detail', 'Unknown error') raise Exception(f"Failed to add user: {error_detail}")
return True except requests.exceptions.RequestException as e: print(f"Error adding user: {e}") return False```text### Print Company Users with Permissions (Python)
```pythondef get_company_users(customer_id=None): url = "https://auth.synthreo.ai/tenant/users" if customer_id: url += f"/{customer_id}"
headers = { "Authorization": f"Bearer {access_token}" }
response = requests.get(url, headers=headers) response.raise_for_status()
return response.json()
users = get_company_users(123):for user in users: print(f"User: {user['firstName']} {user['lastName']} <{user['email']}>") print(f" Has Password: {user['hasPassword']}") print(f" 2FA Method: {user['otpMethod']}") print(f" Permissions:")
for perm in user['permissions']: app_name = perm['application']['name'] role_name = perm['role']['name'] account_name = perm['account']['name'] status = "Disabled" if perm['disabled'] else "Active" print(f" - {app_name}: {role_name} on {account_name} ({status})")
```text### Create Account Permission (Python)
```pythondef create_account_permission(app_account_id, role_id, user_id): url = "https://auth.synthreo.ai/permission"
headers = { "Authorization": f"Bearer {access_token}" }
data = { "appAccountId": app_account_id, "appRoleId": role_id, "userIdentityId": user_id, "disabled": False }
response = requests.post(url, headers=headers, json=data)
if not response.ok: error_detail = response.json().get('detail', 'Unknown error') if 'Permission already exists' in error_detail: print('User already has permission for this account') return False raise Exception(f"Failed to create permission: {error_detail}")
return response.json()```text### Get Permission Options (Python)
```pythondef get_permission_options(app_type=None, region_id=None, account_id=None, customer_id=None): url = "https://auth.synthreo.ai/permission/options"
# Build URL path if app_type: url += f"/{app_type}" if region_id: url += f"/{region_id}" if account_id: url += f"/{account_id}"
headers = { "Authorization": f"Bearer {access_token}" }
params = {} if customer_id: params['cid'] = customer_id
response = requests.get(url, headers=headers, params=params) response.raise_for_status()
return response.json()
options = get_permission_options(customer_id=123)
options = get_permission_options(1, customer_id=123)
options = get_permission_options(1, 1, customer_id=123)```text### Reinitiate User Setup (Python)
```pythondef reinitiate_user(user_id): url = "https://auth.synthreo.ai/tenant/user/init"
headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" }
data = { "id": user_id }
response = requests.post(url, headers=headers, json=data)
if response.status_code == 400: error_detail = response.json().get('detail', '') if 'already initiated' in error_detail: print("User has already set up their account.") return False elif response.status_code == 204: print(f"Setup email sent") return True else: response.raise_for_status() return False```text---
## Common Workflows
### Complete User Onboarding Workflow
```pythondef onboard_new_user(customer_id, email, first_name, last_name, permissions): """ Complete user onboarding workflow with permission assignment permissions: list of {'applicationId': int, 'roleId': int} """ try: # Step 1: Add user to company add_user_to_company(customer_id, email, first_name, last_name) print(f"User {email} added to customer {customer_id}")
# Step 2: Get user id user_id = next((u['id'] for u in get_company_users(customer_id) if u['email'] == email), None) if not user_id: print("Failed to find user Id") return False
# Step 3: Create permissions for perm in permissions: create_account_permission(perm['applicationId'], perm['roleId'], user_id) print(f"Permission created: {perm['applicationName']} - {perm['roleName']}")
return True except Exception as error: print(f"Onboarding failed: {error}") return False
onboard_new_user(123, 'jsmith@company.com', 'Jane', 'Smith', [ {'applicationId': 1, 'roleId': 4}, # Full Power User for Builder {'applicationId': 2, 'roleId': 3} # Admin for ThreoAI])```text---
## Authorization Notes
1. **Authentication**: All endpoints require a valid JWT token in the Authorization header2. **Hierarchical Access Control**: - Users can only manage other users within their accessible company hierarchy - Parent companies can manage users in subsidiary companies - Users cannot manage permissions for companies above them in the hierarchy3. **Permission Validation**: - Account permissions can only be created for accounts belonging to accessible companies - Roles must be compatible with the application type and company - Cannot create duplicate permissions for the same user and account combination4. **User Identity Management**: - Email addresses are used as unique identifiers for users - Users can be created automatically when adding permissions if they don't exist - Name parsing automatically splits full names into first/last name components
## Best Practices
### User Management
- Always validate email addresses before creating users- Use the permission options endpoint to populate UI dropdowns- Check user `hasPassword` status before attempting reinitialization- Implement proper error handling for duplicate user scenarios
### Permission Management
- Retrieve available options before creating permissions to ensure valid combinations- Use toggle functionality for temporary access control instead of delete/recreate- Monitor `lastAccess` timestamps to identify inactive users- Consider role hierarchies when assigning permissions (Admin vs User roles)
### Performance Optimization
- Cache permission options for form population- Batch permission operations when onboarding multiple users- Use company-specific queries to reduce data transfer
### Security Considerations
- Validate user access to target companies before making permission changes- Log all permission modifications for audit trails- Implement proper session management for long-running operations- Use principle of least privilege when assigning roles