Reportsv7.0.20
Generate on-demand reports — flow and protocol activity, fleet availability and capacity, per-tracker time series, single-device dossiers — plus the picker catalogs that populate report forms and the per-user cache of saved results.
Reports are on-demand queries. Each report endpoint runs a database aggregation over a time range — and usually over a chosen device, interface, or tracker — and returns a set of rows ready for charting. There is no report scheduler: a report is generated when you call its endpoint, and nothing runs it again on your behalf.
Most reports also save a copy of their result. Unless you pass nostore, the generated report is persisted as a saved report owned by the calling user and assigned an id; the Saved reports endpoints at the end of this page let you list, fetch, update the metadata of, and delete those saved copies. Saved reports are per-user: you only ever see your own, and sa bypasses that restriction.
Two further groups round out the page. The availability report (Up/Down) and the tracker reports (performance, interface, latency, disk, TCP, URL) each summarize one monitored object over a window. The bulk listing endpoints (getAllTrackers, getAllInterfaces, getAllDisks, getAllTCPs, getAllLatencys, plus the netflow/protocol interface lists) return catalogs used to populate the pickers on a report form — they take no time range and return everything you are allowed to see.
These endpoints belong to the reports functional area; an MCP or OAuth token needs the mcp:reports scope, and the calling user needs the reports Laravel permission shown on each block. (getAllLatencys is the one exception — it is gated by the devices permission, noted on its block.)
Tag-scoping applies throughout. Every report and every catalog filters its rows to the devices inside the calling user’s tags: a tag-restricted user sees only their own devices’ interfaces, disks, latencies, flows, and so on. A user with no tag restriction sees everything, and sa bypasses scoping entirely. Where a report targets a single device or tracker you are not allowed to see, the request fails (the device lookup throws), and the endpoint returns its standard error envelope.
Error envelope. With the exception of updateReport, every endpoint on this page returns HTTP 200 even on failure and signals the outcome in the body. A successful generation returns {"status":201,"hasError":false,"report":{…}}; a failure returns {"status":false,"hasError":true,"message":"…"}. The numeric status inside the body is the real signal, not the HTTP code. Each endpoint block below shows the success envelope; assume the failure envelope above applies unless stated otherwise.
Shared request fields. The report-generation endpoints (Network, Availability, Tracker, Device, and Port reports) read these fields directly from the request body or query string — there is no formal validator:
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | no | Label stored on the saved report. Defaults to "Untitled". |
start | datetime | yes | Window start. Parsed loosely (any value strtotime/Carbon accepts). |
end | datetime | yes | Window end. |
nostore | any | no | If present (any value), the result is returned but not saved as a report — so no id is assigned. Omit it to persist the report. |
Each report also fixes its own report type string (e.g. "Network Activity", "Latency") and adds the report-specific selector fields documented per endpoint.
Network reports
These reports aggregate flow and protocol data. They are read with GET (parameters in the query string). All three share the Shared request fields above and add the selectors shown.
Network activity report
GET/api/networkActivityreports
Aggregates NetFlow/sFlow conversations over the window into top talkers (grouped by source/destination IP, exporter, interface, VLAN, port, and protocol), enriching each row with the best-known hostname and service name. Use it for a “who is talking to whom” view.
Query parameters (in addition to the shared fields)
| Name | Type | Notes |
|---|---|---|
device | string | A device id, a device IP address, or -1 for all devices (default). A tag-restricted caller may only name a device/IP inside their tags; an out-of-scope value is rejected. |
iface | integer | Restrict to one ingress interface index. Default -1 (all). |
vlan | integer | Restrict to one VLAN. Default -1 (all). |
port | integer | Keep only conversations whose lowest port equals this value. |
filter | string | Substring matched against source or destination IP. |
order | string | Sort column for the top-N (default sum, total bytes). |
limit | integer | Max rows returned (default 10000). |
Response 200
{
"status": 201,
"hasError": false,
"report": {
"report": "Network Activity",
"title": "Untitled",
"device": "10.0.0.1",
"iface": -1, "vlan": -1,
"start": "2026-06-14T00:00:00.000000Z",
"end": "2026-06-15T00:00:00.000000Z",
"data": [
{
"src_ip": "10.0.0.5", "dst_ip": "10.0.0.1",
"src_host": "ws-05", "dst_host": "core-rtr",
"flow_src": "10.0.0.1", "in_iface": 2, "vlan": null,
"lowest_port": 443, "port_name": "https",
"protocol": 6, "sum": 184320192, "end_time": "2026-06-15T00:00:00Z"
}
],
"id": 412
}
}
Example
curl -sS "https://APPLIANCE/api/networkActivity?device=-1&start=2026-06-14T00:00:00Z&end=2026-06-15T00:00:00Z&limit=50" \
-H "Authorization: Bearer $TOKEN"
Network protocol report
GET/api/networkProtocolreports
Returns a per-protocol/port byte time series suitable for a stacked-area chart. The top ports (by total bytes) are aligned onto a single shared timeline.
Query parameters (in addition to the shared fields)
| Name | Type | Notes |
|---|---|---|
device | integer | Device id, or -1 for all (default). Out-of-scope ids return the error envelope. |
iface | integer | Restrict to one interface. This is the SNMP/kernel ifIndex stored on the flow rows, not the interfaces.id surrogate key — resolve labels for it through the by_ifindex map in the helpers bundle. Default -1. |
vlan | integer | Restrict to one VLAN. Default -1. |
limit | integer | Keep only the top-N ports by total bytes (default 10). |
Response 200
report.data is a two-element array: [timestamps, ports]. timestamps is the shared, sorted timeline; ports is an object keyed by protocol_port, each entry carrying a bytes array and a packets array — both aligned to timestamps — plus total (bytes) and totalPackets.
A packets element, and totalPackets itself, is null where no packet count was recorded. Treat null as not measured rather than zero: that is what an entry looks like for data collected before packet counting existed, and reading it as zero implies an infinite average packet size.
Protocols with no port concept (GRE, ESP, AH, OSPF, VRRP, SCTP, IP-in-IP, ICMPv6, PIM) are keyed on port 0 and take the protocol name as their label; their name is null.
{
"status": 201, "hasError": false,
"report": {
"report": "Network Protocol", "title": "Untitled",
"device": -1, "iface": -1, "vlan": -1,
"start": "2026-06-14T00:00:00.000000Z", "end": "2026-06-15T00:00:00.000000Z",
"limit": 10,
"data": [
[1749859200, 1749862800],
{
"6_443": { "port": 443, "label": "https", "name": "https",
"protocol": 6, "timestamps": [1749859200, 1749862800],
"bytes": [10485760, 8388608], "packets": [8192, 6553],
"total": 18874368, "totalPackets": 14745 },
"47_0": { "port": 0, "label": "GRE", "name": null,
"protocol": 47, "timestamps": [1749859200, 1749862800],
"bytes": [524288, 491520], "packets": [512, 480],
"total": 1015808, "totalPackets": 992 }
}
],
"id": 413
}
}
Network traffic report
GET/api/networkTrafficreports
Builds a conversation report centered on a single subject — a monitored device or any IP address — listing the conversations that subject participated in, a per-partner timeline, and a protocol/service distribution summary.
Query parameters (in addition to the shared fields)
| Name | Type | Notes |
|---|---|---|
device | string | Required. A device id, or an arbitrary IP address to report on. A tag-restricted caller only sees conversations between the subject and one of their own devices. |
limit | integer | Max conversations (default 100, capped at 1000). |
Response 200
report.data carries conversations[], a time_series object, and a summary (totals plus a protocol_distribution). report.devices echoes the resolved subject.
{
"status": 201, "hasError": false,
"report": {
"report": "Network Traffic", "title": "Untitled",
"devices": [{ "id": 42, "label": "core-rtr", "ip_address": "10.0.0.1" }],
"data": {
"conversations": [
{ "src_ip": "10.0.0.1", "dst_ip": "8.8.8.8",
"protocol": 17, "protocol_name": "UDP",
"total_bytes": 20480, "flow_count": 1,
"first_seen": "2026-06-14T01:00:00Z", "last_seen": "2026-06-14T01:05:00Z",
"duration_seconds": 300, "dst_ports": [53], "primary_service": "domain" }
],
"time_series": { "hosts": ["8.8.8.8"], "conversationSegments": [], "totalConversations": 0 },
"summary": { "total_conversations": 1, "total_bytes": 20480, "total_flows": 1,
"protocol_distribution": { "UDP": { "total_bytes": 20480, "total_conversations": 1, "services": {} } },
"time_range": { "start": "…", "end": "…" } }
},
"id": 414
}
}
Sniffer sources
GET/api/getAllSourcesreports
Lists the distinct flow exporter addresses (flow_src) seen in NetFlow data, scoped to your tags. Use it to populate an exporter picker on a flow report form.
Response 200
{ "status": 201, "hasError": false, "sources": { "data": [ { "flow_src": "10.0.0.1" } ] } }
NetFlow interfaces
GET/api/getNetflowInterfacesreports
Lists the device/interface pairs that have appeared as NetFlow ingress points, including the local sniffing host. Used to populate the interface picker on flow reports.
Response 200
{
"status": 200, "hasError": false,
"data": [
{ "label": "core-rtr", "name": "GigabitEthernet0/1", "flow_src": "10.0.0.1", "in_iface": 2 },
{ "label": "Netmon", "name": "eth0", "flow_src": "127.0.0.1", "in_iface": 1 }
]
}
Protocol-breakdown interfaces
GET/api/getProtocolInterfacesreports
Returns the device → interface → VLAN tree available for the Network Protocol report, derived from flow data plus the locally sniffed protocol breakdown. The appliance’s own local host — the device row whose address is 127.0.0.1 — is included only when you are allowed to see it; its device id is not fixed, so match on the address rather than on an id.
Unlike its sibling listings, the payload is returned under the message key, keyed by device id.
Response 200
{
"status": 200, "hasError": false,
"message": {
"42": { "id": 42, "ip_address": "10.0.0.1",
"interfaces": { "2": { "id": 2, "vlans": [10, 20] } } },
"1": { "id": 1, "ip_address": "127.0.0.1",
"interfaces": { "1": { "id": 1, "vlans": [] } } }
}
}
Availability and fleet summaries
These reports summarize the whole fleet over the window rather than a single object. They take only the Shared request fields (title, start, end, nostore) — there is no selector; each returns every device, disk, or interface you are allowed to see.
Up/Down report
GET/api/upDownreports
Summarizes ICMP reachability over the window for every device you can see: min/max/average latency and a downtime percentage per device. Use it for an availability scorecard.
Response 200
{
"status": 201, "hasError": false,
"report": {
"report": "Up/Down", "title": "Untitled",
"start": "2026-06-14T00:00:00.000000Z", "end": "2026-06-15T00:00:00.000000Z",
"data": [
{ "id": 42, "label": "core-rtr", "interval": 60,
"ip_address": "10.0.0.1", "profile": "cisco-ios",
"summary": { "minLatency": 1, "maxLatency": 9, "avgLatency": 3, "downtime": 0 } }
],
"id": 415
}
}
All-disks report
GET/api/allDisksreports
Returns one row per monitored disk across every device you can see (report type "All Disks"), each with min/avg available space, max total, the start/end available values over the window, and the underlying sample series. Use it for a fleet-wide capacity overview.
Response 200
Each data row identifies the parent device and disk plus its aggregates and log series:
{
"status": 201, "hasError": false,
"report": {
"report": "All Disks", "title": "Untitled",
"start": "…", "end": "…",
"data": [
{ "device_id": 42, "label": "core-rtr", "ip_address": "10.0.0.1", "profile": "cisco-ios",
"disk_id": 7, "name": "/", "minAvailable": 10485760, "maxTotal": 53687091200,
"avgAvailable": 12582912, "startAvailable": 13631488, "endAvailable": 10485760,
"log": [ { "available": 13631488, "timestamp": 1749859200 } ] }
],
"id": 418
}
}
All-interfaces report
GET/api/allInterfacesreports
Returns one row per logging-enabled interface across every device you can see (report type "All Interfaces"), each with min/avg/max inbound and outbound throughput, the link speed, and the underlying sample series. Use it for a fleet-wide throughput overview.
Response 200
{
"status": 201, "hasError": false,
"report": {
"report": "All Interfaces", "title": "Untitled",
"start": "…", "end": "…",
"data": [
{ "device_id": 42, "label": "core-rtr", "ip_address": "10.0.0.1", "profile": "cisco-ios",
"interface_id": 5, "description": "uplink", "name": "Gi0/5",
"minInbound": 1000, "avgInbound": 50000, "maxInbound": 900000,
"minOutbound": 800, "avgOutbound": 40000, "maxOutbound": 850000,
"speed": 1000000000,
"log": [ { "inbound": 50000, "outbound": 40000, "timestamp": 1749859200 } ] }
],
"id": 419
}
}
Tracker reports
Each tracker report charts one or more monitored objects (an SNMP OID, an interface, a ping target, a disk, a TCP service, or a URL) over the window. They all share the Shared request fields and add a selector identifying the object(s). All return the standard {status, hasError, report} envelope with a data array of time-stamped samples, so only the selector and the data row shape are called out below.
The performance, interface, and disk selectors accept either a single id (?oid=12) or a repeated array (?oids[]=12&oids[]=13); naming none returns the error envelope ("No Oid Specified", etc.).
Performance (OID) tracker report
GET/api/performanceTrackerreports
Charts the logged values of one or more SNMP OID trackers (report type "Performance Tracker").
Selector: oid or oids[] — one or more oids.id values.
Each data row: { oid_id, label, oid, interval, message, timestamp }.
Example
curl -sS "https://APPLIANCE/api/performanceTracker?oids[]=12&oids[]=13&start=2026-06-14T00:00:00Z&end=2026-06-15T00:00:00Z" \
-H "Authorization: Bearer $TOKEN"
Interface tracker report
GET/api/interfaceTrackerreports
Charts inbound/outbound throughput for one or more interfaces (report type "Interface").
Selector: interface or interfaces[] — one or more interfaces.id values.
Each data row: { interface_id, description, name, inbound, outbound, speed, status, timestamp }.
Latency tracker report
GET/api/latencyTrackerreports
Charts ICMP latency and loss for a single device’s ping tracker (report type "Latency").
Selector: device — a devices.id you can see (an out-of-scope device returns the error envelope).
Each data row: { label, latency, loss, timestamp }.
Disk tracker report
GET/api/diskTrackerreports
Charts available/total disk space for one or more monitored disks (report type "Disk").
Selector: disk or disks[] — one or more disk_servers.id values.
Each data row: { disk_id, name, available, total, timestamp }.
TCP service tracker report
GET/api/tcpTrackerreports
Charts TCP connect latency for a single monitored TCP service (report type "TCP Service").
Selector: port — a ports.id value. Latency is in microseconds with -1 meaning the probe failed.
Each data row: { label, latency, timestamp }.
URL tracker report
GET/api/urlTrackerreports
Charts response latency, HTTP status, and the result message for a single monitored URL (report type "URL"). The URL monitors themselves are managed under URL Monitoring.
Selector: url — a urls.id value.
Each data row: { url, latency, message, status, timestamp }.
Device and port reports
Device report
GET/api/deviceReportreports
Assembles a single-device summary: identity, profile, current up/down status, and any of the optional sections you opt into (latency, disks, interfaces, and a log-event roll-up). Use it as the per-device dossier behind a device report page.
Query parameters (in addition to the shared fields)
| Name | Type | Notes |
|---|---|---|
device | integer | Required. devices.id to report on (must be in your scope). |
latency | boolean | Include the device’s ping log series. |
disks | boolean | Include disk series. |
interfaces | boolean | Include interface series. |
events | boolean | Include a bucketed syslog / event-log / IDS roll-up over the window. |
Response 200
report.device is an object (not an array): identity fields, profile, status ("Active"/"Offline"/null), the device’s oids/walks, and whichever optional sections were requested.
{
"status": 201, "hasError": false,
"report": {
"report": "Device", "title": "Untitled",
"start": "…", "end": "…",
"device": {
"id": 42, "label": "core-rtr", "ip_address": "10.0.0.1",
"status": "Active", "profile": { "profile": "cisco-ios", "label": "Cisco IOS", "oids": [], "walks": [], "tables": [] },
"enable_agent": false, "enable_netflow": true, "enable_snmp": true,
"tags": [], "oids": [], "walks": [],
"events": { "bucket": "hour", "syslog": { "total": 0 }, "eventlog": {}, "eve": {} }
},
"id": 416
}
}
Port (connectivity) report
GET/api/portReportreports
Returns a device’s switch-port connectivity map: for each interface, the neighboring device/IP/MAC discovered on the other end (report type "Port"). Unlike the other reports it takes no time range — it is a point-in-time topology snapshot.
Query parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Required. devices.id (must be in your scope). |
title | string | Optional saved-report label. |
nostore | any | Present → don’t save. |
Response 200
report.interfaces lists each interface with its discovered connected[] neighbors.
{
"status": 201, "hasError": false,
"report": {
"report": "Port", "title": "Untitled", "devicelabel": "core-sw",
"interfaces": [
{ "id": 5, "device_id": 42, "interface": 5, "name": "Gi0/5",
"description": "uplink", "mac": "00:11:22:33:44:55", "status": "up",
"connected": [ { "dev_id": 51, "ip": "10.0.0.9", "label": "ws-09", "mac": "aa:bb:cc:dd:ee:ff", "iface": null } ] }
],
"id": 417
}
}
Bulk listings (report pickers)
These catalogs back the selector dropdowns on the report forms. They take no parameters and no time range, and each returns everything the caller is allowed to see (tag-scoped). The getAll* family share one envelope: {"status":201,"hasError":false,"message":{"data":[…]}}.
List OID (performance) trackers
GET/api/getAllTrackersreports
Every SNMP OID tracker you can see. Each row: { dev_id, dev_label, id, label, oid }.
Response 200
{ "status": 201, "hasError": false,
"message": { "data": [ { "dev_id": 42, "dev_label": "core-rtr", "id": 12, "label": "CPU", "oid": "1.3.6.1…" } ] } }
List disk trackers
GET/api/getAllDisksreports
Every monitored disk you can see. Each row: { dev_id, dev_label, id, name }.
List TCP service trackers
GET/api/getAllTCPsreports
Every TCP service with latency logging enabled that you can see. Each row: { dev_id, dev_label, id, label }.
List interfaces
GET/api/getAllInterfacesreports
Every logging-enabled interface you can see. Each row: { dev_id, dev_label, id, description, name, interface }.
List latency (ping) trackers
GET/api/getAllLatencysdevices
Every ICMP ping tracker you can see. Each row: { dev_id, dev_label, id, label, interval, timeout, lossout }.
Unlike the other bulk listings, this endpoint is gated by the devices permission, not reports.
Report helpers bundle
GET/api/getAllHelpersreports
A single call that bundles everything a report form needs to bootstrap: protocol-breakdown sources, monitored URLs, logging-enabled interfaces grouped by device, and a mindate map giving the earliest queryable timestamp per report type (derived from each table’s retention setting).
Each device entry under interfaces carries the same rows indexed two ways, because two different id spaces address them. interfaces is keyed by interfaces.id, the surrogate primary key — that is what the Interface report expects back in its interfaces[] parameter. by_ifindex is keyed by the SNMP/kernel ifIndex — that is what the flow tables store, so it is the index to use when labelling an iface value from the Network Activity or Network Protocol selectors.
Response 200
{
"status": 201, "hasError": false,
"helpers": {
"pbsources": { "42": { "id": 42, "ip_address": "10.0.0.1", "interfaces": {} } },
"urls": [ { "id": 1, "url": "https://example.com" } ],
"interfaces": { "42": { "id": 42, "label": "core-rtr", "ip_address": "10.0.0.1",
"interfaces": { "5": { "id": 5, "interface": 12, "name": "Gi0/5",
"description": "uplink", "speed": 1000000000 } },
"by_ifindex": { "12": { "id": 5, "interface": 12, "name": "Gi0/5",
"description": "uplink", "speed": 1000000000 } } } },
"mindate": { "networkActivity": 1746662400, "networkProtocol": 1746662400, "iface": 1746662400,
"disk": 1746662400, "latency": 1746662400, "performance": 1746662400, "url": 1746662400 }
}
}
Saved reports
Every report generated without nostore is persisted as a saved report owned by the caller. These endpoints manage that cache. Saved reports are per-user — you only ever see and act on your own rows (sa bypasses), and a request for an id that isn’t yours returns the same “not found” answer as one that doesn’t exist, so the endpoint can’t be used to probe for other users’ reports.
List saved reports (cache)
GET/api/getReportCachereports
Returns your saved reports grouped by report type, with the heavy data payload stripped out (set to null) so the listing stays light. Fetch a full report body with getReport.
Response 200
{
"status": 201, "hasError": false,
"reports": [
{ "type": "Network Activity", "data": [ { "report": "Network Activity", "title": "Q2 talkers", "id": 412, "data": null } ] },
{ "type": "Up/Down", "data": [] }
]
}
Fetch one saved report
POST/api/getReportreports
Returns the full saved report body (including its data) for one of your reports, matched by id and type.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | yes | Saved report id. |
type | string | yes | Report type string (e.g. "Latency"), must match the stored value. |
Response 200
{ "status": 200, "hasError": false, "report": { "report": "Latency", "title": "core-rtr ping", "id": 418, "data": [] } }
On a missing id/type, or an id that isn’t yours: {"status":404,"hasError":true,"message":"Report not found"} (still HTTP 200).
Update a saved report’s metadata
POST/api/updateReportreports
Updates the metadata of one of your saved reports (for example renaming it). The data and id keys of the supplied report are ignored — the stored result set is never overwritten.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | yes | Saved report id (must be yours). |
report | object | yes | Report object whose non-data/non-id keys are merged onto the stored report. |
This endpoint, alone on this page, uses real HTTP codes: 201 on success, 400 for a missing id/report, 404 when the report isn’t found (or isn’t yours), 500 on error.
Response 201
{ "hasError": false, "message": "Report updated" }
Delete a saved report
POST/api/deleteReportreports
Permanently deletes one of your saved reports.
This permanently removes the saved report. It only affects your own reports; you cannot delete another user’s report (the lookup is scoped to you).
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer (numeric) | yes | Saved report id to delete. |
Response 200
{ "status": 200, "hasError": false, "message": "Report deleted" }
A missing/non-numeric id or an id that isn’t yours returns {"status":false,"hasError":true,"message":"…"} (HTTP 200).