Skip to main content

Admin API

Admin endpoints require a Bearer token with the appropriate permission. All endpoints are scoped to the tenant identified by the X-Tenant-ID header.

Permission convention: resource:read grants list/get access. resource:write grants create/update/delete access.

Base path: https://api.ithbat.io/api/v1/


Roles

Roles are named collections of permissions assigned to users. The system ships with built-in roles that cannot be deleted.

GET /api/v1/roles

Permission: role:read

List all roles in the tenant.

curl "https://api.ithbat.io/api/v1/roles" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>"

Response 200

{
"items": [
{
"id": "r1b2c3d4-e5f6-7890-abcd-ef1234567890",
"tenantId": "3e7a9f12-4b2c-4d8e-a1f0-9c2b3d4e5f6a",
"name": "Support Engineer",
"description": "Read access to users and audit logs",
"permissions": ["user:read", "audit:read"],
"isSystem": false,
"createdAt": "2026-01-15T10:00:00Z",
"updatedAt": "2026-01-15T10:00:00Z"
}
],
"totalItems": 1
}

GET /api/v1/roles/{id}

Permission: role:read

Get a single role by ID.

GET /api/v1/roles/permissions

Permission: role:read

Get the list of all available permissions that can be assigned to roles.

curl "https://api.ithbat.io/api/v1/roles/permissions" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>"

POST /api/v1/roles

Permission: role:write

Create a new role.

Request Body

FieldTypeRequiredDescription
namestringYesRole name (unique within tenant)
descriptionstringNoHuman-readable description
permissionsstring[]NoInitial permissions to grant
curl -X POST "https://api.ithbat.io/api/v1/roles" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>" \
-H "Content-Type: application/json" \
-d '{
"name": "Support Engineer",
"description": "Read access to users and audit logs",
"permissions": ["user:read", "audit:read"]
}'

Response 201 — Returns the created role object.

PUT /api/v1/roles/{id}

Permission: role:write

Update a role's name, description, or permissions. System roles cannot be modified.

Request Body — All fields optional:

FieldTypeDescription
namestringNew role name
descriptionstringNew description
permissionsstring[]Replaces the entire permissions list

DELETE /api/v1/roles/{id}

Permission: role:write

Delete a custom role. System roles cannot be deleted. Users with only this role will lose those permissions immediately.


Permissions

GET /api/v1/permissions

Permission: permission:read

List all permissions in the tenant.

GET /api/v1/permissions/categories

Permission: permission:read

List permissions grouped by category.

GET /api/v1/permissions/{id}

Permission: permission:read

Get a permission by ID.

POST /api/v1/permissions

Permission: permission:write

Create a custom permission.

PUT /api/v1/permissions/{id}

Permission: permission:write

Update a permission.

DELETE /api/v1/permissions/{id}

Permission: permission:write

Delete a custom permission.


Groups

Groups are collections of users. Assign roles to groups to apply permissions to all members at once.

GET /api/v1/groups

Permission: group:read

List all groups in the tenant.

curl "https://api.ithbat.io/api/v1/groups?page=1&limit=25" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>"

GET /api/v1/groups/{id}

Permission: group:read

Get a group by ID.

GET /api/v1/groups/{id}/members

Permission: group:read

List members of a group.

GET /api/v1/groups/{id}/roles

Permission: group:read

List roles assigned to a group.

POST /api/v1/groups

Permission: group:write

Create a new group.

Request Body

FieldTypeRequiredDescription
namestringYesGroup name (unique within tenant)
descriptionstringNoGroup description
curl -X POST "https://api.ithbat.io/api/v1/groups" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>" \
-H "Content-Type: application/json" \
-d '{
"name": "Backend Team",
"description": "Backend engineers"
}'

Response 201 — Returns the created group object.

PUT /api/v1/groups/{id}

Permission: group:write

Update a group's name or description.

DELETE /api/v1/groups/{id}

Permission: group:write

Delete a group. Members are not deleted — they lose any permissions inherited through this group.

POST /api/v1/groups/{id}/members

Permission: group:write

Add a user to the group.

Request Body

FieldTypeRequiredDescription
userIdstringYesUUID of the user to add

DELETE /api/v1/groups/{id}/members/{uid}

Permission: group:write

Remove a user from the group.

POST /api/v1/groups/{id}/roles

Permission: group:write

Assign a role to the group. All group members inherit the role's permissions.

Request Body

FieldTypeRequiredDescription
roleIdstringYesUUID of the role to assign

DELETE /api/v1/groups/{id}/roles/{rid}

Permission: group:write

Remove a role from the group.


Organizations

Organizations model external companies, departments, or sub-entities within a tenant. Users can belong to multiple organizations with different roles in each.

GET /api/v1/organizations

Permission: organization:read

List all organizations in the tenant.

curl "https://api.ithbat.io/api/v1/organizations" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>"

GET /api/v1/organizations/{id}

Permission: organization:read

Get an organization by ID.

GET /api/v1/organizations/{id}/members

Permission: organization:read

List members of an organization.

POST /api/v1/organizations

Permission: organization:write

Create a new organization.

PUT /api/v1/organizations/{id}

Permission: organization:write

Update an organization.

DELETE /api/v1/organizations/{id}

Permission: organization:write

Delete an organization.

POST /api/v1/organizations/{id}/members

Permission: organization:write

Add a user to an organization.

Request Body

FieldTypeRequiredDescription
userIdstringYesUUID of the user to add
rolesstring[]NoRoles to assign within the organization

DELETE /api/v1/organizations/{id}/members/{userId}

Permission: organization:write

Remove a user from an organization.

PUT /api/v1/organizations/{id}/members/{userId}/roles

Permission: organization:write

Update the roles a user holds within an organization.

Request Body

FieldTypeRequiredDescription
rolesstring[]YesNew set of roles for the member

Invitations

Invite users by email. They receive a link to set up their account and will automatically receive the specified roles on signup.

GET /api/v1/invitations

Permission: invitation:read

List invitations.

Query Parameters

ParameterTypeDescription
pageintPage number
limitintResults per page
statusstringFilter: pending, accepted, expired, revoked
searchstringSearch by email

GET /api/v1/invitations/{id}

Permission: invitation:read

Get a single invitation by ID.

POST /api/v1/invitations

Permission: invitation:write

Send an invitation email to a single user.

Request Body

FieldTypeRequiredDescription
emailstringYesRecipient's email address
rolesstring[]NoRole IDs to assign on signup
groupsstring[]NoGroup IDs to add the user to
firstNamestringNoPre-fill first name
familyNamestringNoPre-fill family name
expiryDaysintegerNoDays until invitation expires
curl -X POST "https://api.ithbat.io/api/v1/invitations" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"roles": ["r1b2c3d4-e5f6-7890-abcd-ef1234567890"],
"expiryDays": 7
}'

Response 201 — Returns the created invitation.

POST /api/v1/invitations/bulk

Permission: invitation:write

Send invitations to multiple email addresses at once.

POST /api/v1/invitations/{id}/resend

Permission: invitation:write

Resend an invitation email.

POST /api/v1/invitations/{id}/revoke

Permission: invitation:write

Revoke a pending invitation.

DELETE /api/v1/invitations/{id}

Permission: invitation:write

Delete an invitation record.


Tenants

GET /api/v1/tenants/current

Permission: tenant:read

Get the current tenant's details.

GET /api/v1/tenants

Permission: tenant:write

List tenants.

GET /api/v1/tenants/{id}

Permission: tenant:write

Get a tenant by ID.

PUT /api/v1/tenants/{id}

Permission: tenant:write

Update a tenant.

DELETE /api/v1/tenants/{id}

Permission: tenant:write

Delete a tenant.

POST /api/v1/tenants/{id}/suspend

Permission: tenant:write

Suspend a tenant.

POST /api/v1/tenants/{id}/reactivate

Permission: tenant:write

Reactivate a suspended tenant.


Settings

GET /api/v1/tenant/settings

Permission: settings:read

Get all settings for the current tenant.

GET /api/v1/tenant/password-policy

Permission: settings:read

Get the tenant's password policy.

PUT /api/v1/tenant/password-policy

Permission: settings:write

Update the tenant's password policy.

GET /api/v1/tenant/security/ip-whitelist

Permission: settings:read

Get the tenant's IP whitelist configuration.

PUT /api/v1/tenant/security/ip-whitelist

Permission: settings:write

Update the IP whitelist. When enabled, API requests from IPs not on the list are rejected with HTTP 403.

{
"enabled": true,
"ranges": ["197.134.10.0/24", "10.0.0.1"]
}

PATCH /api/v1/tenant/settings/general

Permission: settings:write

Update general tenant settings such as name and default language.

PATCH /api/v1/tenant/settings/branding

Permission: settings:write (requires branding feature)

Update branding settings — logo URL, primary color.

PATCH /api/v1/tenant/settings/security

Permission: settings:write

Update security settings — session duration, MFA enforcement.

GET /api/v1/tenant/custom-domain

Permission: settings:read

Get the custom domain configuration.

POST /api/v1/tenant/custom-domain

Permission: settings:write (requires custom_domain feature)

Set a custom domain for the tenant's authentication pages.

POST /api/v1/tenant/custom-domain/verify

Permission: settings:write (requires custom_domain feature)

Trigger DNS verification for a configured custom domain.

DELETE /api/v1/tenant/custom-domain

Permission: settings:write (requires custom_domain feature)

Remove the custom domain configuration.


Audit Logs

GET /api/v1/audit/events

Permission: audit:read

Query all audit events for the tenant.

Query Parameters

ParameterTypeDescription
pageintegerPage number
limitintegerResults per page
userIdstringFilter by actor user ID
eventTypestringFilter by event type
fromdatetimeISO 8601 start time
todatetimeISO 8601 end time
curl "https://api.ithbat.io/api/v1/audit/events?from=2026-02-01T00:00:00Z&limit=50" \
-H "Authorization: Bearer <access_token>" \
-H "X-Tenant-ID: <tenant_id>"

GET /api/v1/audit/events/{id}

Permission: audit:read

Get a single audit event by ID.

GET /api/v1/audit/logins

Permission: audit:read

Query the login history for all users in the tenant.

GET /api/v1/audit/stats

Permission: audit:read

Get aggregated statistics — total events, events by type, events over time.

GET /api/v1/audit/users/{userId}/activity

Permission: audit:read

Get all audit events for a specific user.

GET /api/v1/audit/users/{userId}/logins

Permission: audit:read

Get login history for a specific user.

GET /api/v1/audit/resources/{type}/{id}/history

Permission: audit:read

Get audit history for a specific resource (e.g., a user, role, or group).


OAuth 2.0 Client Management

GET /api/v1/oauth/admin/clients

Permission: oauth:read

List all OAuth 2.0 clients registered for the tenant.

GET /api/v1/oauth/admin/clients/{id}

Permission: oauth:read

Get an OAuth client by ID.

POST /api/v1/oauth/admin/clients

Permission: oauth:write

Register a new OAuth 2.0 client.

Request Body

FieldTypeRequiredDescription
namestringYesClient display name
redirectUrisstring[]YesAllowed redirect URIs
grantTypesstring[]YesOAuth grant types (e.g., authorization_code, client_credentials)
scopesstring[]YesAllowed scopes
descriptionstringNoClient description
logoUrlstringNoClient logo URL

Response 201 — Returns the client including clientSecret. Store the secret immediately — it is shown only at creation time.

PUT /api/v1/oauth/admin/clients/{id}

Permission: oauth:write

Update an OAuth client.

DELETE /api/v1/oauth/admin/clients/{id}

Permission: oauth:write

Delete an OAuth client.

POST /api/v1/oauth/admin/clients/{id}/regenerate-secret

Permission: oauth:write

Rotate the client secret. All existing tokens issued using the old secret remain valid until they expire.