Skip to main content

API Reference

The REST API gives you programmatic access to the same data as the Stealthium dashboard: security alerts, your GPU fleet, and fleet-wide metrics. All endpoints on this page live under https://api.stealthium.io/api/v1, require a bearer token, and return JSON. The API is read-only.

Account & key management live on a different host

Login, /me, API keys (including key rotation), and workspaces are served by https://api.backend.stealthium.io/api/v1 with the same bearer token — see Authentication and Creating an API Key.

Conventions

Errors. Every non-2xx response from a valid endpoint has the same body:

{ "error": "invalid_query", "message": "unknown filter field: severty" }
errorStatusMeaning
unauthorized401Missing or invalid bearer token.
invalid_query400Bad filter field/operator, sort field, id, page size, or timestamp — including any query parameter the endpoint doesn't know.
invalid_cursor400Malformed pagination token.
not_found404The resource (e.g. alert id) doesn't exist.
upstream_error502A backing service failed — retry later.
internal_server_error500Unexpected server failure.

A request to a path that doesn't exist returns the framework's default 404 body instead. (The account/key endpoints on api.backend.stealthium.io use a different error shape, {"title": "...", "detail": "..."}.)

Scoping. Every list endpoint accepts optional numeric scope filters as query parameters: customer_id, workspace_id, api_key_id (integers ≥ 1). Omit them to see everything your account can access.

Timestamps are RFC 3339 UTC strings, e.g. 2026-07-24T09:14:03Z. Time windows are half-open: from is inclusive, to is exclusive.

Unknown parameters are rejected. Endpoints validate their querystring strictly and return 400 invalid_query for anything they don't recognize — a typo'd parameter never silently widens your results.


Alerts

List alerts

GET /api/v1/alerts/

Returns alerts, newest first by default.

ParameterDescription
filter[<field>][<op>]Filter on a field — see Filtering below. Combine filters on different fields; they AND together.
sortSort field: timestamp (default), severity, type, state, hostname. Prefix with - for descending (default: -timestamp). Sorting by severity orders from critical down, not alphabetically.
page_sizePage size. Default 1000, max 10000.
page_tokenOpaque token from a previous response's next_page_token.
from, toOnly alerts within this time range (RFC 3339, half-open [from, to)).
customer_id, workspace_id, api_key_idScope filters.
curl -G "https://api.stealthium.io/api/v1/alerts/" \
--data-urlencode "filter[severity][in]=critical,high" \
--data-urlencode "page_size=100" \
-H "Authorization: Bearer <YOUR-JWT>"

Response:

{
"alerts": [
{
"id": "0b6ec7a4-52f7-4f7e-9df1-8f6f3f2b7c1d",
"title": "Unknown binary executed",
"description": "A binary not seen before on this host was executed.",
"type": "unknown_binary_exec",
"severity": "high",
"state": "active",
"created_at": "2026-07-24T09:14:03Z",
"hostname": "gpu-node-17",
"gpu_model": "NVIDIA H100 80GB HBM3",
"gpu_serial": "1650923000000",
"workspace_id": 3,
"api_key_id": 12
}
],
"next_page_token": "eyJ2IjoiMjAyNi0wNy0yNFQwOToxNDowM1oi...",
"total_size": 148
}

hostname, gpu_model, gpu_serial, workspace_id, and api_key_id are null when not applicable to the alert.

Filtering

Filters use the form filter[<field>][<op>]=<value>. The operators depend on the field type:

FieldsOperatorsNotes
severity, type, statein, notIn, equals, notEqualsin/notIn take a comma-separated list.
hostname, title, descriptioncontains, notContains, startsWith, endsWith, equals, notEqualsFree text.
timestampgte, lteRFC 3339 values. Combine both for a range.

Valid values: severity is one of critical, high, medium, low, info; state is active or ignored.

All type values

cpu_usage, gpu_usage, gpu_firmware, gpu_shader, gpu_dma, gpu_power, gpu_interrupt, gpu_command, gpu_memory, gpu_ransomware, gpu_texture, gpu_pcie, gpu_thermal, gpu_throttle, gpu_ecc, gpu_nvlink, process_anomaly, privilege_escalation, command_line_anomaly, system_info_change, network_anomaly, cpu_anomaly, kernel_oops, container_sensitive_mount, container_gpu_access, container_privileged, container_escape, container_cgroup_escape, unknown_binary_exec, rogue_ebpf, gpu_driver_access, c2_covert_channel, model_poisoning, controlplane_integrity, controlplane_credential_attack, controlplane_saturation, controlplane_slo, controlplane_etcd_storage, controlplane_kcm, vm_escape, ray_job_rce

Pagination

Pagination is token-based. While next_page_token is present, pass it back as page_token to get the next page — pages never overlap or skip alerts. total_size is computed only on the first page (a request without a page_token) and is null on later pages.

Alert summary (facet counts)

GET /api/v1/alerts:summary

Per-value alert counts for severity, type, and state — useful for building filter UIs. Accepts the same filter, time-range, and scope parameters as List alerts (but not sort/page_size/page_token — an aggregate has no pages). Each column's counts ignore any filter on that same column, so selecting severity=high doesn't zero out the other severity buckets.

curl -G "https://api.stealthium.io/api/v1/alerts:summary" \
--data-urlencode "filter[state][equals]=active" \
-H "Authorization: Bearer <YOUR-JWT>"

Response:

{
"summary": {
"severity": [
{ "value": "high", "count": 12 },
{ "value": "medium", "count": 30 }
],
"type": [
{ "value": "gpu_memory", "count": 18 },
{ "value": "process_anomaly", "count": 24 }
],
"state": [
{ "value": "active", "count": 42 },
{ "value": "ignored", "count": 7 }
]
}
}

Alert severity trend

GET /api/v1/alerts:severityTrend

Per-severity alert counts grouped into time buckets (hour or day, chosen from the window width) — ready for a trend chart. Takes the same filter/time/scope parameters as the summary.

{
"points": [
{ "bucket": "2026-07-23T00:00:00Z", "severity": "high", "count": 4 }
]
}

Get alert details

GET /api/v1/alerts/{id}

Full detail for one alert. {id} is the alert UUID from List alerts. The response is one flat object: the list fields plus workspace_name, customer_id, summary_data, resource_details, and correlated_alerts. session_id and host_id appear when the alert has an associated agent session, and are omitted otherwise.

curl "https://api.stealthium.io/api/v1/alerts/0b6ec7a4-52f7-4f7e-9df1-8f6f3f2b7c1d" \
-H "Authorization: Bearer <YOUR-JWT>"

Response:

{
"alert": {
"id": "0b6ec7a4-52f7-4f7e-9df1-8f6f3f2b7c1d",
"title": "Unknown binary executed",
"description": "A binary not seen before on this host was executed.",
"type": "unknown_binary_exec",
"severity": "high",
"state": "active",
"created_at": "2026-07-24T09:14:03Z",
"hostname": "gpu-node-17",
"workspace_id": 3,
"workspace_name": "production",
"customer_id": 1,
"api_key_id": 12,
"summary_data": { "alert_info": { "title": "…", "description": "…" }, "alert_sequence": { "steps": [] } },
"resource_details": {
"process_details": {
"title": "python3",
"process_name": "python3",
"pid": 41233,
"start_time": "2026-07-24T06:02:11Z",
"current_status": "running",
"last_modified": "",
"parent_process_pid": 41200,
"command_line": "python3 train.py --epochs 10"
},
"memory_details": null,
"workload_details": null,
"gpu_details": {
"gpu_id": "0001:00:00.0",
"model": "NVIDIA H100 80GB HBM3",
"vendor": "NVIDIA",
"gpu_utilization": "87",
"temperature": "64",
"driver_version": "550.54.15",
"firmware_version": "96.00.74.00.01",
"serial_number": "1650923000000",
"power_draw": "512",
"fan_speed": "55",
"clock_throttle_events": "",
"host_id": "gpu-node-17",
"node": "gpu-node-17",
"utilization_data": [{ "time": 0, "value": 85 }],
"temperature_chart": [{ "time": 0, "value": 63 }]
},
"node_details": {
"node_id": "gpu-node-17",
"uptime": "86400",
"cpu_load": "3",
"number_of_cpus_attached": "64",
"cpu_utilization_average": "4.7%"
},
"container_details": null
},
"correlated_alerts": { "correlated_alerts": [] }
}
}

resource_details always has the same six keys; a section is null when the alert carries no data for it (node_details is always present). summary_data.alert_sequence and correlated_alerts currently contain illustrative placeholder data, not real correlation results — don't build logic on them yet.

Get alert timeline

GET /api/v1/alerts/{id}/timeline

The process-level events recorded around the alert.

curl "https://api.stealthium.io/api/v1/alerts/0b6ec7a4-52f7-4f7e-9df1-8f6f3f2b7c1d/timeline" \
-H "Authorization: Bearer <YOUR-JWT>"

Response:

{
"timeline_events": [
{
"ts": "2026-07-24T09:13:58Z",
"pid": 41233,
"tid": 41233,
"event_type": "process_exec",
"event_info": "process started",
"comm": "python3",
"command_line": "python3 train.py --epochs 10",
"args": ["--epochs", "10"],
"pwd": "/home/ml/jobs"
}
]
}

comm, command_line, args, and pwd are omitted (not null) when the event doesn't carry them.


GPUs

List GPUs

GET /api/v1/gpus

Every GPU in your fleet with its identity, health, and freshest telemetry.

ParameterDescription
from, toTelemetry window for the row's utilization/temperature/XID numbers (RFC 3339).
viewfull (default) or basicbasic drops the per-row utilization_series sparkline.
page_sizeCap the number of rows.
customer_id, workspace_id, api_key_idScope filters.
curl "https://api.stealthium.io/api/v1/gpus" \
-H "Authorization: Bearer <YOUR-JWT>"

Response:

{
"gpus": [
{
"gpu_id": "GPU-8f2c1a7e-1d2b-4c3d-9e8f-0a1b2c3d4e5f",
"workspace_id": 3,
"vendor": "NVIDIA",
"model": "H100 80GB HBM3",
"compute_stack": "CUDA 12.4",
"driver_version": "550.54.15",
"health": "healthy",
"hostname": "gpu-node-17",
"pcie_address": "0001:00:00.0",
"serial_no": "1650923000000",
"utilization_pct": 87.5,
"temperature_c": 64,
"xid_errors": 0,
"utilization_series": [81, 85, 87.5],
"last_seen": "2026-07-24T09:14:03Z"
}
]
}

health is healthy, degraded, critical, or missing (the GPU stopped reporting). utilization_pct, temperature_c, and xid_errors are null when no recent telemetry exists — for xid_errors, null means unknown, not zero.

Get GPU details

GET /api/v1/gpus/{id}

Full detail for one GPU. {id} is the gpu_id exactly as returned by List GPUs — either the GPU-… UUID or a host|pci|guest composite for GPUs without a UUID. A bare PCIe address does not resolve (404).

The response groups everything the dashboard shows:

SectionContents
specsSerial number, compute stack, driver/firmware versions, hostname, PCIe address, MIG state.
security, security_diagnosticsAlert counts for the last 24h, per-severity breakdown, recent XID error rows.
xidXID error count (24h), 7-day trend (rising/flat/falling), last error code.
telemetryLive utilization, memory, temperature, power, fan — each with a history series for sparklines.
processesProcesses currently using the GPU, with per-process utilization and memory.
utilizationBusy/idle breakdown, usage categories, analyzed-event counts, process families.

Fields with no data are returned empty or null rather than omitted, so the response shape is stable.

curl "https://api.stealthium.io/api/v1/gpus/GPU-8f2c1a7e-1d2b-4c3d-9e8f-0a1b2c3d4e5f" \
-H "Authorization: Bearer <YOUR-JWT>"

Response (abridged):

{
"gpu": {
"gpu_id": "GPU-8f2c1a7e-1d2b-4c3d-9e8f-0a1b2c3d4e5f",
"vendor": "NVIDIA",
"model": "H100 80GB HBM3",
"health": "healthy",
"specs": {
"serial_no": "1650923000000",
"compute_stack": "CUDA 12.4",
"driver_version": "550.54.15",
"firmware_version": "96.00.74.00.01",
"hostname": "gpu-node-17",
"pcie_address": "0001:00:00.0",
"mig_enabled": false
},
"security": { "total_alerts_24h": 2, "alerts_by_severity": [0, 1, 1, 0] },
"xid": { "errors_24h": 0, "trend_7d": "flat", "last_code": null },
"telemetry": {
"utilization_pct": 87.5,
"memory_used_gb": 42.1,
"memory_total_gb": 80,
"temperature_c": 64,
"power_draw_w": 512,
"power_limit_w": 700,
"fan_pct": 55,
"history": {
"utilization": [81, 85, 87.5],
"memory": [40.2, 41.8, 42.1],
"temperature": [62, 63, 64],
"power": [498, 505, 512]
}
},
"processes": [
{
"pid": "41233",
"name": "python3",
"description": "binary python3",
"usage_category": "training",
"gpu_utilization_pct": 85,
"memory_usage_gb": 38.4,
"started_at": "2026-07-24T06:02:11Z"
}
],
"last_refreshed_at": "2026-07-24T09:14:03Z"
}
}

security.alerts_by_severity is a fixed 4-tuple of counts: [critical, high, medium, low]. A process's usage_category is the workload class the analyzer assigned ("training", "inference", …; "" = unclassified).


Metrics

Get fleet metrics

GET /api/v1/metrics

Fleet-wide metrics: alert counts with histograms, top alert types, live asset counts, and aggregated telemetry — the same numbers the dashboard shows.

ParameterDescription
from, toTime window for the counts and histograms (RFC 3339). Defaults to the last 90 days.
customer_id, workspace_id, api_key_idScope filters.

Counts mean "seen within the window", not "connected right now" — with the 90-day default, gpu_count includes GPUs that last reported weeks ago. Narrow the window for a live view.

curl "https://api.stealthium.io/api/v1/metrics?from=2026-07-17T00:00:00Z&to=2026-07-24T00:00:00Z" \
-H "Authorization: Bearer <YOUR-JWT>"

Response:

{
"metrics": {
"alerts_by_severity": [
{
"label": "critical",
"value": 2,
"data": [{ "date": "Jul 23", "value": 1 }]
}
],
"top_alert_types": [
{ "icon": "gpu_memory", "title": "gpu_memory", "count": 18 }
],
"asset_coverage": [{ "label": "gpus", "count": 24, "data": [] }],
"metrics_summary": {
"gpu_count": 24,
"avg_gpu_utilization": 71.4,
"avg_gpu_temperature": 63.2,
"total_xid_errors": 3,
"container_count": 112,
"vm_count": 4
},
"metrics_charts": { "…": "chart series keyed by metric" }
}
}

top_alert_types carries at most the top 3 types. metrics_charts holds chart-ready series whenever metric data is in scope.

metrics_summary aggregates telemetry across the fleet. Its stable keys, grouped by domain:

DomainKeys
GPU fleetgpu_count, avg_gpu_utilization, avg_gpu_temperature, avg_gpu_power, avg_gpu_memory, avg_gpu_fan_speed, avg_clock_speed, avg_memory_clock
GPU healthavg_health_score, avg_thermal_slope, total_ecc_errors, total_xid_errors, active_crash_chains, total_throttle_events
CPU & processesavg_cpu_load, avg_cpu_utilization, process_count, avg_fork_rate, avg_exit_rate
Containers & VMscontainer_count, gpu_container_count, mps_container_count, container_process_count, vm_count

Averages (avg_*) are across the fleet seen in the window; totals (total_*, *_count) are sums. Additional keys appear as the platform grows — treat anything not listed above as unstable.