Skip to main content

Settings

Manage API keys, user profiles, role permissions, AI configuration, dashboard presets, and more.

API keys

List API keys

GET /settings/api-keys

Auth: Bearer JWT (any role)

Returns all keys with prefix only (no secrets).

Create an API key

POST /settings/api-keys

Auth: Bearer JWT (admin)

{
"name": "edge-agent-prod",
"expires_at": "2027-04-04T00:00:00Z",
"scopes": ["ingest", "agent"]
}
FieldTypeDescription
namestringDescriptive name for the key (required)
expires_atdatetimeOptional expiration timestamp
scopesstring[]Granted scopes (optional , defaults to ["ingest", "agent"])

Available scopes:

ScopeGrants access to
ingestPOST /ingest , push sensor data batches
agentGET /agent/heartbeat , edge agent heartbeat
read:machinesGET /machines , list and read machine details
read:sensorsGET /sensor-data/* , query sensor readings

Preset shortcuts: Pass a single preset name instead of individual scopes:

PresetExpands to
edge_agent["ingest", "agent"]
read_only["read:machines", "read:sensors"]

Response:

{
"id": "uuid",
"name": "edge-agent-prod",
"key": "hlts_a1b2c3...",
"scopes": ["ingest", "agent"],
"tenant_id": "uuid",
"created_at": "2026-04-04T10:00:00Z"
}
warning

The key field is returned only once at creation time. Store it securely.

If an API key is used on an endpoint outside its granted scopes, the server returns 403 Forbidden with:

{"detail": "API key does not have the required scope: <scope>"}

Revoke an API key

DELETE /settings/api-keys/{key_id}

Auth: Bearer JWT (admin)

User profile

Update profile

PATCH /settings/profile

{"full_name": "Jane Smith", "email": "new@example.com", "current_password": "..."}

Email changes require current_password.

Change password

POST /settings/change-password

{"current_password": "old_password", "new_password": "NewSecureP@ss123!"}

User management

List users

GET /users

Auth: Bearer JWT (admin)

Create a user

POST /users

Auth: Bearer JWT (admin)

{"email": "operator@example.com", "password": "TempP@ss123!", "full_name": "John Doe", "role": "operator"}

Update user role

PUT /users/{user_id}/role

{"role": "admin"}

Deactivate a user

DELETE /users/{user_id}

Soft-deactivates the user. Cannot self-deactivate.

Role permissions

Get permissions

GET /settings/role-permissions

Update permissions

PUT /settings/role-permissions

Auth: Bearer JWT (admin)

Configure which settings tabs and nav pages each role can access:

{
"operator": {
"settings": ["tenant", "notifications", "units"],
"nav": ["dashboard", "machines", "alerts", "maintenance", "work-orders"]
},
"viewer": {
"settings": ["tenant", "units"],
"nav": ["dashboard", "machines", "alerts"]
}
}

AI settings

Get AI settings

GET /settings/ai

Update AI settings

PATCH /settings/ai

Auth: Bearer JWT (admin)

{
"ai_provider": "custom",
"custom_ai_url": "http://192.168.1.50:11434",
"custom_ai_model": "llama3"
}

Providers: platform (Haltless-hosted), custom (self-hosted Ollama, OpenAI-compatible)

List available models

GET /settings/ai/models?probe_url=http://192.168.1.50:11434

Dashboard presets

Get presets

GET /settings/dashboard-presets

Save a role's default layout

PUT /settings/dashboard-presets

Auth: Bearer JWT (admin)

{
"role": "operator",
"widgets": [
{"id": "stat-cards", "labelKey": "...", "visible": true, "size": "full"},
{"id": "at-risk-machines", "labelKey": "...", "visible": true, "size": "half"}
],
"statMetrics": [
{"metricId": "critical_count"},
{"metricId": "active_alerts"}
]
}

Unit preferences

Get preferences

GET /settings/units

Update preferences

PATCH /settings/units

{"temperature": "fahrenheit", "pressure": "bar"}

Data retention

Run manual cleanup

POST /settings/admin/retention/run

Auth: Bearer JWT (admin)

Triggers immediate cleanup of data beyond your tier's retention window.