Skip to main content

User Management

Ithbat IAM provides a complete user lifecycle API and admin console. Users can be created manually, imported in bulk via CSV, provisioned automatically via SCIM, or created through self-registration and SAML JIT provisioning.


User profile fields

Every user account contains the following standard fields:

FieldTypeDescription
idUUIDUnique identifier
emailstringPrimary email, must be unique within the tenant
firstNamestringGiven name
lastNamestringFamily name
phonestringPhone number (optional)
localestringBCP 47 language tag, e.g. en, ar
statusenumactive, suspended, pending
emailVerifiedboolWhether the email address has been verified
externalIdstringID from an external system (e.g. IdP user ID)
metadataobjectArbitrary key-value pairs for your own use
createdAttimestampAccount creation time
lastLoginAttimestampMost recent successful login

Inviting users

The recommended way to add users is by invitation. Ithbat sends an email with a secure link. The user clicks the link, sets their password, and their account is activated.

Via admin console

  1. Go to Users → Invite User.
  2. Enter the email address and optionally a first and last name.
  3. Select the roles to assign on acceptance.
  4. Click Send Invitation.

Via API

POST /api/v1/invitations
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"roleIds": ["7c9e6679-7425-40de-944b-e07fc1f90ae7"]
}

Response:

{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"email": "[email protected]",
"status": "pending",
"expiresAt": "2026-03-03T10:00:00Z",
"createdAt": "2026-02-24T10:00:00Z"
}

Invitations expire after 7 days. Resend an expired invitation:

POST /api/v1/invitations/{id}/resend
Authorization: Bearer {token}

Bulk invitations

Send up to 50 invitations in a single request:

POST /api/v1/invitations/bulk
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"invitations": [
{ "email": "[email protected]", "firstName": "User", "lastName": "One" },
{ "email": "[email protected]", "firstName": "User", "lastName": "Two" }
],
"roleIds": ["7c9e6679-..."]
}

Creating users directly

Create users without the invitation email flow. The user will be created in active status with emailVerified: false unless overridden.

POST /api/v1/users
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"phone": "+966501234567",
"locale": "ar"
}

Response:

{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"tenantId": "c2e3f4a5-...",
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"phone": "+966501234567",
"locale": "ar",
"status": "active",
"emailVerified": false,
"createdAt": "2026-02-24T10:00:00Z",
"updatedAt": "2026-02-24T10:00:00Z"
}

Viewing users

List all users

GET /api/v1/users
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}

Supports pagination (page, limit) and filtering by status, email, and more.

Get a single user

GET /api/v1/users/{id}
Authorization: Bearer {token}

Get the current authenticated user

GET /api/v1/users/me
Authorization: Bearer {user_token}

Updating users

Update profile fields

PUT /api/v1/users/{id}
Authorization: Bearer {token}
Content-Type: application/json

{
"firstName": "Jane",
"lastName": "Smith",
"phone": "+966501234567",
"locale": "en"
}

Update metadata

Attach arbitrary key-value metadata to a user without touching the standard profile fields:

PATCH /api/v1/users/{id}/metadata
Authorization: Bearer {token}
Content-Type: application/json

{
"department": "Engineering",
"employeeId": "EMP-1042",
"costCenter": "CC-500"
}

Suspending and reactivating users

Suspension prevents sign-in while preserving the user's data, sessions, and role assignments. All active sessions are invalidated immediately on suspension.

Suspend a user

POST /api/v1/users/{id}/suspend
Authorization: Bearer {token}

Reactivate a suspended user

POST /api/v1/users/{id}/reactivate
Authorization: Bearer {token}

Unlock a locked account

Accounts are locked automatically after repeated failed login attempts (configured by your password policy). Unlock manually:

POST /api/v1/users/{id}/unlock
Authorization: Bearer {token}

Deleting users

Deletion is permanent and irreversible. All sessions, role assignments, group memberships, and personal data are removed.

DELETE /api/v1/users/{id}
Authorization: Bearer {token}

Bulk delete

DELETE /api/v1/users/bulk
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"userIds": [
"3fa85f64-...",
"7c9e6679-..."
]
}

Bulk import via CSV

Import large numbers of users from a CSV file.

Prepare the CSV

The CSV must include a header row. Supported columns:

email,firstName,lastName,phone,locale,externalId
[email protected],Jane,Doe,+966501234567,en,EMP-1042
[email protected],John,Smith,,ar,EMP-1043

Required: email. All other columns are optional.

Import via API

POST /api/v1/users/import
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: multipart/form-data

[email protected]

The import is processed asynchronously. The response includes a job ID:

{
"jobId": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"status": "queued"
}

Poll for job status:

GET /api/v1/jobs/{jobId}/status
Authorization: Bearer {token}

Export users to CSV

POST /api/v1/users/export
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"format": "csv",
"fields": ["email", "firstName", "lastName", "status", "createdAt"]
}

Returns a job ID. Retrieve the result when complete:

GET /api/v1/jobs/{jobId}/result
Authorization: Bearer {token}

Password policies

Configure password requirements for your tenant.

Get the current policy

GET /api/v1/tenant/password-policy
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}

Response:

{
"minLength": 8,
"requireUppercase": true,
"requireLowercase": true,
"requireNumbers": true,
"requireSymbols": false,
"maxAge": 90,
"preventReuse": 5,
"maxLoginAttempts": 5,
"lockoutDuration": 900
}

Update the policy

PUT /api/v1/tenant/password-policy
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"minLength": 12,
"requireUppercase": true,
"requireLowercase": true,
"requireNumbers": true,
"requireSymbols": true,
"maxAge": 90,
"preventReuse": 10,
"maxLoginAttempts": 5,
"lockoutDuration": 1800
}
FieldDescription
minLengthMinimum password length (1–128)
requireUppercaseAt least one uppercase letter required
requireLowercaseAt least one lowercase letter required
requireNumbersAt least one digit required
requireSymbolsAt least one special character required
maxAgePassword expiry in days (0 = never expires)
preventReuseNumber of previous passwords that cannot be reused
maxLoginAttemptsFailed attempts before account lockout
lockoutDurationLockout duration in seconds

Session management

View a user's active sessions

GET /api/v1/users/{id}/sessions
Authorization: Bearer {token}

Revoke all sessions for a user

DELETE /api/v1/users/{id}/sessions
Authorization: Bearer {token}

User API reference summary

MethodEndpointPermission
GET/api/v1/usersuser:read
GET/api/v1/users/{id}user:read
POST/api/v1/usersuser:write
PUT/api/v1/users/{id}user:write
DELETE/api/v1/users/{id}user:delete
POST/api/v1/users/{id}/suspenduser:write
POST/api/v1/users/{id}/reactivateuser:write
POST/api/v1/users/{id}/unlockuser:write
POST/api/v1/users/bulkuser:write
DELETE/api/v1/users/bulkuser:write
POST/api/v1/users/importuser:write
POST/api/v1/users/exportuser:write
PATCH/api/v1/users/{id}/metadatauser:write
POST/api/v1/invitationsinvitation:write
POST/api/v1/invitations/bulkinvitation:write
POST/api/v1/invitations/{id}/resendinvitation:write
POST/api/v1/invitations/{id}/revokeinvitation:write

Next steps