Skip to content
synthreo.ai

User Management API

User Management API reference - create, update, and manage users, roles, and application permissions across Synthreo tenant instances via REST API.

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.

https://auth.synthreo.ai

All endpoints require authentication via JWT Bearer token. Obtain a token from the auth endpoint, then include it in all subsequent requests.

URL: POST https://auth.synthreo.ai/tenant/token

Request Body:

{
"email": "example@company.com",
"password": "password",
"customerId": 123
}

Field Descriptions:

FieldTypeRequiredDescription
emailstringYesYour email address
passwordstringYesYour password
customerIdintegerNoThe customer you want to generate a token for. If omitted, generates a token for your default customer.

Example Response:

{
"token": "token here",
"customerOptions": [
{
"customerId": 123,
"displayName": "MyCompany",
"roleName": "Admin",
"isOwner": false
}
]
}

Include the following header in all subsequent calls:

Authorization: Bearer your_jwt_token

OperationMethodEndpointDescription
List usersGET/tenant/users/{cid?}Get all users and their permissions for a company
Add userPOST/tenant/userCreate a new user and add them to a company
Reinitiate userPOST/tenant/user/initResend account setup email to a new user
Get permission optionsGET/permission/options/{type?}/{region?}/{account?}Get valid options for creating permissions
Create permissionPOST/permissionGrant a user access to an application account
Update permissionPUT/permissionChange the role assigned to an existing permission
Toggle permissionPATCH/permission/{permId}Enable or disable an existing permission
Delete permissionDELETE/permission/{permId}Permanently revoke a permission

Description: Retrieves all users associated with a company and their detailed permission information.

URL: GET /tenant/users/{cid?}

Requirements:

  • Authentication required

Parameters:

ParameterTypeRequiredDescription
cidintegerNoCompany ID. If omitted, returns users for the company your token was generated for.

Example Request:

GET /tenant/users/123 HTTP/1.1
Host: auth.synthreo.ai
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Example Response:

[
{
"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": { "...": "..." }
}
]
}
]

Response Fields:

FieldTypeDescription
idintegerUnique user identity ID
firstNamestringUser’s first name
lastNamestringUser’s last name
emailstringUser’s email address (unique identifier)
createdAtstringISO 8601 timestamp when the user was created
hasPasswordbooleanWhether the user has completed account setup and set a password
otpMethodstringTwo-factor authentication method configured for this user
lastAccessstringTimestamp of the user’s most recent login
permissionsarrayList of application access permissions for this user
permissions[].idintegerPermission record ID
permissions[].disabledbooleanWhether this permission is currently active
permissions[].lastAccessstringLast time the user accessed this application account

Description: Creates a new user account and adds them to the specified company with ThreoAI access.

URL: POST /tenant/user

Requirements:

  • Authentication required

Request Body:

{
"customerId": 123,
"email": "newuser@company.com",
"firstName": "Jane",
"lastName": "Smith"
}

Field Descriptions:

FieldTypeRequiredDescription
customerIdintegerNoCompany ID (defaults to current company if omitted)
emailstringYesValid email address for the new user
firstNamestringNoFirst name of the user
lastNamestringNoLast name of the user
namestringNoFull name (automatically splits into firstName/lastName if those fields are empty)

Example Request:

POST /tenant/user HTTP/1.1
Host: auth.synthreo.ai
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"customerId": 123,
"email": "newuser@company.com",
"firstName": "Jane",
"lastName": "Smith"
}

Response: 201 Created on success. The user will receive an email invitation to set up their account.


Description: Resends the initial setup email to a user who has not yet completed account setup (users without passwords).

URL: POST /tenant/user/init

Requirements:

  • Authentication required

Request Body:

{
"id": 456
}

Field Descriptions:

FieldTypeRequiredDescription
idintegerYesThe user identity ID of the user to reinitiate

Example Request:

POST /tenant/user/init HTTP/1.1
Host: auth.synthreo.ai
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"id": 456
}

Response: 204 No Content on success

Notes:

  • Only works for users who have not yet set up their password (hasPassword = false)
  • Returns a 400 error if the user has already completed account setup
  • For password reset of existing users, use the /auth/reset endpoint instead

Description: Retrieves available options for creating permissions. Call this endpoint progressively to populate form dropdowns - each step narrows available options based on prior selections.

URLs:

URLReturns
GET /permission/optionsList of available applications
GET /permission/options/{type}Regions available for the selected application
GET /permission/options/{type}/{region}Accounts available for that application in that region
GET /permission/options/{type}/{region}/{account}Available roles and users

Requirements:

  • Authentication required

Route Parameters:

ParameterTypeRequiredDescription
typestringNoApplication value from the previous step
regionintegerNoRegion value from the previous step
accountstringNoAccount value from the previous step

Query Parameters:

ParameterTypeRequiredDescription
cidintegerNoCompany ID to scope the options to
allbooleanNoInclude disabled accounts when set to true

Example Request:

GET /permission/options/1/1/101?cid=123 HTTP/1.1
Host: auth.synthreo.ai
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Example Response:

{
"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
}
]
}

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:

{
"appAccountId": 101,
"appRoleId": 2,
"userIdentityId": 456,
"disabled": false
}

Field Descriptions:

FieldTypeRequiredDescription
appAccountIdintegerYesID of the application account to grant access to (from GET /permission/options)
appRoleIdintegerYesID of the role to assign (from GET /permission/options)
userIdentityIdintegerYesUser identity ID of the user to grant access to
disabledbooleanNoWhether the permission starts disabled (default: false)

Example Request:

POST /permission HTTP/1.1
Host: auth.synthreo.ai
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"appAccountId": 101,
"appRoleId": 2,
"userIdentityId": 456,
"disabled": false
}

Example Response:

{
"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\"}"
}

Error Responses:

StatusMeaning
400 Bad RequestPermission already exists for this user and account combination
403 ForbiddenThe target account does not belong to an accessible company

Description: Updates an existing permission’s role assignment.

URL: PUT /permission

Requirements:

  • Authentication required

Request Body:

{
"id": 789,
"appRoleId": 1
}

Field Descriptions:

FieldTypeRequiredDescription
idintegerYesThe permission record ID to update
appRoleIdintegerYesThe new role ID to assign

Example Request:

PUT /permission HTTP/1.1
Host: auth.synthreo.ai
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"id": 789,
"appRoleId": 1
}

Response: 204 No Content on success


Description: Enables or disables an existing account permission without deleting it. Useful for temporary access suspension.

URL: PATCH /permission/{permId}

Requirements:

  • Authentication required

Parameters:

ParameterTypeRequiredDescription
permIdintegerYesPermission ID to toggle

Example Request:

PATCH /permission/789 HTTP/1.1
Host: auth.synthreo.ai
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response: 204 No Content on success. The permission’s disabled state is flipped (enabled becomes disabled, disabled becomes enabled).


Description: Permanently deletes an account permission, removing user access to the application account.

URL: DELETE /permission/{permId}

Requirements:

  • Authentication required

Parameters:

ParameterTypeRequiredDescription
permIdintegerYesPermission ID to delete

Example Request:

DELETE /permission/789 HTTP/1.1
Host: auth.synthreo.ai
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response: 204 No Content on success


  • 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
  • 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

import 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

Get Company Users with Permissions (Python)

Section titled “Get Company Users with Permissions (Python)”
def 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})")
def 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()
def 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 progressively
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()
# Get all applications
options = get_permission_options(customer_id=123)
# Get regions for application 1 (Builder)
options = get_permission_options(1, customer_id=123)
# Get accounts for application 1 in region 1
options = get_permission_options(1, 1, customer_id=123)
def 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

def 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
])

  1. Authentication: All endpoints require a valid JWT token in the Authorization header.
  2. 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 hierarchy
  3. 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 combination
  4. 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
  • Always validate email addresses before creating users
  • Use the permission options endpoint to populate UI dropdowns with valid combinations
  • Check user hasPassword status before attempting reinitialization
  • Implement proper error handling for duplicate user scenarios
  • Retrieve available options before creating permissions to ensure valid combinations
  • Use the toggle functionality (PATCH) 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)
  • Cache permission options for form population, as they change infrequently
  • Batch permission operations when onboarding multiple users
  • Use company-specific queries to reduce data transfer
  • 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 the principle of least privilege when assigning roles

Related pages: