Repository navigation
Commands
The complete reportmateutil command surface, read from src/cli.rs and
src/main.rs. Every command except config makes one request to the
ReportMate API; the method and path are listed so you can reason about scopes.
When no credential is set and no app connection supplies one, the CLI may first
read GET /api/v1/auth/config to discover an Entra audience (see
Configuration).
A contract test fails the build when the API's OpenAPI document, as copied into
tests/openapi.json, has an operation the CLI has no command for (see
Development). Operations the API has that no command names yet —
GET/PUT /api/v1/inventory-state and GET/DELETE /api/v1/admin/orphans —
are reachable with raw, and their GET forms with module.
| Flag | Values | Default | Notes |
|---|---|---|---|
--output |
table, json
|
table |
Global; accepted anywhere on the line. Only devices, events and config have a table view — see Output Formats
|
--help, -h
|
Every command and subcommand | ||
--version, -V
|
Prints the build's calendar version |
There is no --api-url, --token, --profile, --verbose or --timeout
flag. The endpoint and credential are resolved automatically; see
Configuration.
| Command | Method and path |
|---|---|
config |
none — prints the resolved configuration |
devices |
GET /api/v1/devices |
device SERIAL |
GET /api/v1/device/{serial} |
device SERIAL info |
GET /api/v1/device/{serial}/info |
device SERIAL module NAME (or --module NAME) |
GET /api/v1/device/{serial}/modules/{name} |
device SERIAL events |
GET /api/v1/device/{serial}/events |
device SERIAL installs-log |
GET /api/v1/device/{serial}/installs/log |
device SERIAL log TOOL |
GET /api/v1/device/{serial}/logs/{tool} |
device SERIAL usage |
GET /api/v1/device/{serial}/applications/usage/history |
device SERIAL archive |
PATCH /api/v1/device/{serial}/archive |
device SERIAL unarchive |
PATCH /api/v1/device/{serial}/unarchive |
device SERIAL delete --confirm |
DELETE /api/v1/device/{serial}?confirm=true |
module NAME |
GET /api/v1/{name} |
apps list |
GET /api/v1/applications |
apps filters |
GET /api/v1/applications/filters |
apps usage |
GET /api/v1/applications/usage |
apps by-device APP |
GET /api/v1/applications/usage/by-device |
apps distribution NAMES |
GET /api/v1/applications/distribution |
apps collection-health |
GET /api/v1/applications/collection-health |
certificates |
GET /api/v1/security/certificates |
logs TOOL |
GET /api/v1/management/logs/{tool} |
events |
GET /api/v1/events |
events failures |
GET /api/v1/events/failures |
events payload ID |
GET /api/v1/events/{id}/payload |
events submit JSON |
POST /api/v1/events |
dashboard |
GET /api/v1/dashboard |
health |
GET /api/v1/health/live |
health --ready |
GET /api/v1/health/ready |
health --full |
GET /api/v1/health |
metrics |
GET /api/v1/metrics |
negotiate |
GET /api/v1/negotiate |
api-keys list |
GET /api/v1/admin/api-keys |
api-keys create NAME |
POST /api/v1/admin/api-keys |
api-keys revoke KEY_ID |
DELETE /api/v1/admin/api-keys/{key_id} |
admin usage-history date-anomalies |
GET /api/v1/admin/usage-history/date-anomalies |
admin usage-history integrity |
GET /api/v1/admin/usage-history/integrity |
admin usage-history export |
GET /api/v1/admin/usage-history/export |
admin usage-history reset-baseline |
POST /api/v1/admin/usage-history/reset-baseline |
admin usage-history cleanup |
DELETE /api/v1/admin/usage-history/cleanup |
admin installs clear-errors |
DELETE /api/v1/admin/installs/clear-errors |
admin installs reclassify |
POST /api/v1/admin/installs/reclassify |
admin debug-database |
GET /api/v1/debug/database |
settings get |
GET /api/v1/settings |
settings set JSON |
PUT /api/v1/settings |
settings discover |
GET /api/v1/settings/inventory/discover |
raw PATH |
any method, any path |
Scopes are enforced by the API, not the CLI. See Authentication.
Flags that are not given are not sent, so the API's own defaults apply. The ranges quoted below are the API's; the CLI does not validate them locally, so an out-of-range value comes back from the server as a 422.
Prints the endpoint and credential the CLI would use and where each came from,
without any secret material. It runs the same resolution as every other command
(including any az, aws or /api/v1/auth/config lookups) but never fails
for a missing value, so it is the first thing to run when a command reports
no API endpoint or no credential.
reportmateutil config
With --output json it prints apiUrl, apiUrlSource, credential,
credentialSource, audienceSource, internalSecret (a boolean) and notes.
reportmateutil config --output json
Lists the fleet. Table by default.
| Flag | Sent as | Notes |
|---|---|---|
--limit N |
limit |
1–1000 |
--offset N |
offset |
|
--include-archived |
includeArchived=true |
reportmateutil devices --limit 100 --offset 100
Shows one device by serial number, or runs a per-device subcommand. Always prints JSON.
| Argument / flag | Notes |
|---|---|
SERIAL |
Positional, required |
--module NAME |
Shorthand for the module NAME subcommand. Cannot be combined with a subcommand |
reportmateutil device SERIAL123
reportmateutil device SERIAL123 --module installs
Subcommands:
| Subcommand | Flags | Notes |
|---|---|---|
info |
Fast summary (identity, platform, last seen) without module payloads | |
module NAME |
One module document. The name is passed through unchecked | |
events |
--limit N, --type T
|
--type is one of success, warning, error, info, system
|
installs-log |
Managed-software (Munki or Cimian) install log | |
log TOOL |
One log root with its tails. TOOL is the root key the device reports: installs, bootstrap, reports, state, encryption, users, utilities, notifications, mdm or installer
|
|
usage |
--days N (1–548), --app NAME (sent as appName) |
Application usage history for this device |
archive |
Admin scope | |
unarchive |
Admin scope | |
delete |
--confirm |
Admin scope. Refused locally without --confirm
|
reportmateutil device SERIAL123 events --limit 20 --type error
reportmateutil device SERIAL123 log installs
reportmateutil device SERIAL123 usage --days 90 --app Photoshop
reportmateutil device SERIAL123 delete --confirm
Without --confirm, delete fails before any request with
refusing to delete SERIAL123 without --confirm. With it, confirm=true is
also sent to the API. There is no interactive prompt.
The top-level forms archive SERIAL, unarchive SERIAL and
delete SERIAL --confirm are hidden aliases for these subcommands.
Fleet-wide report for a module. Always prints JSON.
| Argument / flag | Sent as | Notes |
|---|---|---|
NAME |
path | Path under /api/v1/; leading and trailing slashes are trimmed |
--include-archived |
includeArchived=true |
|
--limit N |
limit |
1–5000 |
--offset N |
offset |
|
--param KEY=VALUE |
KEY=VALUE |
Repeatable; for any other query parameter |
Modules include hardware, applications, installs, network, security,
management, inventory, system, peripherals, identity and profiles,
plus nested variants such as installs/full. The name is a path fragment, not
an enum, so any /api/v1/<name> GET route works.
reportmateutil module hardware --limit 100
reportmateutil module installs/full --param platform=windows
A --param without = fails before any request with
--param must be key=value, got: .... Only the first = splits.
Application inventory, usage and distribution. applications is a visible
alias for apps. Every subcommand prints JSON.
Several subcommands share a set of inventory-facet filters. Each takes a comma-separated list and is sent under the same name:
| Flag | Notes |
|---|---|
--usages |
Inventory usages |
--catalogs |
Inventory catalogs |
--locations |
Inventory locations |
--areas |
Inventory areas (departments) |
--fleets |
Inventory fleets |
--rooms |
Inventory rooms |
--platforms |
windows, macos
|
Installed applications across the fleet.
| Flag | Sent as | Notes |
|---|---|---|
--devices |
deviceNames |
Comma-separated device names |
--names |
applicationNames |
Comma-separated application names |
--publishers |
publishers |
Comma-separated |
--categories |
categories |
Comma-separated |
--versions |
versions |
Comma-separated |
--search |
search |
Free text |
--installed-from |
installDateFrom |
Date |
--installed-to |
installDateTo |
Date |
--size-min |
sizeMin |
Bytes |
--size-max |
sizeMax |
Bytes |
| inventory filters | as above | |
--load-all |
loadAll=true |
Every item instead of one page |
--include-archived |
includeArchived=true |
|
--limit N |
limit |
1–5000, API default 500 |
--offset N |
offset |
|
--device-limit N |
deviceLimit |
Devices to scan, 1–5000, API default 2000 |
reportmateutil apps list --names "Zoom,Slack" --platforms macos --limit 200
Available filter values (publishers, categories, inventory facets). Takes
--include-archived.
reportmateutil apps filters
Fleet-wide application usage over a window.
| Flag | Sent as | Notes |
|---|---|---|
--days N |
days |
1–548, API default 30 |
--names |
applicationNames |
Comma-separated |
--min-hours X |
minHours |
Decimal |
--min-launches N |
minLaunches |
|
| inventory filters | as above | |
--include-archived |
includeArchived=true |
reportmateutil apps usage --days 30 --min-hours 1
Per-device usage of one application; the name is a substring match.
| Argument / flag | Sent as | Notes |
|---|---|---|
APP |
app |
Positional, required |
--days N |
days |
1–548, API default 30 |
--usages, --catalogs, --locations
|
same names | Comma-separated; the other facet filters are not offered here |
--include-archived |
includeArchived=true |
reportmateutil apps by-device Photoshop --days 90
Where the named applications are installed, aggregated by inventory facet.
| Argument / flag | Sent as | Notes |
|---|---|---|
NAMES |
applicationNames |
Positional, comma-separated, required |
| inventory filters | as above | |
--include-archived |
includeArchived=true |
reportmateutil apps distribution "Zoom,Slack" --areas Design
Freshness of application data collection across the fleet.
| Flag | Sent as | Notes |
|---|---|---|
--fresh-days N |
freshDays |
1–90, API default 7 |
--stale-days N |
staleDays |
1–180, API default 30 |
--include-archived |
includeArchived=true |
reportmateutil apps collection-health --fresh-days 7 --stale-days 30
Searches certificates across the fleet. certs is a visible alias. Prints
JSON.
| Flag | Default | Notes |
|---|---|---|
--search TEXT |
empty | Matches common name, issuer, subject or serial number |
--status S |
all |
all, valid, expired, expiring
|
--limit N |
||
--include-archived |
search and status are always sent, with their defaults when not given.
reportmateutil certificates --search "Contoso Root" --status expiring
Sweeps one tool's log tails across every device that reports it. Prints JSON.
| Argument / flag | Sent as | Notes |
|---|---|---|
TOOL |
path | Log root key as the management module reports it: installs, bootstrap, reports, state, encryption, users, utilities, notifications, mdm or installer
|
--levels |
levels |
Comma-separated error, warning, info, debug; API default error,warning
|
--platform |
platform |
windows or macos
|
--file |
file |
Only lines from this file within the root, for example run.log
|
--grep |
q |
Case-insensitive substring the line must contain |
--summary |
summary=true |
Also return fleet-wide message patterns |
--max-lines-per-device N |
maxLinesPerDevice |
1–5000, API default 200 |
--include-archived |
includeArchived=true |
|
--limit N |
limit |
Devices, 1–5000 |
--offset N |
offset |
Devices to skip |
reportmateutil logs installs --levels error --grep "timed out" --summary
Recent fleet events. Table by default.
| Flag | Sent as | Notes |
|---|---|---|
--limit N |
limit |
1–1000 |
--offset N |
offset |
|
--since DATE |
startDate |
ISO 8601 |
--until DATE |
endDate |
ISO 8601 |
--type T |
type |
success, warning, error, info, system
|
reportmateutil events --limit 20 --type error --since 2026-09-01
The table has Time, Serial, Kind and Message columns; see Output Formats.
Check-ins the API turned away. Prints JSON.
| Flag | Sent as | Notes |
|---|---|---|
--limit N |
limit |
1–1000 |
--offset N |
offset |
|
--serial S |
serial |
Case-insensitive substring |
--reason R |
reason |
Rejection reason code |
--hours N |
hours |
1–2160, API default 168 |
--outcome O |
outcome |
rejected (API default), retried, accepted, all
|
reportmateutil events failures --hours 24
Full payload for one event, including the related module data.
reportmateutil events payload 11184392
Submits a device check-in payload the way the device agents do. The argument is
inline JSON or @path to a file; it is parsed locally first, so malformed JSON
fails before the request. A POST, so it needs the ingest scope.
reportmateutil events submit @checkin.json
Dashboard rollup: fleet counts, recent events, module summaries. Prints JSON.
| Flag | Sent as | Notes |
|---|---|---|
--events-limit N |
eventsLimit |
1–500 |
--include-archived |
includeArchived=true |
reportmateutil dashboard --events-limit 50
API health. Prints JSON. --ready and --full cannot be combined.
| Flag | Endpoint |
|---|---|
| none | /api/v1/health/live |
--ready |
/api/v1/health/ready — includes the database probe |
--full |
/api/v1/health — the complete report |
reportmateutil health --ready
The CLI resolves a credential before any request, including health, so a
machine with no credential at all cannot run it. Use config to see what was
resolved.
Prometheus metrics exposition. The text body is printed verbatim.
reportmateutil metrics
Real-time (SignalR / Web PubSub) negotiate: returns a connection URL and token.
| Flag | Default | Sent as |
|---|---|---|
--device ID |
dashboard |
device |
reportmateutil negotiate
Manages per-client API keys. All three need the admin scope and print JSON.
reportmateutil api-keys list
create NAME posts {"client_id": NAME, "scopes": [...]}. --scope is
repeatable, takes read, ingest or admin, and defaults to read. The
response holds the full key, which the API shows exactly once.
reportmateutil api-keys create ci-reader --scope read
reportmateutil api-keys create fleet-ops --scope read --scope admin
revoke KEY_ID takes the server-generated key id — the id field from
create or list, not the client name and not the full key.
reportmateutil api-keys revoke 0123456789ab
Maintenance and diagnostics. Everything here prints JSON except
usage-history export, which prints CSV. usage-history and installs need
the admin scope; debug-database (GET /api/v1/debug/database, outside
/admin) needs only read.
| Subcommand | Flags |
|---|---|
date-anomalies |
--floor YYYY-MM-DD (rows dated before it are implausible; API default 548 days ago), --limit N (sample rows per bucket, 1–1000) |
integrity |
--days N (1–90, API default 7), --sample N (offending device-days returned, 1–200, API default 20) |
export |
--from YYYY-MM-DD (inclusive, required), --to YYYY-MM-DD (exclusive, required), --out PATH / -o PATH
|
reset-baseline |
--before YYYY-MM-DD (required), --confirm, --reason TEXT
|
cleanup |
--months N (default 18, 1–36) |
date-anomalies lists rows whose date could not have come from a healthy
client; integrity is a physical-plausibility check over recent rows per
platform.
reportmateutil admin usage-history date-anomalies
reportmateutil admin usage-history integrity --days 7
export streams CSV to stdout, or writes it to --out and reports
wrote N rows to PATH on stderr.
reportmateutil admin usage-history export --from 2026-08-01 --to 2026-09-01 --out august.csv
reset-baseline archives and removes rows dated before --before. Without
--confirm the API returns a preview and changes nothing. --reason is
recorded on the archived rows so the batch can be identified later. The API
also takes a repeatable device parameter that limits the reset to given
serial numbers; the CLI has no flag for it, so send it with raw.
reportmateutil admin usage-history reset-baseline --before 2026-01-01 --reason "term reset" --confirm
cleanup deletes rows older than the retention window. It runs immediately.
reportmateutil admin usage-history cleanup --months 18
| Subcommand | Flags |
|---|---|
clear-errors |
--days N (default 10, 0–365; 0 clears every device), --item-age-days X (sent as item_age_days) |
reclassify |
--batch N (rows per batch, 1–1000, API default 200), --limit N (stop after this many rows) |
clear-errors clears stale install errors and warnings for devices not seen in
--days days, and with --item-age-days also clears individual items whose own
last attempt is older than that. It runs immediately.
reportmateutil admin installs clear-errors --days 10 --item-age-days 30
reclassify re-runs the install-item classifier over stored installs rows;
--limit rehearses it against part of the fleet.
reportmateutil admin installs reclassify --limit 500
Database diagnostics: duplicates, orphans, retention, bloat.
reportmateutil admin debug-database
admin cleanup-usage --months N and admin clear-errors --days N are hidden
aliases for admin usage-history cleanup and
admin installs clear-errors.
Reads and writes the server-side org settings document.
settings get needs only a read credential.
reportmateutil settings get
settings set JSON is a replace, not a merge — what you send becomes the whole
document. The argument is inline JSON or @path, parsed locally first.
--updated-by NAME is sent as the X-Updated-By header and recorded on the
settings revision. The API restricts this call to internal-service callers, so
it needs REPORTMATE_INTERNAL_SECRET.
reportmateutil settings set @settings.json --updated-by admin
settings discover lists the inventory keys present in the fleet. It also needs
REPORTMATE_INTERNAL_SECRET, and takes --include-archived (sent as
include_archived=true).
reportmateutil settings discover
The escape hatch: any path, any method, an optional JSON body.
| Argument / flag | Default | Notes |
|---|---|---|
PATH |
Must start with /; appended to the API URL as given |
|
--method M / -X M
|
get |
get, post, put, patch, delete
|
--data JSON / -d JSON
|
Inline JSON or @path, parsed locally first |
|
--param KEY=VALUE |
Repeatable; URL-encoded and appended as a query string |
reportmateutil raw /api/v1/dashboard --param eventsLimit=10
reportmateutil raw /api/v1/admin/installs/reclassify -X post
reportmateutil raw /api/v1/settings -X put -d @settings.json
A JSON response is pretty-printed; a text response is printed verbatim. A path
not starting with / fails locally with
path must start with /, e.g. /api/v1/dashboard. Prefer --param over writing
? and & into the path yourself: the path is not encoded, and an unquoted &
is taken by the shell.
AGPL-3.0-or-later — reportmate.app