What the agent collects
The endpoint agent runs on employee laptops and reports just enough to keep the hardware register and software inventory honest: device identity, hardware specs, the list of installed apps, and a daily yes/no of which apps were used. This page is the exhaustive account of what leaves the machine, what never does, and why the line sits where it does — if a field is not listed here, the agent does not send it.
The agent is built to be defensible to the employee whose laptop it runs on. It ships a visible tray icon, links straight to a transparency page, and uninstalls cleanly. The data scope below is a deliberate floor, not an accident of what was easy to grab.
:::note Before you begin
Every employee can see this for themselves. Open My device in the portal (at
/my/agent) to view your device's status and the transparency summary. This page
explains the model; the agent overview covers what the agent
is and how it pairs.
:::
What gets sent, and when
The agent reports on three schedules. Each carries a fixed, named set of fields — there is no free-form payload and no catch-all "diagnostics" blob.
| Report | When | Carries |
|---|---|---|
| Enrollment | Once, at first install | Device identity + OS |
| Heartbeat | Every 6 hours, best effort | Identity again, plus hardware spec |
| Usage report | Daily, at 02:00 local time | Installed apps + a per-app daily used flag |
On enrollment
Sent once, the first time the agent pairs, so the server can recognise this machine on every later call. The identity is stable across re-installs, which is what stops a reinstalled laptop from orphaning its old record.
| Field | Example | What it is |
|---|---|---|
hardware_uuid | ABCD-1234-… | Stable device identity. IOPlatformUUID on macOS, MachineGuid on Windows. |
hostname | mac-asmith | The machine name, shown in the fleet view so a human can recognise the device. |
os | macos / windows | Selects the matching logic — bundle-id index on macOS, exe-name index on Windows. |
os_version | 14.6.1 | Patch-level and asset-age tracking. |
agent_version | 0.1.0 | Rollout tracking, so you can see which devices are behind. |
On each heartbeat
Every six hours the agent re-sends its identity and the hardware spec, probed once per boot and cached. The spec is what auto-fills CPU, RAM, and storage on the linked hardware record, so the register reflects the real machine rather than what someone typed at purchase time.
| Field | Example (macOS) | Example (Windows) |
|---|---|---|
manufacturer | Apple Inc. | LENOVO |
model | MacBookPro18,1 | 20XW004UUK |
serial | C02XYZ12345 | PF3A4B5C |
cpu | Apple M1 Pro | Intel Core i7-1260P |
cpu_cores | 10 | 12 |
ram_bytes | 17179869184 | 34359738368 |
disk_bytes | 994662584320 | 511109865472 |
:::note The serial is the join
serial is how the platform reconciles an agent-reporting device with a hardware
record you entered by hand. See Hardware overview for how
that matching works.
:::
On each daily usage report
Once a day, at 02:00 local time, the agent sends the installed-app inventory and a flag for which apps were touched that day. This is what powers license-utilization reporting: it answers "is this paid seat actually being used" without watching anyone work.
| Field | What it is | Example |
|---|---|---|
date | The calendar day being reported. | 2026-04-17 |
installed_apps[] | The full list of installed apps at report time, with name, identifier, and version. | [{name: "Slack", bundle_id: "com.tinyspeck.slackmacgap", version: "4.38.125"}] |
foreground[] | The apps the user interacted with that day. | [{id: "com.figma.Desktop", minutes: 1}] |
domains[] | Always empty in this version. The field exists in the schema for forward compatibility, but the agent does not scrape browser history. | [] |
:::warning minutes is a daily yes/no, not a stopwatch
In foreground[], the minutes value is always 0 or 1 — a binary "was this app
used today", never accumulated time. The agent polls the foreground app roughly once a
minute and records only whether each app appeared at all. There is no minute-level,
hour-level, or session-level time tracking, by design.
:::
What the agent never collects
The boundary below is intentional and absolute. None of the following is read, stored, or transmitted — there is no setting that turns any of it on.
| Category | Not collected |
|---|---|
| Input | Keystrokes, clipboard contents |
| Screen | Screenshots, screen recordings, window titles |
| Browsing | Browser history, bookmarks, any URLs |
| Files | File contents, file names |
| Sensors | Webcam, microphone |
| Location | GPS, Wi-Fi SSID, IP geolocation |
| Communications | Email, calendar, or messaging content |
| Network | Network connections, DNS queries |
| Timing | Per-app minute tracking — only a daily yes/no |
:::note The agent is network-agnostic It collects the same fields regardless of where the laptop is. It does not know or care whether the machine is on a VPN, the corporate network, or a home connection, and it reports nothing about the network itself. :::
How long the server keeps it
Once a report reaches the server, retention is bounded and enforced by scheduled jobs — nothing accumulates forever. The raw stream is short-lived; only the aggregate that feeds utilization trends is kept longer, and even that drops off after a year.
| Data | Retention | Then |
|---|---|---|
| Raw usage reports | 90 days | Purged by a daily job |
| Rolled-up daily app use | 365 days | Purged — kept this long for license-utilization trends |
| Hardware spec on the device record | Lifetime of the enrollment | Wiped when the device is revoked |
The split is deliberate: the raw per-day reports exist only long enough to be rolled up, while the year-long aggregate is what makes "this seat went unused for three months" a question you can answer.
What an employee can do
The agent is designed so the person it runs on stays in control. Three things are always available, with no admin involvement.
| Control | How | Result |
|---|---|---|
| See everything collected | Download a GDPR export from My → Profile (at /my/profile) | A downloadable copy of the data held about you, generated on the spot. See Your profile and data export. |
| Uninstall | Company Portal → OnTrackio Agent → Uninstall | The agent calls the revoke endpoint before removing itself; the server immediately stops accepting any further data from that keypair. |
| Pause | Not supported | Uninstall is the documented path in this version. |
:::tip Uninstalling stops collection at the source On uninstall the agent revokes its own credentials, so the cutoff is immediate and clean — the server won't accept a late report from a removed agent even if one were somehow sent. :::
Limitations and trade-offs
| Boundary | What it means |
|---|---|
| No pause switch | You can uninstall but not temporarily suspend collection. A pause control isn't in this version; uninstall and re-pair is the supported round trip. |
| Usage is coarse by design | Because foreground[] is a daily boolean, the platform can tell you an app was used on a day, never how long. That's a privacy choice, and it means utilization reporting is about active/idle seats, not productivity. |
| The agent only sees its own machine | It reports nothing about other devices, peripherals, or the network. Anything without the agent installed — monitors, docks, phones — exists in the register only because someone added it by hand. |