Reports Reference
REST endpoints, widget catalogue, evaluation limits and permissions for reports.
The Reports area builds custom PDF reports from a library of widgets. This page documents the behaviours, permissions, layout grid, and widget catalogue that the schema alone cannot express.
For the complete, always-current list of endpoints, parameters, and response fields for the version you are running, use the interactive OpenAPI (Swagger) interface at https://<your-octoja-instance>/openapi/index.html.
For an end-to-end walkthrough of creating a template and generating a PDF, see Create a report template.
REST endpoints
All Reports endpoints live under /api/reports/. The Notes column carries the required permission (octoja uses custom permission policies that are not all expressed in Swagger) plus the non-obvious behaviour.
Behaviours worth knowing
- Clone on create:
cloneFromTemplateIdmust be a GUID-formatted string when present; the new template is a deep copy of the source's rows + widgets, including itsdeviceRulesdevice filter. - UpdateValue envelope: the update body wraps each field, e.g.
{ name?: { hasValue: true, value }, rows?: { hasValue: true, value }, orientation?: { hasValue: true, value }, deviceRules?: { hasValue: true, value } }. The update is partial — fields omitted from the body (or sent withouthasValue: true) are left untouched on the stored template, not cleared. - Generate range: the optional
rangeStart/rangeEnd(ISO dates) restrict time-windowed widgets to a reporting period — pass both or neither; omit them for an all-time report.
Schema and fields
The full field list and types for ReportTemplate, ReportRow, and ReportWidget are in Swagger. The fields below carry behaviour the schema cannot convey.
- name — for built-in templates this is an i18n key (e.g.
pages.reports.builtIns.executiveSnapshot.name), localized on display; for custom templates it is the literal user-entered string. - isBuiltIn — response-only / derived. Server-computed from a built-in id allowlist rather than persisted on the entity;
truefor templates that ship with octoja,falsefor tenant-created custom templates. - slug — the name-localization key for built-in templates. Their PDF filename uses the slugified display name in the selected report language. Custom templates use
slugwhen set, otherwise the slugifiedname(defaultnull). - iconName — Lucide icon component name on the template card. Built-ins only (default
null). - orientation —
Portrait(default) orLandscape. Landscape fits wide tables such as the hardware inventory; an invalid value returns400 Bad Request. - deviceRules — the report-wide device filter, stored on the template (the Device filter button on the template page). A list of rule groups combined with OR; each group carries a
matchmode (AllorAny) and a list of rule items, the same sentence-builder shape used for tag rules. Empty by default, which means every device in scope. See Scope semantics. - columnSpan (widget) — number of grid columns occupied (default
1). Bounded per-widget; each widget type declares its ownminColumnSpan,maxColumnSpan, anddefaultColumnSpan, which the editor enforces. - rowSpan (widget) — height in editor rows;
0(default) means "use the widget's default row span". - config (widget) — widget-specific settings whose shape depends on the widget
type; refer to the editor's properties panel for the available options. - backgroundColor (widget) — one of a fixed set of tints (
Indigo,Emerald,Amber,Sky,Rose,Slate); the Callout widget uses the same set. - autoStatusColor (widget) — when
true, data-driven widgets (KPI cards, gauges) tint themselves by the value's severity (green OK, amber Warning, red Critical). No effect on widgets that declare no auto-status thresholds.
A ReportRow has no configurable properties of its own — it groups widgets horizontally and triggers a natural page break when the grid runs out of room.
The four-column grid
The report canvas is a fixed four-column grid. Each widget's columnSpan declares how many of the four columns it occupies. A row can hold any combination of widgets whose columnSpan values sum to four or less. When you add a fifth widget to a row that already sums to four, octoja places it in a new row.
Typical spans: 1 = quarter-width (KPI cards, small gauges); 2 = half-width (info cards, charts); 3 = three-quarters (a wide table beside a narrow card); 4 = full-width (hero charts, tables that need every column).
Widget catalogue
Widgets are grouped into six categories — KPI cards, Charts, Tables, Info cards, Layout, and Checks. The notes below capture each widget's scope-awareness and any non-obvious behaviour; GET /api/reports/widgets/available returns the authoritative live catalogue for the current build. Unless noted otherwise, every data widget is scope-aware (it honours the report's customer / site filters).
KPI cards (Kpi)
Single-value indicators with a coloured header and an optional auto-status tint. The catalogue is large and grows with the product — examples include Total Devices, Online Devices, Open Cases (count of non-closed cases — any status other than Closed), Health Score, Low Disk Devices, Patch Compliance, Certs Expiring ≤30d, plus activity, backup, monitoring, Lywand, software-inventory, and incident KPIs. All KPI cards are scope-aware. Patch Compliance, Endpoint Protection, and their matching Management scorecard pillars exclude network devices; patch compliance considers servers and workstations only, while endpoint protection uses the device kinds in its configuration. When a pillar has no eligible device, it remains unknown and is not included as a zero in the overall score.
Several KPI cards derive their value from a specific monitoring check rather than from device inventory, so they render a — placeholder unless that check is assigned to devices in the report's scope:
- Availability — average online availability across the reporting period, computed from the stored Device online check history (the share of recorded samples that came back Ok). Only devices with that check assigned are evaluated, and the card can be narrowed further to specific devices (default All devices) or to a Device filter rule of its own. With no reporting period set, the window falls back to the last 30 days. Auto-status thresholds: 95% or more Ok, 80% or more Warning, anything below Critical.
- Sophos protection active — the number of devices whose Sophos Antivirus check last returned Ok, out of the devices in scope that have that check assigned. Same auto-status thresholds: 95% or more of those devices protected is Ok, 80% or more Warning, anything below Critical.
- SLA Incidents — how many incidents (unbroken runs of Warning or Critical results) the selected check recorded in the reporting period.
- Mean Time to Resolve — average time in hours those incidents took to recover. Incidents still open at the end of the window are left out, because their duration is not yet known. Auto-status thresholds: 4 hours or less Ok, 24 hours or less Warning, anything longer Critical.
- Service Uptime (time-weighted) — the share of monitored time in the period that was not covered by an open incident. Auto-status thresholds: 99% or more Ok, 95% or more Warning, anything below Critical.
The three SLA cards take a check plus an optional device list, and pair with the SLA Incidents table in the built-in SLA Report template.
Antivirus evaluation includes the generic antivirus-status check plus Acronis Cyber Protect Antivirus, Bitdefender, ESET, G DATA, Securepoint, SentinelOne, Sophos, ThreatDown, VIPRE and WatchGuard EPDR. A device counts as protected when at least one of its included checks has effective status OK; several such checks do not count the device more than once. Backup reporting includes Acronis Cyber Protect, NAKIVO and Veeam Microsoft 365, among other built-in backup checks and checks with repository category backup. Installing a product alone does not establish corresponding check evidence in the report without an assigned check.
Charts (Chart)
- Device Age (bar chart) — histogram of devices by age band (e.g. < 1y, 1–3y, 3–5y, > 5y).
- OS Distribution (bar chart) — devices grouped by operating system family.
- Device Kinds (donut) — devices grouped by kind (workstation, server, etc.).
- Disk Usage Buckets (donut) — devices grouped by overall disk-usage bucket.
- Cases by Priority (donut) — non-closed cases grouped by priority. Closed cases are excluded, matching the Open Cases KPI.
- Activity by Source (donut) — activity events grouped by source.
Tables (Table)
- All Devices (Table) (
table-devices) — devices with name, OS, last-seen and health. OptionalcustomFieldKeyadds a Markdown device field; the editor labels this selection Markdown custom field. - Network Devices (Table) (
table-network-devices) — monitored network devices with customer, type, IP, manufacturer/model and last seen. Sorted by device name;config.limitdefaults to 100, maximum 1,000. Unknown device types and unadopted scan discoveries are excluded. - Custom Fields (Table) (
table-custom-fields) — selected device or customer fields with effective values including defaults.entityTypeisDeviceorCustomer,fieldscontains field keys,filterisAll,PopulatedorNonDefault;showDefaultsonly controls default-value labels in column headers.limitdefaults to 100, maximum 1,000. Customer rows respect customer and user scope, not site or device rules. See Create a report template for selection, filter limits and Markdown rendering. - Recent Cases — recent cases with title, status, priority, customer, and date.
- Certificate Expiry Table — certificates due to expire, grouped by days remaining.
- Disk Space Table — devices ordered by least free disk space.
- Top Manufacturers — devices grouped by hardware manufacturer.
- Incident Timeline — chronological list of incidents within the scope.
- Backup Status — backup job runs with target, status, and last success.
- Local Users — local accounts present on devices in the scope.
- Vulnerabilities — vulnerability findings surfaced by the Lywand integration.
- Monitoring Summary — monitoring check state across devices. Individual checks can be kept out of the table with the widget's Hide checks setting.
- Checks without Alerting (Table) — checks assigned to devices in scope that have no alerting configured, with the device, the check, and the config package the assignment came from. Also honours Hide checks.
- Remote Times (table) — remote-support time spent on the scope's devices during the reporting period, with start time, technician, device, and duration. Grouping switches between one row per session, per device, and per technician; the widget also carries a Device filter of its own. Only the ungrouped per-session view also shows the remote session's Note; grouping by device or technician hides it. With no reporting period set, the window falls back to the last 30 days. It is the centrepiece of the built-in Remote Times template.
- Top Installed Software — most-installed software titles across the scope's devices.
- Software Changes (table) (
table-software-changes) — installed, updated, and uninstalled software, newest change first. An update is a removed and added product with the same name in one inventory change; it shows the previous and new versions. Initial inventories (nobaseHash) are excluded. The widget honours period, customer, site, device filter, and user scope.config.limitdefaults to500; the shared properties panel accepts 1–1,000. - Hardware Inventory — one row per device with a configurable set of hardware fields, grouped into System, Identity, CPU, Memory, Storage, and Network. The optional Enrolled system field (
enrolledAt) outputs the enrollment date and is not part of the default field set. - Patch History — installed updates per device, with KB number and install date.
- Pending Patches — updates still outstanding per device. Carries a Device filter of its own, applied on top of the report-wide one.
Patch performance evidence and current status
The Patch Performance Evidence template documents completed work: its activity table shows the latest completed attempt per device and update within the selected period, or across all available results if no period is set. It does not count every retry as additional work. Definition updates are included in full by default.
Current Patch and Action Status instead answers what still needs attention. Its table starts from pending updates in device inventory and adds the latest execution and approval status. An approved update is therefore not yet an installed update. Definition updates are reduced to the latest per device and definition family by default.
Both tables support Latest, All or Exclude for definition updates; the default row limit is 500, with a maximum of 1000. The fully patched device summary counts devices with inventory and no pending updates, divided by all selected devices. Missing inventory does not count as fully patched; inventory age is not checked in this calculation. Also review when devices last reported.
Info cards (Info)
- Device Summary — server-resolved roll-up of devices in scope (totals + breakdown).
- Customer Breakdown — server-resolved customer roll-up (names + counts), filtered by the report's customer and site scope.
- Management scorecard — one overall score with a traffic-light status, broken into pillars that reuse the same green/amber/red bands as the matching standalone KPI cards. Individual checks can be kept out of the score with Hide checks.
- Gauge (Static) — single gauge with a configurable value range and severity thresholds. Author-provided value — does not query live data and is not scope-aware.
- Traffic Lights — author-curated grid of status cells (
Ok/Warning/Critical/Unknown). Author-provided, and not scope-aware.
Checks (Checks)
- Check Detail — details for one or several checks (current state, last result, configuration summary), including the device's last user and last seen time. The limit applies per check; changing the check selection clears the previous device selection.
- Check History (per device) — per-device result history for a single check, one entry per device with its recent trend. Can be narrowed to specific devices or statuses.
- Check Status Timeline — timeline of a single check's state transitions across the scope.
- Check Status Distribution (donut) — a selected check's result distribution (Ok / Warning / Critical / Unknown).
- Check Status History (chart) — time-series of a selected check's result history across the scope.
- Check Success Rate — KPI card with the share of devices whose latest result for a selected check is Ok. Can be narrowed to specific devices or statuses. Auto-status thresholds: above 90% Ok, above 70% Warning, anything below Critical.
- Check Results (Table) — per-device results for a selected check (status, value, last evaluated).
- Check Alerting by Device — per device, a selected check's latest result alongside its alerting posture: no alerting configured, alerting configured and quiet, or an alarm currently open. Capped by the widget's Limit (default 50).
- SLA Incidents — every incident (an unbroken run of Warning or Critical results) for a selected check within the reporting period, with device, start, resolution, duration, and worst status. The table echoes the window the numbers actually cover: check results are kept for 30 days by default, so a longer period yields only the history still on file. Capped by Limit (default 50).
- Sophos status (table) — per-device Sophos detail from the Sophos Antivirus check: device, status, real-time protection, definitions current, threats, health, and version. Only devices with that check assigned appear; rows are ordered worst status first and capped by the widget's Limit (default 50). The built-in Sophos Report template pairs this table with the Sophos protection active KPI.
Layout (Layout)
Structural widgets — no live data, and not scope-aware.
- Heading — section heading text.
- Paragraph — body paragraph text.
- Callout — coloured callout box with one of the six background colours.
- Bullet List — bullet list with marker style
Dot,Check, orDash. - Divider — horizontal rule.
- Spacer — vertical whitespace.
- Page Break — forces a page break at this point in the PDF.
Scope semantics
When a report is generated, the request payload carries customerId? and siteId? — both optional, and a siteId is only meaningful when paired with a customerId. The renderer narrows every scope-aware widget's data query to that customer (and optional site).
Widgets that are not scope-aware (the Gauge, the Traffic Lights grid, and all Layout widgets) ignore the scope — their content is author-provided and renders the same regardless of customerId / siteId.
Customer and site scope is not stored on the template. It is a generate-time parameter — the same template can produce a tenant-wide report, a per-customer report, or a per-site report depending on what is passed to the generate call.
The device filter is the one piece of scope that is stored on the template. The deviceRules field holds rule groups combined with OR (a device matches if it satisfies any group), and every device-derived widget is narrowed to the matching devices on top of the customer / site scope. Case widgets are not device-filtered. Set it from the Device filter button on the template page, update it through the deviceRules UpdateValue, and note that cloning a template copies it along with the rows. A filter can match Chassis type, among other inventory fields.
Requested scope can never widen the signed-in user's access. Preview and PDF generation additionally intersect devices, customers, cases, and time entries with that user's current group scope. Widget option lists are scoped too. A user with no accessible devices receives no device data even if the customer/site or device filter would otherwise match.
Built-in vs custom templates
Both types share the same schema and editor experience. The differences are behavioural:
- Created by — built-in ships with octoja; custom is created by you.
- name — built-in is an i18n key (localized on display); custom is the literal user string.
- slug / iconName — set on built-ins (
slugsupplies the name-localization key,iconNamethe card icon); their PDF filename follows the display name in the report language.nullon custom (filename slugified fromname, generic template icon). - Edit — built-ins are read-only; clone first to customize. Custom templates are editable.
- Delete — built-ins are protected server-side; custom templates are deletable.
- Duplicate — allowed for both, and always produces a new custom template.
Permissions
The Reports area uses two permissions:
- reports.view — listing templates, opening one, rendering the editor preview, generating a PDF, and listing or opening schedules.
- reports.manage — creating, editing, deleting, and renaming custom templates; reading the widget palette and its check-asset picker; and creating, updating, deleting, or immediately running schedules.
Both are granted via groups in Administration → Groups.
PDF filename
The generated PDF's filename is set by the content-disposition header on the response:
- Built-in template:
<slugified-display-name>-<yyyy-mm-dd>.pdf, using the display name in the selected report language — for example,hardware-inventory-2026-04-20.pdfin English andhardware-inventar-2026-04-20.pdfin German. - Custom template:
<slugified-name>-<yyyy-mm-dd>.pdf(e.g.quarterly-customer-review-2026-04-20.pdf).
The date is the date of generation. The report's data window is a separate setting: the optional rangeStart / rangeEnd reporting period on the generate call (the Period selector in the UI, with All time, Current month, Last month, and Custom presets). Time-windowed widgets honour it; point-in-time widgets such as the inventory tables always reflect the current state.
PDF language
The generate call takes an explicit language parameter, and the template page has a Language dropdown next to the download button. Pick a language there and the PDF comes out in it, whatever the UI is set to. The dropdown starts on your current UI language.
Supported values are en, de, es, fr, it, and nl; any other value returns 400 Bad Request. When language is omitted from the request, the PDF falls back to the locale carried by the Accept-Language header. The editor preview endpoint takes the same parameter with the same fallback.
Scheduling
Reports can be delivered automatically on a recurring basis. A schedule bundles one or more report templates with a cron expression and a set of receivers; when the schedule fires, octoja generates each template as a PDF and emails it to the receivers. The reports page has a Scheduling entry that opens this management area.
- cron — a standard 5-field cron expression, evaluated in the instance time zone (
Europe/Berlinby default; UTC only if the instance has no valid time zone configured). It is validated on save; an invalid expression returns400 Bad Request. - receivers — one or more entries with optional
customerId, asiteIdslist, recipientemails, andlanguage. Without a customer, the receiver covers all customers; saving this requires global customer access andsiteIdsmust be empty. An empty list produces one PDF per template for the entire customer or all customers. Multiple site IDs produce one PDF per template and site; every site must belong to the selected customer. Duplicate attachment names receive a numeric suffix when needed. - language (per receiver) — the Language picker on each receiver row. Its PDFs and the delivery email are produced in that language, so one schedule can serve a German customer and a French one from the same templates. Same supported values as the generate call (
en,de,es,fr,it,nl); anything else returns400 Bad Requeston save. Receivers created before this field existed carry no value and fall back to English until you set one. - enabled — a disabled schedule is retained but does not run on its recurring schedule; the next run time is only computed while it is enabled. Manual Send now still queues a run using its saved settings. Changes to the UI pause/enable switch take effect only after Save.
- subject — optional custom subject line for the delivery email; leave it empty for the default.
Creating or updating stores the current user as the execution user. Every scheduled run re-evaluates that person's current permissions and customer, device, case, and time-entry scopes. If they lack reports.view, global customer access for an all-customers receiver, or access to an explicitly selected customer, the entire run fails closed. A template's device filter can only narrow that user scope. Creating and updating therefore require both reports.manage and reports.view; deleting and Run now require reports.manage, while listing and viewing require only reports.view.
Related articles
- Create a report template — end-to-end walkthrough.
Was this helpful?
Still need help? Ask the team