API Reference
The self-hosted OmniSight API is served under /api. The public health check is served at /health.
Authentication
Console sessions use HttpOnly secure cookies. Mutating cookie-authenticated requests must include:
textX-Requested-With: XMLHttpRequest
Bearer token requests use:
textAuthorization: Bearer <token>
Agents authenticate with their persistent agent token after enrollment.
Health
GET /health
No authentication required.
json{
"status": "ok",
"service": "server",
"version": "1.2.2"
}
Auth Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/auth/login | Form login, sets cookies |
POST | /api/auth/refresh | Rotate refresh token and issue new cookies |
GET | /api/auth/me | Current user |
POST | /api/auth/logout | Revoke current token family and clear cookies |
/api/auth/me returns user profile, roles, and user-facing capability IDs such as dashboard, agents, agents_manage, agents_deploy, agents_remote_terminal, agents_remote_connect, agents_remote_approve, events, alerts, alerts_manage, audit_logs, users_manage, and notifications_manage.
Users
Requires users_manage.
| Method | Path | Description |
|---|---|---|
GET | /api/users | List users |
POST | /api/users | Create user and return one-time generated password |
PATCH | /api/users/{user_id}/permissions | Replace user capabilities |
DELETE | /api/users/{user_id} | Delete user |
PATCH | /api/users/me/password | Change own password |
Valid user-facing capabilities:
dashboardagentsagents_manageagents_deployagents_remote_terminalagents_remote_connectagents_remote_approveeventsalertsalerts_manageaudit_logsusers_managenotifications_manage
Agents
GET /api/agents
Requires agents.
Returns paginated agents:
json{
"items": [
{
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"agent_name": "workstation-01",
"hostname": "macbook-pro.local",
"os": "darwin",
"last_seen": "2026-05-20T18:00:00Z",
"status": "online"
}
],
"page": 1,
"page_size": 50,
"total": 1
}
status is effective status, not only the last raw heartbeat value.
GET /api/agents/{agent_id}
Requires agents.
Adds detail fields:
json{
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"agent_name": "workstation-01",
"hostname": "macbook-pro.local",
"os": "linux",
"arch": "amd64",
"ip_address": "192.168.1.70",
"last_seen": "2026-05-20T18:00:00Z",
"status": "online",
"remote_terminal_supported": true,
"remote_desktop_supported": false,
"remote_control_policy": "approval_required",
"interactive_user_present": false,
"remote_control_connected": true,
"created_at": "2026-05-20T17:59:00Z",
"updated_at": "2026-05-20T18:00:00Z"
}
GET /api/agents/{agent_id}/system-metrics
Requires agents.
Returns the latest aggregate metrics snapshot for one agent. If no sample exists yet, the response is still bounded and marks the metrics as stale/unavailable.
json{
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"sampled_at": "2026-06-22T18:29:34Z",
"stale": false,
"cpu_percent": 10.4,
"memory_total_bytes": 17179869184,
"memory_used_bytes": 11596411699,
"disk_total_bytes": 245135343616,
"disk_used_bytes": 222801543168,
"net_rx_bytes_per_sec": 9523.2,
"net_tx_bytes_per_sec": 2150.4,
"temperature_celsius": null
}
GET /api/agents/system-metrics/summary
Requires agents.
Returns compact latest metrics for the fleet, used by the dashboard and Agents table health indicators.
Agent metrics normally arrive through the agent-facing /api/ingest/metrics/ws WebSocket when available. The existing heartbeat path still carries the latest metrics sample as a REST fallback. Browser console pages continue to read metrics through permission-gated REST endpoints; browser WebSocket frames are lightweight nudges only and do not carry metric payloads.
Metric Interval Configuration
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /api/agents/metrics-config/global-default | agents | Fleet default metric interval |
PUT | /api/agents/metrics-config/global-default | agents_manage | Update the fleet default metric interval |
GET | /api/agents/{agent_id}/metrics-config | agents | Effective per-agent metric interval and ack state |
PUT | /api/agents/{agent_id}/metrics-config | agents_manage | Set or clear a per-agent interval override |
POST | /api/agents/{agent_id}/metrics-config/diagnostic | agents_manage | Start a time-limited 1s/2s diagnostic interval |
DELETE | /api/agents/{agent_id}/metrics-config/diagnostic | agents_manage | Clear the diagnostic interval early |
Interval changes are pushed live to connected agents over the metrics WebSocket and acknowledged; changes are recorded as bounded audit rows.
Protocol Metadata Configuration
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /api/agents/{agent_id}/protocol-meta-config | agents | Current DNS protocol metadata state and ack info |
PUT | /api/agents/{agent_id}/protocol-meta-config | agents_manage | Enable or disable Linux DNS query metadata for one agent |
DNS protocol metadata is Linux-only and default-off. The setting is pushed to the agent over the metrics WebSocket config channel; the agent keeps only DNS query metadata (name, type, response code, answer count) and never stores or transmits raw packet bytes.
PATCH /api/agents/{agent_id}
Requires agents:manage internally. Updates agent display name.
DELETE /api/agents/{agent_id}
Requires agents:manage internally. Deletes the agent row and cascades events.
GET /api/agents/deploy-token
Requires agents_deploy. Returns a 15-minute bootstrap enrollment token unless enrollment is disabled. Entitlement can block this endpoint.
Agent Install Sessions
These support the macOS Agent Installer app invite flow.
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /api/agents/install-sessions | agents_deploy | List recent invite sessions and seat usage |
POST | /api/agents/install-sessions | agents_deploy | Create a macOS invite |
POST | /api/agents/install-sessions/{session_id}/revoke | agents_deploy | Revoke an invite |
GET | /api/agents/install-sessions/{session_id}/launcher?token=... | session token | Legacy .command fallback launcher |
POST | /api/agents/install-sessions/{session_id}/claim | session token | Agent app claims manifest |
POST | /api/agents/install-sessions/{session_id}/events | session token | Agent app reports install lifecycle |
Create request:
json{
"platform": "macos",
"arch": "arm64",
"agent_name": "Finance MacBook"
}
Claim response includes:
- server URL
- bootstrap enrollment token
- artifact download URL
- optional agent name
- CA PEM for local/LAN TLS trust
Current session platform is macOS. Unsupported platforms return an error.
Remote Terminal
Remote terminal routes are mounted under /api/agents.
POST /api/agents/{agent_id}/terminal/sessions
Requires agents_remote_terminal.
Request:
json{
"reason": "Investigate suspicious outbound connection"
}
The reason must be at least 8 characters. The server must have remote access enabled, the agent must be online, terminal-capable, and connected to the remote-control channel.
POST /api/agents/{agent_id}/terminal/sessions/{session_id}/approve
Requires agents_remote_approve.
Returns:
json{
"session": {
"id": "0cd3e3b1-0663-42d8-b63c-dc4c5c8ebc81",
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"actor_user_id": 1,
"mode": "terminal",
"status": "approved",
"reason": "Investigate suspicious outbound connection",
"approval_state": "approved",
"started_at": null,
"ended_at": null,
"expires_at": "2026-05-20T18:05:00Z",
"close_reason": null,
"created_at": "2026-05-20T18:00:00Z"
},
"websocket_url": "/api/agents/{agent_id}/terminal/sessions/{session_id}/ws?token=...",
"token": "..."
}
POST /api/agents/{agent_id}/terminal/sessions/{session_id}/close
Requires agents_remote_terminal. Closes the browser/agent session and records a kill-request audit row.
Websockets
| Path | Used by |
|---|---|
/api/agents/{agent_id}/terminal/sessions/{session_id}/ws?token=... | Browser terminal |
/api/agents/control/ws?agent_id=... | Agent remote-control channel |
There are no remote desktop/RDP routes in the current release.
Events
GET /api/events
Requires events.
Query filters:
pagepage_sizeagent_idevent_typeprotocoldirectionprocess_nameremote_ipremote_portdomainstart_timeend_time
Common event types include:
connection_openconnection_seenconnection_closedns_queryweb_http_connectionweb_https_connection
web_http_connection and web_https_connection are endpoint connection metadata classifications based on destination protocol/port. OmniSight does not decrypt TLS, inspect request bodies, or collect browser request headers, cookies, paths, or payloads.
POST /api/events/search
Requires events.
Runs the command-driven Events Search Workspace query. Legacy GET /api/events remains available for existing consumers.
Request:
json{
"query": "event_type=\"connection_close\", remote_port=443",
"time_preset": "24h",
"start_time": null,
"end_time": null,
"timezone_offset_minutes": 180,
"page": 1,
"page_size": 50
}
Response:
json{
"items": [],
"total": 0,
"pagination": {
"page": 1,
"page_size": 50,
"total_pages": 0,
"has_previous": false,
"has_next": false
},
"normalized_filters": {
"query": "event_type=\"connection_close\", remote_port=443",
"clauses": [
{"field": "event_type", "operator": "=", "value": "connection_close"},
{"field": "remote_port", "operator": "=", "value": "443"}
],
"time_preset": "24h",
"start_time": null,
"end_time": null,
"timezone_offset_minutes": 180
},
"presence_counts": {
"event_type": 0,
"remote_ip": 0,
"process_name": 0
}
}
Supported time presets:
15m1h24h7d30dallcustom
Supported query fields:
idagent_idtimestampevent_typedirectionlocal_iplocal_portremote_ipremote_portprotocolprocess_namepiddomainorg
Supported operators:
text= != > >= < <=
Aliases:
timemaps totimestampagentmaps to agent identity contextlocal="IP:port"maps to local endpoint fieldsremote="IP:port"maps to remote endpoint fields
Rules and limits:
- query length: maximum 4096 characters
- clauses: maximum 20
page_size: default 50, maximum 100- text matching is case-insensitive
*is supported as a controlled wildcard- timestamp values accept ISO 8601 or
DD.MM.YYYY timestamp="DD.MM.YYYY"covers that calendar day in the supplied timezone offset- invalid fields, operators, and malformed clauses return a structured syntax error
Examples:
textevent_type="connection_close", remote_port=443
process_name="brave browser helper" direction="outbound"
timestamp>="15.06.2026"
remote_ip="18.97.*"
remote="18.97.36.5:443"
POST /api/events/facets
Requires events.
Returns top values for one allowlisted field inside the same query and time context.
Request:
json{
"query": "event_type=\"connection_close\"",
"time_preset": "24h",
"timezone_offset_minutes": 180,
"field": "remote_ip",
"limit": 10
}
Response:
json{
"field": "remote_ip",
"values": [
{"value": "18.97.36.5", "count": 12}
],
"normalized_filters": {
"query": "event_type=\"connection_close\"",
"clauses": [
{"field": "event_type", "operator": "=", "value": "connection_close"}
],
"time_preset": "24h",
"start_time": null,
"end_time": null,
"timezone_offset_minutes": 180
}
}
limit defaults to 10 and is capped at 50. Null values are omitted from facet values.
Saved Event Searches
Saved searches preserve repeatable Events investigations.
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /api/events/saved-searches | events | List private searches owned by the current user and shared searches visible to the user |
POST | /api/events/saved-searches | events; alerts_manage for shared | Create a private or shared saved search |
PATCH | /api/events/saved-searches/{search_id} | owner for private; alerts_manage for shared | Rename or update a saved search |
DELETE | /api/events/saved-searches/{search_id} | owner for private; alerts_manage for shared | Delete a saved search |
Create request:
json{
"name": "Outbound HTTPS by browser",
"query": "remote_port=443 process_name=\"brave browser helper\"",
"time_preset": "24h",
"visibility": "private"
}
Shared saved-search management reuses alerts_manage in the current release. Free-form query text is stored as saved-search data but is not copied into audit metadata.
Dashboard
Requires dashboard.
| Method | Path | Description |
|---|---|---|
GET | /api/dashboard/summary | Counts and latest summary |
GET | /api/dashboard/hourly-events | Hourly chart data |
GET | /api/dashboard/top-processes | Top processes |
GET | /api/dashboard/top-destinations | Top destinations/domains |
GET | /api/dashboard/geo-stats | Country distribution when enriched |
GET | /api/system/server/metrics | Local server-host aggregate CPU, memory, disk, network, and best-effort temperature metrics |
Dashboard metrics remain readable for users with dashboard. The refreshed Dashboard keeps the existing real time-range selector and now exposes a freshness affordance with last-updated time, manual Refresh, and live/reconnecting state. Dashboard page polling uses a 15-second cadence with resilient backoff/jitter behavior. Current release-line behavior also includes Dashboard Custom ranges, Charts All time, and the single healthy Live/cadence affordance shared with Agents and Alerts. Latest event details require events; without that capability, the dashboard reports a neutral no-permission state for that card while keeping aggregate metrics available.
System metric responses contain aggregate numeric values only. They do not include process command lines, per-connection tuples, ports, destinations, payloads, headers, cookies, TLS content, or secrets. Network throughput is computed from cumulative byte counters and may be null for the first sample, boot changes, or counter resets.
Reports
Reports reuse existing RBAC:
- summary preview requires
dashboard - Events CSV export requires
events - Alerts CSV export requires
alerts - schedule list requires
dashboard - schedule create, update, disable, delete, manual run, and one-off email send require
users_manage
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /api/reports/summary | dashboard | Daily, weekly, or custom SOC summary |
POST | /api/reports/export/events.csv | events | CSV export for Events Search context |
GET | /api/reports/export/alerts.csv | alerts | CSV export for alert queue context |
GET | /api/reports/schedules | dashboard | List report schedules and delivery state |
POST | /api/reports/schedules | users_manage | Create a daily or weekly SOC summary schedule |
PATCH | /api/reports/schedules/{schedule_id} | users_manage | Update or disable a report schedule |
DELETE | /api/reports/schedules/{schedule_id} | users_manage | Hard-delete a report schedule |
POST | /api/reports/schedules/{schedule_id}/run | users_manage | Manually run a schedule |
POST | /api/reports/email/send | users_manage | Send a one-off aggregate SOC summary email without creating a schedule |
Summary query parameters:
report_type:daily,weekly, orcustomstart_time: required for custom reportsend_time: required for custom reports
Events CSV export accepts the same query/time context used by the Events Search Workspace. Alerts CSV export supports alert queue filters such as status and severity.
CSV exports are row-bounded, audit-backed, and hardened against spreadsheet formula injection. Scheduled and one-off email delivery use OmniSight Cloud Relay and send aggregate SOC summary metrics only. Raw event rows, CSV attachments, report bodies, plaintext recipients, tokens, delivery credentials, database contents, and secrets are not included in relay audit metadata.
Notifications
All notification endpoints require notifications_manage.
| Method | Path | Description |
|---|---|---|
GET | /api/notifications/settings | Email alert notification settings |
PUT | /api/notifications/settings | Update enablement, severity threshold, filters, quiet hours, cooldown, and daily limit |
GET | /api/notifications/recipients | List email recipients |
POST | /api/notifications/recipients | Add a recipient |
PATCH | /api/notifications/recipients/{recipient_id} | Enable/disable or update a recipient |
DELETE | /api/notifications/recipients/{recipient_id} | Remove a recipient |
POST | /api/notifications/test | Send a test email notification |
GET | /api/notifications/deliveries | Email delivery history |
GET | /api/notifications/webhooks | List webhook endpoints |
POST | /api/notifications/webhooks | Create a webhook endpoint |
PATCH | /api/notifications/webhooks/{endpoint_id} | Update a webhook endpoint |
DELETE | /api/notifications/webhooks/{endpoint_id} | Delete a webhook endpoint |
POST | /api/notifications/webhooks/{endpoint_id}/test | Send a test webhook delivery |
GET | /api/notifications/webhooks/deliveries | Webhook delivery history |
Behavior notes:
- Email delivery uses the bounded cloud alert relay; webhook delivery posts
omnisight.alert.v1payloads directly from the self-hosted server to customer HTTP(S) endpoints. - Webhook endpoints are validated against unsafe destinations (SSRF/egress guard); insecure schemes to non-local targets are blocked.
- Webhook URLs are masked in API responses; optional signing secrets are stored encrypted and never returned.
- Test sends are duplicate-protected with per-endpoint cooldowns.
- All payloads carry bounded alert metadata only: no raw events, packet payloads, HTTP bodies, headers, cookies, TLS contents, command lines, endpoint files, credentials, tokens, environment values, or secrets.
Alerts
Alerts require alerts for read operations and alerts_manage for mutation/evaluation operations. alerts_manage includes the alert-read capability so Manage Alerts-only operators can enter the Alerts workspace and use management controls. The reverse is not granted: alerts users remain read-only. Current triage surfaces include maintenance-window management and suppression controls in the dense queue layout, but the underlying permission split remains unchanged.
The current Alerts workspace presents a dense SOC/admin triage layout with compact summary and filter areas, a two-column alert list and selected-alert detail flow, and lower-priority rules, custom rules, suppressions, and maintenance windows grouped below the primary queue. Long evidence and context content stays scroll-safe, and the bounded-metadata privacy note remains explicit.
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /api/alerts/summary | alerts | Alert counts by status, severity, verdict, and assignment |
GET | /api/alerts | alerts | Paginated alert queue |
GET | /api/alerts/{alert_id} | alerts | Alert detail with notes and linked evidence |
GET | /api/alerts/assignees | alerts | Active users eligible for alert assignment |
POST | /api/alerts/evaluate | alerts_manage | Run built-in alert evaluation |
GET | /api/alerts/rules/metadata | alerts | Event type, severity, MITRE, and mapping metadata for rule authoring |
GET | /api/alerts/rules/templates | alerts | Reusable SIEM detection rule templates |
POST | /api/alerts/rules/preview | alerts_manage | Dry-run a custom rule without creating alerts |
GET | /api/alerts/rules | alerts | List detection rules |
POST | /api/alerts/rules | alerts_manage | Create a custom detection rule |
GET | /api/alerts/rules/{rule_id} | alerts | Get rule detail |
PUT | /api/alerts/rules/{rule_id} | alerts_manage | Replace a custom rule (forbidden for built-in) |
PATCH | /api/alerts/rules/{rule_id} | alerts_manage | Partial update: enable, disable, or edit custom rule fields |
DELETE | /api/alerts/rules/{rule_id} | alerts_manage | Delete a custom rule (forbidden for built-in) |
GET | /api/alerts/suppressions | alerts | List active and historical suppressions |
POST | /api/alerts/suppressions | alerts_manage | Create a global, rule-scoped, or alert-scoped suppression |
DELETE | /api/alerts/suppressions/{suppression_id} | alerts_manage | Deactivate a suppression |
PATCH | /api/alerts/{alert_id} | alerts_manage | Update status, verdict, assignment, close reason, or note |
POST | /api/alerts/{alert_id}/snooze | alerts_manage | Snooze an alert for 1 hour, 24 hours, or 7 days |
POST | /api/alerts/{alert_id}/notes | alerts_manage | Add an analyst note |
List filters:
status_filter:open,in_progress,closedseverity:critical,high,medium,low,infoverdict:true_positive,false_positive,benign,expected_activity,duplicate,insufficient_dataassignment:assigned,unassigned
Update request example:
json{
"status": "in_progress",
"assigned_user_id": 2,
"note": "Assigned to analyst."
}
Use explicit assigned_user_id: null to clear assignment.
Custom rule requests can use automatic MITRE ATT&CK mapping. When mitre_mapping_source is omitted or set to auto, the server infers tactics and techniques from rule metadata such as event type, direction, protocol, ports, process, domain, organization, and thresholds. Template and manual mapping modes remain available for analyst override.
Matching active suppressions pause alert creation or updates during maintenance windows or analyst-approved snooze periods. The suppression list can include active, expired, and manually disabled rows. Historical rows show scope, target, reason, creator, start/end timestamps, and disable audit metadata when available. Suppression changes are managed through alerts_manage.
Alert responses include linked event IDs, linked event metadata, notes, and optional assigned_user display metadata.
Vulnerabilities and Inventory
The Vulnerabilities page combines endpoint software inventory with CVE/NVD matching through the private CVE service.
| Method | Path | Permission | Description |
|---|---|---|---|
GET | /api/vulnerabilities/summary | authenticated console user | Vulnerability counts by severity |
GET | /api/vulnerabilities/list | authenticated console user | Matched CVE findings for software inventory |
GET | /api/vulnerabilities/software | authenticated console user | Endpoint software inventory rows |
GET | /api/vulnerabilities/{cve_id}/raw | authenticated console user | Full raw NVD JSON detail for a single CVE |
The agent submits package metadata such as name, version, vendor, platform, architecture, source, install path when available, and last seen timestamp. OmniSight does not upload binaries or inspect application contents.
List responses stay lightweight and do not include raw NVD JSON. The raw detail endpoint fetches a single CVE detail through the configured CVE intelligence path and returns a generic unavailable response when upstream lookup fails; upstream URLs, API keys, headers, and internal errors are not exposed to the browser.
Audit
Requires audit_logs.
| Method | Path | Description |
|---|---|---|
GET | /api/audit/actions | Observed action names |
GET | /api/audit | Paginated audit rows |
Filters include action and actor_username.
Routine internal HTTP request traces are not shown as audit rows. Audit is reserved for authentication, administrative, install, entitlement, update, and remote terminal lifecycle activity.
System
Most system endpoints require users_manage.
| Method | Path | Description |
|---|---|---|
GET | /api/system/config | Basic config flags |
GET | /api/system/update-status | Account/server-aware update status |
GET | /api/system/entitlement-status | Signed entitlement lease state |
POST | /api/system/entitlement-refresh | Force lease refresh |
GET | /api/system/onboarding-status | Current onboarding state |
GET | /api/system/agent-artifacts | Eligible agent artifacts |
POST | /api/system/agent-download-session | Short-lived agent artifact download |
GET | /api/system/update-artifacts | Eligible update artifacts |
POST | /api/system/update-download-session | Short-lived update artifact download |
POST | /api/system/update-apply | Start native update apply |
GET | /api/system/storage/status | Managed storage sizing, retention settings, cleanup state, and last bounded result |
PATCH | /api/system/storage/settings | Update retention windows and automatic cleanup settings |
POST | /api/system/storage/maintenance | Start a manual storage cleanup, optionally with safe SQLite compaction |
Storage & Retention endpoints require users_manage. They report bounded size/count metadata only: database size, WAL size, server log size, agent log size, update rollback backup size, managed total, free disk, configured retention settings, in-progress state, and the last maintenance result. They do not return file contents, log contents, database rows, secrets, certificate material, or environment values.
Manual maintenance returns 202 only when a run is accepted and 409 when one is already active. Cleanup prunes managed retention targets, rotates/gzips logs, checkpoints SQLite WAL, can run SQLite compaction after a free-space preflight, and prunes only strict managed native update backup directories while retaining the newest configured rollback backups.
GET /api/system/menubar-status
Used by the macOS menu bar app. Requires a bearer token configured through MENUBAR_STATUS_TOKEN; it is not a normal browser endpoint.
Agent Ingest
POST /api/ingest/heartbeat
Agent endpoint.
Request fields:
agent_idagent_tokenagent_namehostnameip_addressos_familyarchstatusremote_terminal_supportedremote_desktop_supportedremote_control_policyinteractive_user_present
First enrollment also includes:
textX-Enrollment-Secret: <bootstrap-token-or-enrollment-secret>
Response includes assigned agent_id, optional one-time agent_token, entitlement payload, and remote_access_enabled.
POST /api/ingest/events
Agent endpoint for batched connection events. Event ingest can be denied by entitlement runtime policy.
POST /api/ingest/inventory
Agent endpoint for periodic software inventory batches. Inventory ingest uses the same enrolled agent token model as heartbeat and events, and is blocked when runtime entitlement blocks event ingest.
Request body:
json{
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"software": [
{
"name": "OpenSSL",
"version": "1.1.1",
"vendor": "OpenSSL Project",
"install_path": "/usr/bin/openssl",
"platform": "darwin",
"architecture": "arm64"
}
]
}
Response:
json{
"accepted": 1,
"created": 0,
"updated": 1,
"errors": []
}
Common Errors
| Status | Meaning |
|---|---|
400 | Invalid request |
401 | Missing/invalid auth |
403 | Permission, CSRF, entitlement, or remote access block |
404 | Resource not found |
409 | Conflict such as offline agent, seat limit, or already claimed session |
410 | Expired install session |
422 | Validation error |
429 | Rate limit |
500 | Server error |