Tenant / Admin API Overview
The Informer Tenant API provides administrative endpoints for managing tenant configuration, license activation, mail settings, search clusters, and system-level operations. Most endpoints require superuser permissions. All routes are prefixed with /api.
Features
- Tenant Management - Create, read, update, and delete tenants
- License Management - Activate and sync license information
- Mail Configuration - Configure SMTP settings and test mail delivery
- Search Clusters - Configure Elasticsearch connection
- App Settings - Configure App resources and settings
- Job History - View tenant-wide job execution history
- Orphan Indices - Manage orphaned Elasticsearch indices
- Password Strength - Check password strength
- Export/Copy - Export and copy tenant configurations
Authentication
Most Tenant API endpoints require superuser permissions (permission.tenant.superuser). Some endpoints require root manager superuser access for cross-tenant operations.
Endpoints
GET /api/tenants
Get a list of all tenants (manager-only endpoint).
Authentication: Required (root manager superuser for full list)
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
crossTenantAccessOnly | boolean | Filter tenants by crossTenantAccess flag |
Response:
{
"_links": {
"self": { "href": "/api/tenants" }
},
"_embedded": {
"inf:tenant": [
{
"id": "acme",
"name": "Acme Corporation",
"crossTenantAccess": false,
"createdAt": "2024-01-15T10:30:00Z",
"_links": {
"self": { "href": "/api/tenants/acme" }
}
}
]
},
"start": 0,
"count": 1,
"total": 1
}
Notes:
- Non-manager users only see their own tenant
- Non-superusers only see their own tenant
- Manager superusers see all tenants
POST /api/tenants
Create a new tenant with optional content provisioning.
Authentication: Required (manager superuser)
Pre-blocks: permission.tenants.create(auth), tenant.verifyLicense(payload.licenseToken), tenant.provision
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Tenant ID (auto-generated if not provided) |
name | string | Yes | Tenant display name |
licenseToken | string | Yes | License token for activation |
adminPassword | string | No | Admin password (default: 123) |
adminEmail | string | No | Admin email address |
progress | string | No | Progress tracking ID |
copyFromId | string | No | Copy content from existing tenant |
bundleId | string | No | Deploy from bundle template |
jwtPublicKey | string | No | JWT public key for authentication |
activate | boolean | No | Auto-activate license (default: false) |
searchClusterId | string | No | Elasticsearch cluster ID |
appDatabaseId | string (UUID) | null | No | Manager-curated App Database profile to host the tenant's app workspace data. null (default) uses the deployment-level default. Can be changed later via PUT /api/tenants/{id}/app-database. |
Example Request:
{
"id": "newcorp",
"name": "New Corporation",
"licenseToken": "license-token-xyz",
"adminPassword": "secure-password",
"adminEmail": "admin@newcorp.com",
"activate": true,
"copyFromId": "template-tenant"
}
Response:
Returns the created tenant object with 201 Created status and Location header.
Auto-Activation:
- If
activate: trueand user is root manager superuser - Automatically activates license via License Manager
- Reloads tenant after activation to reflect updated license info
GET /api/tenants/{id}
Get a specific tenant's public information.
Authentication: Required (session)
Response:
{
"id": "acme",
"name": "Acme Corporation",
"crossTenantAccess": false,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z",
"_links": {
"self": { "href": "/api/tenants/acme" }
}
}
PUT /api/tenants/{id}
Update tenant configuration.
Authentication: Required (superuser)
Pre-blocks: tenant.lookup(params.id), permission.tenant.write(pre.tenant)
Request Body:
Tenant configuration fields (varies by what's updateable).
Response:
Returns the updated tenant object.
DELETE /api/tenants/{id}
Delete a tenant (cannot delete 'manager' tenant).
Authentication: Required (root manager superuser)
Pre-blocks: auth.assertRootManagerSuperuser, tenant.lookup(params.id)
Response:
Returns 204 No Content on successful deletion.
Restrictions:
- Cannot delete the 'manager' tenant
- Requires root manager superuser access
POST /api/license/_sync
Sync license information with License Manager.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Response:
Returns updated license information after syncing.
Side Effects:
- Updates tenant's license status
- Syncs the AI credit pool and entitlements
- Updates feature flags based on license
GET /api/license
Get current license information.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Response:
{
"licenseToken": "token-xyz",
"status": "active",
"expiresAt": "2025-12-31T23:59:59Z",
"features": {
"ai": true,
"multiTenant": true
}
}
GET /api/settings
Get the current tenant's settings. This is a broad settings object (letterhead, export options, cloud, etc.); the AI/usage-related fields are summarized below.
Authentication: Required
AI / usage fields:
| Field | Type | Description |
|---|---|---|
aiEnabled | boolean | Master switch for AI features on the tenant |
defaultAiProfileId | UUID | null | The usage profile applied to users with no team-assigned profile |
aiMonthlyLimit | number | Tenant-wide monthly credit ceiling |
aiSettings | object | Per-feature AI configuration/instructions |
PUT /api/settings
Update tenant settings.
Authentication: Required
Permissions: Superusers may update any setting. Billing managers (billing.manage) may update only the AI/usage fields — aiEnabled, aiSettings, aiMonthlyLimit, and defaultAiProfileId; any other field in the same payload requires permission.tenant.superuser.
Request Body (AI / usage fields):
| Field | Type | Description |
|---|---|---|
aiEnabled | boolean | Enable/disable AI for the tenant |
defaultAiProfileId | UUID | null | Set or clear the tenant default usage profile |
aiMonthlyLimit | number (≥ 0) | Tenant-wide monthly credit ceiling |
aiSettings | object | Per-feature AI configuration |
Example Request:
{ "aiEnabled": true, "defaultAiProfileId": "11111111-1111-1111-1111-111111111111" }
Response:
Returns the updated settings object.
GET /api/mail-settings
Get current mail configuration.
Authentication: Required (session)
Pre-blocks: tenant.current
Response:
{
"authType": "login",
"host": "smtp.example.com",
"port": 587,
"secure": false,
"ignoreTLS": false,
"requireTLS": true,
"pool": true,
"maxConnections": 5,
"maxMessages": 100,
"rateLimit": null,
"rateDelta": 1000,
"defaultFromAddress": "noreply@example.com",
"alwaysUseDefault": false
}
PUT /api/mail-settings
Update mail configuration.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser, tenant.current
Request Body:
| Field | Type | Description |
|---|---|---|
authType | string | Authentication type: none, login, oauth2 (default: none) |
host | string | SMTP host (default: localhost) |
port | integer | SMTP port (default: 587) |
secure | boolean | Use TLS (default: false) |
ignoreTLS | boolean | Ignore TLS errors (default: false) |
requireTLS | boolean | Require TLS (default: false) |
pool | boolean | Use connection pooling (default: true) |
maxConnections | integer | Max connections (default: 5, min: 1) |
maxMessages | integer | Max messages per connection (default: 100, min: 1) |
rateLimit | integer | Messages per rateDelta (optional) |
rateDelta | integer | Rate limit window in ms (default: 1000, min: 1) |
defaultFromAddress | string | Default from address |
alwaysUseDefault | boolean | Always use default from address (default: false) |
auth | object | Authentication credentials |
Response:
Returns the updated mail settings.
POST /api/mail-settings/_ping
Test mail configuration by sending a test email.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Request Body:
| Field | Type | Description |
|---|---|---|
to | string | Recipient email address |
subject | string | Email subject (optional) |
body | string | Email body (optional) |
Response:
{
"success": true,
"message": "Test email sent successfully"
}
GET /api/search-cluster
Get Elasticsearch cluster configuration.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Response:
{
"id": "cluster-123",
"host": "localhost",
"port": 9200,
"protocol": "http"
}
PUT /api/search-cluster
Update Elasticsearch cluster configuration.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Request Body:
Elasticsearch connection configuration.
Response:
Returns the updated cluster configuration.
POST /api/password-strength/_test
Test password strength.
Authentication: Required (session)
Request Body:
| Field | Type | Description |
|---|---|---|
password | string | Password to test |
Response:
{
"score": 3,
"strength": "strong",
"feedback": {
"warning": "",
"suggestions": []
}
}
GET /api/job-history
Get tenant-wide job execution history.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of results |
offset | integer | Pagination offset |
status | string | Filter by status (success, failure, running) |
Response:
{
"_links": {
"self": { "href": "/api/job-history" }
},
"_embedded": {
"inf:job-history": [
{
"id": "exec-123",
"jobId": "job-456",
"status": "success",
"startedAt": "2024-01-15T10:30:00Z",
"completedAt": "2024-01-15T10:32:00Z",
"duration": 120000
}
]
},
"start": 0,
"count": 1,
"total": 1
}
GET /api/orphan-indices
Get orphaned Elasticsearch indices (indices without corresponding datasets).
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Response:
{
"indices": [
{
"name": "dataset-abc123-old",
"size": "100MB",
"docCount": 50000
}
]
}
GET /api/magic-report-settings
Get App configuration.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Response:
{
"enabled": true,
"cspConnectSrc": ["https://api.example.com"]
}
PUT /api/magic-report-settings
Update App configuration.
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Request Body:
App settings configuration.
Response:
Returns the updated App settings.
GET /api/magic-report-resources
Get App resources (libraries, scripts).
Authentication: Required (superuser)
Pre-blocks: permission.tenant.superuser
Response:
{
"resources": [
{
"id": "resource-123",
"name": "Chart Library",
"type": "script",
"url": "https://cdn.example.com/chart.js"
}
]
}
POST /api/tenants/{id}/_export
Export tenant configuration and content.
Authentication: Required (superuser)
Pre-blocks: tenant.lookup(params.id), permission.tenant.write(pre.tenant)
Response:
Returns tenant export package (JSON).
POST /api/tenants/{id}/_copy
Copy content from one tenant to another.
Authentication: Required (root manager superuser)
Request Body:
Copy configuration options.
Response:
Returns copy operation status.
Admin Operations
Common administrative workflows:
Provision New Tenant
- Create tenant with license token
- Optionally copy from template tenant
- Auto-activate license
- Configure mail settings
- Set up search cluster
License Management
- Get current license status
- Sync with License Manager
- Monitor expiration dates
- Update license tokens
Mail Configuration
- Configure SMTP settings
- Test with ping endpoint
- Verify delivery
Maintenance
- Check for orphan indices
- Review job history for failures
- Monitor resource usage