Skip to content

Reports & Analytics

Breeze provides a full reporting and analytics subsystem for generating on-demand or scheduled fleet reports and querying real-time analytics data. Reports are scoped to organizations and enforce multi-tenant access at every layer — organization-scoped users see only their own data, partner-scoped users can access reports for any organization they manage, and system-scoped users have unrestricted access.

The system is split into two complementary route groups:

  • /reports — Saved report definitions, ad-hoc generation, run history, and raw data endpoints for device inventory, software, alerts, compliance, and performance metrics.
  • /analytics — Time-series queries, custom dashboards with widgets, capacity planning, SLA tracking, executive summaries, and OS distribution breakdowns.

Report Types

Every report has a type that determines which data is queried and how the output is structured.

TypeDescriptionKey columns / metrics
device_inventoryFull hardware and software asset listing per devicehostname, OS, agent version, CPU model, RAM, disk, serial number
software_inventoryAll installed software across targeted devicessoftware name, version, publisher, install date, device hostname
alert_summaryAlert history with severity breakdowntitle, severity, status, triggered/acknowledged/resolved timestamps, rule name
complianceDevice health and compliance posturehostname, OS, status, last seen, compliance flag, identified issues
performanceAggregated CPU, RAM, and disk metrics per deviceavg/max CPU %, avg/max RAM %, avg/max disk %
executive_summaryHigh-level fleet overview with device counts, alert stats, OS distribution, and site breakdownonline/offline totals, health %, critical/high alert counts, resolution rate

Report Configuration

When creating a saved report, you provide a config object that controls date ranges, filters, column selection, and sorting.

Date Range Presets

The config.dateRange object supports preset shortcuts or custom boundaries:

PresetMeaning
last_7_daysData from the past 7 days
last_30_daysData from the past 30 days
last_90_daysData from the past 90 days
customUse the explicit start and end ISO date strings

Filters

The config.filters object narrows the data:

FilterApplies toAccepts
siteIdsdevice_inventory, complianceArray of site UUIDs
deviceIdssoftware_inventoryArray of device UUIDs
osTypesdevice_inventorywindows, macos, linux
statusalert_summaryArray of status strings
severityalert_summaryArray of severity strings

Output Formats

FormatDescription
csvComma-separated values (default)
pdfFormatted PDF document
excelExcel spreadsheet (.xlsx)

Generating Reports

Breeze supports two generation flows: ad-hoc (stateless) and saved (tracked with run history).

Ad-hoc Generation

Use POST /reports/generate to produce report data immediately without creating a saved report definition. The response contains the generated data inline.

Terminal window
curl -X POST /api/v1/reports/generate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "device_inventory",
"format": "csv",
"orgId": "ORG_UUID",
"config": {
"dateRange": { "preset": "last_30_days" },
"filters": {
"osTypes": ["windows", "linux"]
}
}
}'

The response includes:

{
"type": "device_inventory",
"format": "csv",
"generatedAt": "2026-02-18T12:00:00.000Z",
"data": {
"rows": [...],
"rowCount": 42
}
}

Saved Report Generation

For saved reports, trigger generation with POST /reports/:id/generate. This creates a report run that is processed asynchronously.

  1. Create a saved report definition with POST /reports (see the API reference below).
  2. Trigger generation with POST /reports/:id/generate.
  3. Poll the run status with GET /reports/runs/:runId.
  4. When the run status is completed, use the outputUrl field to download the file.
Terminal window
# Trigger generation for a saved report
curl -X POST /api/v1/reports/REPORT_UUID/generate \
-H "Authorization: Bearer $TOKEN"

Response:

{
"message": "Report generation started",
"runId": "a1b2c3d4-...",
"status": "pending"
}

Scheduling

Saved reports support recurring schedules. When you set the schedule field, the report will be generated automatically on the configured cadence.

ScheduleBehavior
one_timeNo recurring generation (default). Must be triggered manually.
dailyGenerated once per day
weeklyGenerated once per week
monthlyGenerated once per month

Set the schedule when creating or updating a report:

Terminal window
curl -X POST /api/v1/reports \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekly Compliance Report",
"type": "compliance",
"orgId": "ORG_UUID",
"schedule": "weekly",
"format": "pdf",
"config": {
"filters": { "siteIds": ["SITE_UUID"] }
}
}'

Report Run Status Lifecycle

Each time a saved report is generated, a report run record tracks the process through a status lifecycle.

StatusMeaning
pendingThe run has been created and is queued for processing
runningThe report is actively being generated
completedGeneration succeeded; outputUrl contains the download path
failedGeneration failed; errorMessage contains the reason

The run record stores:

FieldDescription
idUnique run identifier (UUID)
reportIdThe parent saved report definition
statusCurrent lifecycle status
startedAtTimestamp when processing began
completedAtTimestamp when processing finished (success or failure)
outputUrlDownload path for the generated file (set on completed)
errorMessageError description (set on failed)
rowCountNumber of data rows in the output

Downloading and Exporting

When a report run reaches the completed status, the outputUrl field contains the download path. The format of the file matches the format field of the parent report definition (csv, pdf, or excel).

Terminal window
# Check run status
curl /api/v1/reports/runs/RUN_UUID \
-H "Authorization: Bearer $TOKEN"
# Response includes outputUrl when completed:
# "outputUrl": "/api/v1/reports/runs/RUN_UUID/download"

When retrieving a single report via GET /reports/:id, the response includes the five most recent runs, making it easy to find the latest completed download.


Analytics Endpoints

The /analytics route group provides real-time operational intelligence beyond static reports.

Time-Series Queries

POST /analytics/query executes a flexible time-series query across device metrics.

Terminal window
curl -X POST /api/v1/analytics/query \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"deviceIds": ["DEVICE_UUID_1", "DEVICE_UUID_2"],
"metricTypes": ["cpu", "ram"],
"startTime": "2026-02-01T00:00:00Z",
"endTime": "2026-02-18T00:00:00Z",
"aggregation": "avg",
"interval": "hour"
}'

Supported aggregations: avg, min, max, sum, count, p95, p99.

Supported intervals: minute, hour, day, week, month.

An optional groupBy array lets you split the series by additional dimensions.

Custom Dashboards and Widgets

Dashboards are per-organization containers for widgets. Each widget has a type and a config object that determines what data it renders.

Terminal window
curl -X POST /api/v1/analytics/dashboards \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "ORG_UUID",
"name": "NOC Overview",
"description": "Primary network operations dashboard",
"layout": {}
}'

Executive Summary

GET /analytics/executive-summary returns a high-level organizational overview including device totals (online/offline), a 12-week enrollment trend, and configurable period types.

Query parameterValuesDefault
periodTypedaily, weekly, monthlymonthly
rangeFreeform string
startDateISO date string
endDateISO date string

OS Distribution

GET /analytics/os-distribution returns the count of active devices grouped by osType and osVersion, excluding decommissioned devices.

Capacity Planning

GET /analytics/capacity returns capacity predictions based on current metric trends. Accepts optional deviceId and metricType query parameters to narrow scope.

SLA Tracking

SLA definitions set uptime or performance targets that are evaluated over a window.

FieldDescription
nameHuman-readable SLA name
targetPercentageTarget compliance percentage (0—100)
evaluationWindowdaily, weekly, or monthly
scopedevice, site, or organization
filtersAdditional scoping filters (JSON)

Compliance history for an SLA is retrieved via GET /analytics/sla/:id/compliance, which returns period-by-period entries with a status of met, breached, or warning.


Report Data Endpoints

The /reports/data/* endpoints provide raw, paginated data used to power report views and dashboards. These are read-only query endpoints that accept common filters.

EndpointReturns
GET /reports/data/device-inventoryDevice list with hardware details (CPU, RAM, disk, serial number, manufacturer, model)
GET /reports/data/software-inventoryInstalled software list with per-title device counts in a summary array
GET /reports/data/alerts-summaryAlert statistics: counts by severity, by status, daily trend (last 30 days), and top 10 alerting rules
GET /reports/data/complianceCompliance overview with device status breakdown, OS distribution, agent version spread, and identified issues (stale devices, outdated agents)
GET /reports/data/metricsPerformance metrics: fleet-wide averages for CPU/RAM/disk plus the top 10 consumers for each metric

All data endpoints accept these common query parameters:

ParameterDescription
orgIdFilter to a specific organization (required for partner scope)
siteIdFilter to a specific site
startDateStart of date range (ISO string)
endDateEnd of date range (ISO string)
limitPage size (default 100, max 1000)
offsetPagination offset

API Reference

Reports CRUD

MethodEndpointDescription
GET/reportsList saved reports. Filter by type, schedule, orgId. Paginated.
POST/reportsCreate a saved report definition with name, type, config, schedule, and format.
GET/reports/:idGet a single report with its 5 most recent runs.
PUT/reports/:idUpdate report name, config, schedule, or format.
DELETE/reports/:idDelete a report and all associated runs.

Report Generation

MethodEndpointDescription
POST/reports/generateAd-hoc generation. Returns data inline.
POST/reports/:id/generateTrigger async generation for a saved report. Returns a runId.

Report Runs

MethodEndpointDescription
GET/reports/runsList runs. Filter by reportId, status. Paginated.
GET/reports/runs/:idGet a single run with parent report metadata and download URL.

Report Data

MethodEndpointDescription
GET/reports/data/device-inventoryRaw device inventory with hardware join.
GET/reports/data/software-inventoryRaw software inventory with per-title summary.
GET/reports/data/alerts-summaryAlert breakdown by severity, status, daily trend, top rules.
GET/reports/data/complianceCompliance overview, stale device detection, agent version audit.
GET/reports/data/metricsFleet performance averages and top-10 resource consumers.

Analytics

MethodEndpointDescription
POST/analytics/queryExecute a time-series metrics query with aggregation and interval.
GET/analytics/dashboardsList dashboards. Filter by orgId. Paginated.
POST/analytics/dashboardsCreate a dashboard.
GET/analytics/dashboards/:idGet dashboard with all widgets.
PATCH/analytics/dashboards/:idUpdate dashboard name, description, or layout.
DELETE/analytics/dashboards/:idDelete dashboard and all its widgets.
POST/analytics/dashboards/:id/widgetsAdd a widget to a dashboard.
PATCH/analytics/widgets/:idUpdate widget name, type, config, or layout.
DELETE/analytics/widgets/:idRemove a widget from its dashboard.
GET/analytics/capacityCapacity planning predictions.
GET/analytics/slaList SLA definitions. Filter by orgId. Paginated.
POST/analytics/slaCreate an SLA definition.
GET/analytics/sla/:id/complianceGet compliance history for an SLA.
GET/analytics/executive-summaryExecutive fleet summary with enrollment trends.
GET/analytics/os-distributionOS type/version distribution for active devices.

Troubleshooting

Report run stuck in pending status

Report generation is processed asynchronously after POST /reports/:id/generate. If a run remains in pending for an extended period, check that the background job processor is running and connected to the database. Query GET /reports/runs/:id to inspect the run record — if startedAt is null, the job was never picked up.

”Organization context required” (403) on report endpoints

This error occurs when an organization-scoped token is used but the token lacks an orgId claim. Verify that the JWT includes the orgId field. Partner-scoped users must pass orgId explicitly as a query parameter or in the request body.

Data endpoint returns empty results despite existing devices

The /reports/data/* endpoints join against related tables (deviceHardware, deviceSoftware, deviceMetrics). If devices exist but related data has not been collected yet (e.g., hardware inventory has not been reported by the agent), joins may exclude those devices or return null fields. Check that agents are running and have submitted at least one heartbeat with hardware and software data.

Compliance score unexpectedly low

The compliance report flags a device as non-compliant if its status is decommissioned or if it has not been seen in the last 7 days. Devices that are powered off or in maintenance for extended periods will lower the compliance score. The compliance data endpoint also identifies stale_devices (not seen in 7+ days) and outdated_agents (running a version other than the most common version) as separate issues. Review the issues array in the response to understand which factors are contributing to the score.