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
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Role name (unique within tenant) |
description | string | No | Human-readable description |
permissions | string[] | No | Initial 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:
| Field | Type | Description |
|---|---|---|
name | string | New role name |
description | string | New description |
permissions | string[] | 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
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Group name (unique within tenant) |
description | string | No | Group 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
| Field | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | UUID 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
| Field | Type | Required | Description |
|---|---|---|---|
roleId | string | Yes | UUID 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
| Field | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | UUID of the user to add |
roles | string[] | No | Roles 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
| Field | Type | Required | Description |
|---|---|---|---|
roles | string[] | Yes | New 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
| Parameter | Type | Description |
|---|---|---|
page | int | Page number |
limit | int | Results per page |
status | string | Filter: pending, accepted, expired, revoked |
search | string | Search 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
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Recipient's email address |
roles | string[] | No | Role IDs to assign on signup |
groups | string[] | No | Group IDs to add the user to |
firstName | string | No | Pre-fill first name |
familyName | string | No | Pre-fill family name |
expiryDays | integer | No | Days 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
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number |
limit | integer | Results per page |
userId | string | Filter by actor user ID |
eventType | string | Filter by event type |
from | datetime | ISO 8601 start time |
to | datetime | ISO 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
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Client display name |
redirectUris | string[] | Yes | Allowed redirect URIs |
grantTypes | string[] | Yes | OAuth grant types (e.g., authorization_code, client_credentials) |
scopes | string[] | Yes | Allowed scopes |
description | string | No | Client description |
logoUrl | string | No | Client 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.