Oxelone Docs

Search docs and API

Find a guide, a section of one, or an API operation by its name.

Open console (opens in a new tab)

API reference Resources

Machines

Enrolled machines: their state, activity and coverage.

21 operations

List machines

GET/machines

The workspace's fleet, filtered and paged. Archived and deleted machines are left out unless lifecycle asks for archived ones. f, q, cursor and limit work the same way as on the AI artifacts list.

Query parameters

fstring · null

The filter expression, e.g. all;status~in~healthy;group~nin~lab.

A malformed segment is dropped; a field this list does not have is a 400 naming it. Fields: status, os, os_version, agent_version, group, tactic, strategy, last_seen, enrolled.

qstring · null

Free text over hostname, OS, versions, group and machine ID. ANDs with the expression whichever way its conditions are joined.

cursorstring · null

Where the previous page stopped. Opaque; an unreadable one starts over.

limitinteger · null

Rows wanted: 50 when absent, at most 200. A larger value is answered with 200 rows rather than refused.

lifecyclestring · null

active | suspended | stuck | uninstalled | archived. stuck includes machines still installing. Absent lists every machine that is neither archived nor deleted; a deleted one is never listed.

Response200

Enrolled machines in this workspace

machinesMachine[]required
agent_versionstringrequired
capture_strategiesenum[]required

What this machine is enrolled to be capable of. Immutable.

capture_tacticenumrequired

Worked out from capture_strategies.

nonemetadatamitm_caextensionredirect
enabled_strategiesenum[]required

Which of them are running. Mutable, per strategy.

enrolled_atstringrequired
health_reasonsHealthReason[]required

Most severe first; non-empty only when health is degraded. On a list row this is the beat-time snapshot; on the detail view it is recomputed when the request is read.

totalintegerrequired

How many machines the filter matched in all, not just on this page.

next_cursorstring · null

Pass back as cursor for the next page. null means this was the last.

Errors

400

The filter names a field this surface does not have

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such workspace, or the caller is not a member

Machine names

GET/machines/names

Every live machine's ID and hostname, in one response: a lookup for turning machine IDs into names. It takes no filter and is not paged, so the answer is always complete. Needs the same permission as the machines list.

Response200

Every live machine's id and hostname

machinesMachineName[]required
hostnamestringrequired
idstringrequired
totalintegerrequired

How many machines are in the fleet: the length of machines, since this list is never paged.

Errors

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such workspace, or the caller is not a member

One machine and its counts, for the machine details page

GET/machines/{machine_id}

A machine in another workspace is a 404, never a 403. A 403 would confirm that the id exists, which is a cross-workspace existence oracle: machine ids are not secrets, and an attacker who can tell "not yours" from "no such thing" can enumerate another workspace's fleet through this endpoint. The artifacts and scans reads refuse the same way, and so does the PATCH on this path.

An unparseable id is a 404 too, and not a 400: it is a stale or hand-edited link, and the recovery is the same one — go back to the list.

Path parameters

machine_idstringrequired

Response200

The machine and its counts

artifact_countintegerrequired

Every artifact this machine has reported, in any state — gone and out_of_scope included.

artifacts_with_issuesintegerrequired

How many of those artifacts carry an unresolved issue. Counts artifacts, not issues: two issues on one file count once.

configConfigSection[]required

The ten configuration sections and whether each is applied, in a fixed order. Empty before the machine first checks in.

desired_revstringrequired
sectionstringrequired
statestringrequired

applied | pending | not_applied | unknown.

applied_revstring · null
reasonstring · null

Not applied only: the agent's reason.

sincestring · null

RFC 3339. Applied: when. Pending: since. Not applied: when it failed. Unknown: null.

machineMachinerequired
agent_versionstringrequired
capture_strategiesenum[]required

What this machine is enrolled to be capable of. Immutable.

capture_tacticenumrequired

Worked out from capture_strategies.

nonemetadatamitm_caextensionredirect
enabled_strategiesenum[]required

Which of them are running. Mutable, per strategy.

enrolled_atstringrequired
health_reasonsHealthReason[]required

Most severe first; non-empty only when health is degraded. On a list row this is the beat-time snapshot; on the detail view it is recomputed when the request is read.

scan_countintegerrequired

Scan runs surviving retention, not runs ever recorded: quiet runs past the last few per kind are pruned, so this is the number of rows a reader can actually open.

steering_notesSteeringNote[]required

Facts about steering that are not problems: the surfaces' first, then a second TLS inspector.

kindstringrequired

yielded | stale_incumbent | double_tls_inspection.

reasonstring · null

The agent's sentence, when it gave one.

surfacestring · null

The surface, for yielded and stale_incumbent.

surfacesSurface[]required

One per surface the machine reported, in root, pac, routes order. Empty when not reported.

observed_atstringrequired

RFC 3339, this server's clock: when the surface entered this state. An applied_unwitnessed surface keeps the instant it was applied.

statestringrequired

applied | witnessed | flowing | applied_unwitnessed | yielded | stale_incumbent | root_removed.

surfacestringrequired

root | pac | routes. root is the CA surface.

reasonstring · null

The agent's sentence, when it gave one.

surveySurveyFinding[]required

What else the agent found intercepting. Empty when not reported or none.

detailstringrequired
layerstringrequired

proxy | tunnel | tls | local.

vendorstring · null
tool_hooksToolHooksrequired

The effective hooks section: this machine's own or else its profile's, all five tools present.

fallbackenumrequired

What a hook does when the agent cannot answer. One setting for every tool with hooks on.

allowblock
toolsobjectrequired
tool_restrictionsToolRestrictionsrequired

The effective restrictions: this machine's own or else its profile's.

browsersBrowser[] · null

One row per browser the agent reported, state worked out when the request is answered. null when never reported, which is not the same as "no browsers".

idstringrequired

chrome | edge | brave | chromium | firefox.

stateenumrequired
reportingnot_managednot_installed
versionstringrequired

"" when the agent could not read it.

extension_seen_atstring · null

RFC 3339, or null if the extension has never spoken.

extension_versionstring · null

The extension build the agent last heard from. Null if never.

refusalstring · null

Why the policy is not in place. Null unless state is not_managed.

environmentEnvironment · null

The network a machine last said it is on.

flagsstring[]required

tls_inspected | root_missing | captive.

kindstringrequired

direct | upstream_proxy | vpn | sase_proxy | sase_tunnel.

observed_atstringrequired

RFC 3339, this server's clock: when it first saw this network. The agent's own since is not served.

modestring · null

vpn only: full | split.

ownerstring · null

vpn only: the client that owns the tunnel, as the agent named it.

proxystring · null

upstream_proxy only: fixed | pac | wpad.

last_crashLastCrash · null

The newest crash this machine's agent reported.

atstringrequired

RFC 3339.

messagestringrequired
threadstringrequired
last_scanScanRun · null
artifacts_reportedintegerrequired
changed_somethingbooleanrequired

Whether this run changed the inventory. A run that did is always kept; of the runs that did not, only each machine's most recent few are.

content_changedintegerrequired
created_atstringrequired
disappearedintegerrequired
discoveredintegerrequired
profileMachineProfile · null

One enrollment profile's settings, as a machine's page names them.

log_levelstringrequired
namestringrequired
scanScanConfigrequired

The scan configuration a machine should be running.

replaced_byMachineRef · null

Another machine, by ID, hostname and lifecycle. A deleted one can no longer be read.

hostnamestringrequired
idstringrequired
lifecyclestringrequired
replacesMachineRef · null

Another machine, by ID, hostname and lifecycle. A deleted one can no longer be read.

hostnamestringrequired
idstringrequired
lifecyclestringrequired
steeringSteering · null

One machine's own report on its capture tactic.

appliedstring[]required

The surfaces that went on: root, pac, routes.

failuresintegerrequired

How many plans in a row have failed. 0 on a healthy machine, and the number that separates it just broke from it has never worked.

not_attemptedstring[]required

Surfaces this machine's strategy set never asked for. Not failures, and rendering them as such would make a correctly-scoped machine look broken.

outcomestringrequired

applied, failed or nothing_to_do, as the agent reported it.

reported_atstringrequired

When the machine reported this. Read beside the rest: a status from three days ago describes a machine that has not planned since, not a machine that is fine.

failed_surfacestring · null

The one that did not, or null. This is the field the panel exists for.

tool_coverageToolCoverage[] · null

The AI tools the machine last reported, in the order its agent reported them, with each layer and its gap counts. null when the agent has not reported any, which is not the same as "no tools".

gapsToolGapsrequired

Hook calls that could not reach the agent in the last seven days, by why.

layersToolLayer[]required

In the vocabulary's order: hooks, policy, network, tls, trust.

presentbooleanrequired
toolstringrequired

A registry slug.

versionstring · null
tool_coverage_observed_atstring · null

RFC 3339: when this server stored tool_coverage.

tool_hooks_overrideToolHooks · null

The hooks section. tools is keyed claude_code | codex | gemini_cli | cursor | windsurf | copilot_cli | antigravity; in a response every one of the five is present, and on a request an absent tool is on.

fallbackenumrequired

What a hook does when the agent cannot answer. One setting for every tool with hooks on.

allowblock
toolsobjectrequired
tool_restrictions_overrideToolRestrictions · null

The restrictions section, keyed local_mcp_servers | extensions | extension_directory. An absent key is not set.

worst_issue_severitystring · null

The worst unresolved severity across them, or null when nothing is open. Ranked, never sorted alphabetically — that puts critical after high and low before medium, wrong in both directions at once.

Errors

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such machine in this workspace

Reconfigure a machine

PATCH/machines/{machine_id}

Path parameters

machine_idstringrequired

Request bodyUpdateMachineRequest

attachment_encrypted_archivesstring · null

The per-machine attachment overrides, with the same three states as the scan fields: absent leaves it, null clears back to inheriting, a value sets one. Validated in-handler so the refusal names the field.

attachment_fail_modestring · null
capture_strategiesobject

Refused if sent: the set of strategies is fixed when the machine enrolls. To switch one of them on or off, use PATCH /machines/{id}/strategies/{strategy}.

capture_tacticobject

Refused if sent, even as null: a machine's capture tactic is fixed when it enrolls, and sending it is a 400 that says so.

collect_artifact_contentboolean · null

The per-machine content-collection override, three-state like the panel fields above. Not collection_enabled: that switch decides whether this machine observes AI traffic at all, this one only whether file contents may be collected from it.

collection_enabledboolean · null

Whether the machine is currently collecting at all.

Three-state like everything else below: omitting it leaves collection as it was. It was briefly a required bool, which made every existing caller send a value for a field it had no opinion about — and a caller that has to restate the current setting to change something else will eventually restate it wrongly.

disabled_strategiesstring[] · null

Strategy ids to switch off on this machine. null returns to the profile, [] runs everything enrolled; a strategy the machine never enrolled is 400.

log_levelstring · null

The per-machine log-level override, with the same three states as the scan fields: absent leaves it alone, null clears it back to inheriting from the profile, a value sets one. An unknown level is a 400 naming the accepted levels.

machine_groupstring · null

Which group this machine belongs to. The enrollment profile sets the first value; it can be changed. null returns the machine to ungrouped; omitting the field leaves it alone.

panel_show_collectionboolean · null
panel_show_steeringboolean · null

The per-machine panel overrides, three-state like the attachment fields above.

scan_categoriesstring[] · null
scan_enabledboolean · null

The per-machine scan override; the same applies to every scan_* field. Each has three states: omitting it leaves the stored value alone, null clears the override so the field inherits from the profile again, and a value sets one.

scan_full_hoursinteger · null
scan_max_depthinteger · null
scan_max_filesinteger · null
scan_rootsstring[] · null
scan_skipsstring[] · null
scan_smart_minutesinteger · null
tool_hooksToolHooks · null

The hooks section. tools is keyed claude_code | codex | gemini_cli | cursor | windsurf | copilot_cli | antigravity; in a response every one of the five is present, and on a request an absent tool is on.

fallbackenumrequired

What a hook does when the agent cannot answer. One setting for every tool with hooks on.

allowblock
toolsobjectrequired
tool_restrictionsToolRestrictions · null

The restrictions section, keyed local_mcp_servers | extensions | extension_directory. An absent key is not set.

Response200

Updated machine

agent_versionstringrequired
capture_strategiesenum[]required

What this machine is enrolled to be capable of. Immutable.

capture_tacticenumrequired

Worked out from capture_strategies.

nonemetadatamitm_caextensionredirect
enabled_strategiesenum[]required

Which of them are running. Mutable, per strategy.

enrolled_atstringrequired
health_reasonsHealthReason[]required

Most severe first; non-empty only when health is degraded. On a list row this is the beat-time snapshot; on the detail view it is recomputed when the request is read.

kindstringrequired

steering_failed | root_removed | config_not_applied | crashed | worker_stopped | interception_off | pac_unwitnessed | tool_hooks_failed | ask_unavailable | clock_skew, most severe first.

sectionsstring[]required

config_not_applied only: every section not applied.

under_grantbooleanrequired

interception_off only: turned off under an elevation grant.

atstring · null

RFC 3339. crashed: when. pac_unwitnessed: since when the PAC has been applied with nothing fetching it. tool_hooks_failed: the first of the failing beats.

reasonstring · null

steering_failed only: the agent's sentence.

sessionsinteger · null

ask_unavailable only: how many signed-in people have no companion. Its at is since when.

hostnamestringrequired
idstringrequired
is_pausedbooleanrequired

Whether this machine is paused as of this response, worked out from paused_until by the server.

lifecyclestringrequired

active | installing | stuck | suspended | uninstalled | archived | deleted. A list never carries deleted.

osstringrequired
os_versionstringrequired
pausesPause[]required

Live pauses, all three scopes.

scopestringrequired

enforcement | scans | capture.

untilstringrequired

RFC 3339.

toolsToolBadge[]required

AI tools the machine reported present, in the order its agent reported them. Empty when it has reported none.

hookedbooleanrequired

The hooks layer reads applied or witnessed. False draws the mark dimmed: seen, not hooked.

idstringrequired

A registry slug (heartbeat-tools.json → registry).

usersstring[]required

OS logins with a live presence on this machine, newest first. Personal data, readable by anyone who can read machines.

attachment_encrypted_archivesstring · null

The per-machine attachment overrides; null means the machine inherits the setting from its profile.

attachment_fail_modestring · null
browsersBrowserSummary · null

The Machines list's 3 of 4: covered is how many are reporting.

coveredintegerrequired
totalintegerrequired
bundle_hashstring · null
collect_artifact_contentboolean · null

The per-machine content-collection override; null means the machine inherits its profile's switch. Decides whether file contents may be collected from this machine.

companion_versionstring · null

The companion version the machine last reported. null means not reported yet, not "no companion".

disabled_strategiesstring[] · null

The machine's own disabled-strategy block, null when it follows the profile; enabled_strategies above is the materialised result.

healthenum · null

The health of an active machine. Only an active machine has one; installing and stuck are lifecycle values, not health. unreachable is worked out when the request is answered.

unreachablepauseddegradedhealthy
last_seen_atstring · null

RFC 3339, or null if the machine has never checked in.

log_levelstring · null

The per-machine log-level override, or null when this machine inherits its enrollment profile's level.

machine_groupstring · null
observed_addressstring · null

The address the server last saw this machine's requests arrive from. null before its first beat.

Personal data and a coarse location signal: it names the network a machine connects from. Same grant as above.

panel_show_collectionboolean · null
panel_show_steeringboolean · null

The per-machine panel overrides; null means the machine inherits the setting from its profile.

paused_untilstring · null

When this machine's user paused enforcement until, as it last reported. null means enforcing, which almost every machine almost always is.

A value in the past is stale, not paused: the agent resumes on its own clock and clears the field when it next checks in. Read is_paused rather than comparing this to the current time yourself.

profileMachineProfileRef · null

The enrollment profile a machine enrolled through, by name.

idstringrequired
namestringrequired
reported_addressstring · null

The machine's own primary egress address, as it last reported one. null means it never has: either its agent is too old to report one, or it could not determine an address.

Personal data. Readable by anyone who can read machines.

reported_log_levelstring · null

What the agent last said it is actually running at, or null when it has never said — an agent from before the field, which must render as not reported rather than as obeying the assertion.

scan_categoriesstring[] · null
scan_enabledboolean · null

This machine's scan override, not the configuration it is running. null on any scan_* field means the machine inherits that field from the enrollment profile it enrolled through.

scan_full_hoursinteger · null
scan_max_depthinteger · null
scan_max_filesinteger · null
scan_rootsstring[] · null
scan_skipsstring[] · null
scan_smart_minutesinteger · null
suspended_atstring · null

RFC 3339 when Suspend was pressed, else null.

tool_hooksToolHooks · null

The hooks section. tools is keyed claude_code | codex | gemini_cli | cursor | windsurf | copilot_cli | antigravity; in a response every one of the five is present, and on a request an absent tool is on.

fallbackenumrequired

What a hook does when the agent cannot answer. One setting for every tool with hooks on.

allowblock
toolsobjectrequired
tool_restrictionsToolRestrictions · null

The restrictions section, keyed local_mcp_servers | extensions | extension_directory. An absent key is not set.

uninstalled_atstring · null

RFC 3339 when the agent reported its local uninstall, else null.

Errors

400

Request carried a capture_tactic field, or a scan setting outside its bounds

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

409

The machine is deleted or uninstalled

Per-day interaction and decision counts for one machine

GET/machines/{machine_id}/activity

Gated on machines:read, exactly as the interactions list itself is — this is a rollup of rows that grant already reads, and a stricter gate here would hide a count of things the caller may list one by one.

A machine in another workspace is a 404, never a 403 — get_machine's existence-oracle reasoning.

Path parameters

machine_idstringrequired

Query parameters

daysinteger · null

Trailing window, in UTC days. Default 30, clamped to 1..=90.

Response200

Per-day counts, oldest first, zero-filled

daysActivityDay[]required

Oldest first, zero-filled: the quiet days are data, not gaps.

alertedintegerrequired
alertsintegerrequired

Decisions that were alerts that day: raised by a policy's Alert action or by a justified override. Not an outcome: a Block with Alert is counted in blocked and here; a match with no Alert action is alerted and not here.

blockedintegerrequired
daystringrequired

YYYY-MM-DD.

interactionsintegerrequired

Interactions observed on this machine that day.

justifiedintegerrequired

Errors

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such machine in this workspace

A machine's address history

GET/machines/{machine_id}/addresses

Every retained address change for one machine, both kinds, newest first. At most 50 changes of each kind are kept, and all of them are returned: there is no paging. Needs permission to read machines.

Personal data. A machine in another workspace, or an ID that cannot be read, is a 404. A machine whose address has never changed answers 200 with two empty lists.

Path parameters

machine_idstringrequired

Response200

Both kinds' retained changes, newest first

capintegerrequired

How many changes of each kind are kept for a machine. A list this long has had older changes dropped.

observedAddressChange[]required

What the server saw the connection arrive from.

addressstringrequired

The address it changed to, bare — never with a /32 suffix.

changed_atstringrequired

RFC 3339. The API states instants and never pre-formats them.

privatebooleanrequired

True when address is private, loopback, link-local, CGNAT or otherwise non-global — a network inside somebody's walls, about which no country claim would be honest.

countrystring · null

The ISO 3166-1 alpha-2 country of address, looked up on the server itself: no address is sent anywhere to be located. Null for every private address and for a public one the lookup does not cover; private tells the two apart.

previous_addressstring · null

What it replaced, or null when this is the first of its kind.

reportedAddressChange[]required

What the agent said its own primary egress interface was.

addressstringrequired

The address it changed to, bare — never with a /32 suffix.

changed_atstringrequired

RFC 3339. The API states instants and never pre-formats them.

privatebooleanrequired

True when address is private, loopback, link-local, CGNAT or otherwise non-global — a network inside somebody's walls, about which no country claim would be honest.

countrystring · null

The ISO 3166-1 alpha-2 country of address, looked up on the server itself: no address is sent anywhere to be located. Null for every private address and for a public one the lookup does not cover; private tells the two apart.

previous_addressstring · null

What it replaced, or null when this is the first of its kind.

Errors

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such machine in this workspace

A machine's content collection queue

GET/machines/{machine_id}/collection

The file contents requested from this machine: counts by state and up to 200 requests, newest first. A machine in another workspace is a 404.

Path parameters

machine_idstringrequired

Response200

This machine's tracked content queue

countsContentRequestCountsrequired
failedintegerrequired

Requests that used up every attempt without the file contents arriving. Final: the server has stopped asking, so these are not counted as still in progress.

in_flightintegerrequired

The agent said it holds the request (acknowledged).

outstandingintegerrequired

Requests that could still end with the file contents stored.

queuedintegerrequired

Outstanding and not yet acknowledged: requested, plus failed short of the attempt cap — both are still waiting on a beat to move them.

storedintegerrequired

The body arrived (stored). Terminal.

rowsContentRequestRow[]required
artifact_idstringrequired
attemptsintegerrequired
content_hashstringrequired
locationstringrequired
namestringrequired
requested_atstringrequired

RFC 3339.

Errors

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such machine in this workspace

List a machine's recent commands

GET/machines/{machine_id}/commands

The latest 20 commands sent to this machine, newest first, and what its agent said happened.

Path parameters

machine_idstringrequired

Response200

Recent commands, newest first

commandsCommand[]required

Newest first.

delivery_countintegerrequired

How many heartbeats have carried it.

expires_atstringrequired

RFC 3339. When an unanswered command stops being delivered.

idstringrequired
issued_atstringrequired

RFC 3339.

kindstringrequired
payloadobjectrequired

What was asked, verbatim — {"level": "debug"} on a set_log_level, {} on the rest. Operator-authored, never agent-authored.

Errors

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

Queue a command for a machine

POST/machines/{machine_id}/commands

The machine picks the command up when it next checks in. A command that is not picked up before its kind's expiry, or that the machine receives several times without answering, is dropped.

Path parameters

machine_idstringrequired

Request bodySendCommandRequest

kindstringrequired
payloadobject

Response202

Command queued

idstringrequired

Errors

400

Unknown command kind

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

409

A retired kind (retired_kind), or a deleted or uninstalled machine

A machine's AI connections

GET/machines/{machine_id}/connections

The tools on this machine that talked to AI services, and the services they talked to, over a recent window. A machine in another workspace, or a deleted one, is a 404.

Path parameters

machine_idstringrequired

Query parameters

hoursinteger · null

Trailing window, in hours. Default 24, clamped to 1..=168.

Response200

Tools and services, largest first

servicesConnectionService[]required

Largest first, at most 20.

blockedintegerrequired

Interactions with at least one blocked decision.

hoststringrequired

The AI service host, e.g. api.anthropic.com.

interactionsintegerrequired
toolsConnectionTool[]required

Largest first, at most 20.

interactionsintegerrequired
namestringrequired

The client's own declared name, e.g. Claude Code; its client_kind word (cli, ide, …) when it declared none; other when neither.

kindstring · null

The commonest declared client kind among its interactions.

total_servicesintegerrequired

As total_tools, for services.

total_toolsintegerrequired

How many distinct tools were in the window, including any past the 20 the list stops at.

window_hoursintegerrequired

The window actually used, after the clamp.

Errors

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such machine in this workspace, or it was deleted

Delete a machine

POST/machines/{machine_id}/delete

Final. The machine leaves every list, and if its agent comes back online it is told it was deleted and removes itself. An Active machine cannot be deleted (409 not_deletable).

Path parameters

machine_idstringrequired

Response204

Deleted

Errors

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

409

not_deletable (an Active machine) or deleted

List a machine's diagnostic bundles

GET/machines/{machine_id}/diagnostics

Newest first, without log tails. Needs permission to manage the fleet, because a bundle answers a command only a fleet manager can send.

Path parameters

machine_idstringrequired

Query parameters

fstring · null

The filter expression, e.g. all;truncated~in~true;error~nin~none.

Fields: agent_version, bundle_hash, truncated, error, collected, received. The machine is not one of them: it is the path, not a condition, which is what makes this tab's locked chip a statement of the surface rather than a filter a reader could clear.

qstring · null

Free text over the agent version, the bundle hash and the error kind. Never the log tail — this route does not serve one.

cursorstring · null

Where the previous page stopped. Opaque; an unreadable one starts over.

limitinteger · null

Rows wanted: 50 when absent, between 1 and 200.

Response200

Stored bundles, newest first

diagnosticsDiagnosticsSummary[]required
agent_versionstringrequired
collected_atstringrequired

RFC 3339, from the endpoint's clock.

command_idstringrequired
idstringrequired
log_bytes_totalintegerrequired
received_atstringrequired

RFC 3339, from ours.

totalintegerrequired

How many bundles the filter matched in all, not just on this page.

next_cursorstring · null

Pass back as cursor for the next page. null means this was the last.

Errors

400

The filter names a field this surface does not have

401

No valid session

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

One diagnostic bundle

GET/machines/{machine_id}/diagnostics/{id}

The bundle in full, log tail included. Needs permission to manage the fleet. Each read is recorded in the audit log; listing bundles is not.

Path parameters

machine_idstringrequired
idstringrequired

Response200

The bundle

agent_versionstringrequired
collected_atstringrequired
command_idstringrequired
countersobjectrequired

Free-form counters, exactly as the agent sent them.

idstringrequired
log_bytes_totalintegerrequired
log_tailstringrequired

The end of the agent's log. Only a single bundle carries it; the list does not.

received_atstringrequired
stored_bytesintegerrequired
truncatedbooleanrequired
bundle_hashstring · null
last_error_kindstring · null

Errors

401

No valid session

403

Caller lacks fleet:manage in this workspace

404

No such bundle for this machine in this workspace

Delete a diagnostic bundle

DELETE/machines/{machine_id}/diagnostics/{id}

Removes the bundle for good, not just from view, and records the deletion in the audit log. Needs the fleet:manage permission. A 404 when the bundle is not this machine's or the machine is not in this workspace. Deleting a bundle does not ask the machine for a new one.

Path parameters

machine_idstringrequired
idstringrequired

Response204

The bundle no longer exists on the server

Errors

401

No valid session

403

Caller lacks fleet:manage in this workspace

404

No such bundle for this machine in this workspace

List a machine's elevation grants

GET/machines/{machine_id}/elevation-grants

Newest first, with each grant's state: live, revoked or expired. Needs permission to manage the fleet.

Path parameters

machine_idstringrequired

Response200

This machine's grants, newest first

capabilitiesstring[]required
created_atstringrequired
expires_atstringrequired
grant_idstringrequired
standingbooleanrequired

The grant stands until revoked; expires_at is then a century out.

statestringrequired

live, revoked or expired.

first_used_atstring · null

None for a grant nobody ever pasted in — a fact worth showing, not a gap to hide.

revoked_atstring · null

Errors

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

Resume a suspended machine

POST/machines/{machine_id}/resume

The machine's agent sets itself up again on its next check-in.

Path parameters

machine_idstringrequired

Response204

Resumed

Errors

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

409

not_suspended, uninstalled or deleted

Turn one of a machine's strategies on or off

PATCH/machines/{machine_id}/strategies/{strategy}

The set of strategies a machine enrolled with never changes; this only decides which of them are running. A strategy the machine did not enroll with is a 400, not an addition.

Path parameters

machine_idstringrequired
strategystringrequired

Request bodySetStrategyEnabledRequest

enabledbooleanrequired

Whether this strategy should be running.

Response200

Updated machine

agent_versionstringrequired
capture_strategiesenum[]required

What this machine is enrolled to be capable of. Immutable.

capture_tacticenumrequired

Worked out from capture_strategies.

nonemetadatamitm_caextensionredirect
enabled_strategiesenum[]required

Which of them are running. Mutable, per strategy.

enrolled_atstringrequired
health_reasonsHealthReason[]required

Most severe first; non-empty only when health is degraded. On a list row this is the beat-time snapshot; on the detail view it is recomputed when the request is read.

kindstringrequired

steering_failed | root_removed | config_not_applied | crashed | worker_stopped | interception_off | pac_unwitnessed | tool_hooks_failed | ask_unavailable | clock_skew, most severe first.

sectionsstring[]required

config_not_applied only: every section not applied.

under_grantbooleanrequired

interception_off only: turned off under an elevation grant.

atstring · null

RFC 3339. crashed: when. pac_unwitnessed: since when the PAC has been applied with nothing fetching it. tool_hooks_failed: the first of the failing beats.

reasonstring · null

steering_failed only: the agent's sentence.

sessionsinteger · null

ask_unavailable only: how many signed-in people have no companion. Its at is since when.

hostnamestringrequired
idstringrequired
is_pausedbooleanrequired

Whether this machine is paused as of this response, worked out from paused_until by the server.

lifecyclestringrequired

active | installing | stuck | suspended | uninstalled | archived | deleted. A list never carries deleted.

osstringrequired
os_versionstringrequired
pausesPause[]required

Live pauses, all three scopes.

scopestringrequired

enforcement | scans | capture.

untilstringrequired

RFC 3339.

toolsToolBadge[]required

AI tools the machine reported present, in the order its agent reported them. Empty when it has reported none.

hookedbooleanrequired

The hooks layer reads applied or witnessed. False draws the mark dimmed: seen, not hooked.

idstringrequired

A registry slug (heartbeat-tools.json → registry).

usersstring[]required

OS logins with a live presence on this machine, newest first. Personal data, readable by anyone who can read machines.

attachment_encrypted_archivesstring · null

The per-machine attachment overrides; null means the machine inherits the setting from its profile.

attachment_fail_modestring · null
browsersBrowserSummary · null

The Machines list's 3 of 4: covered is how many are reporting.

coveredintegerrequired
totalintegerrequired
bundle_hashstring · null
collect_artifact_contentboolean · null

The per-machine content-collection override; null means the machine inherits its profile's switch. Decides whether file contents may be collected from this machine.

companion_versionstring · null

The companion version the machine last reported. null means not reported yet, not "no companion".

disabled_strategiesstring[] · null

The machine's own disabled-strategy block, null when it follows the profile; enabled_strategies above is the materialised result.

healthenum · null

The health of an active machine. Only an active machine has one; installing and stuck are lifecycle values, not health. unreachable is worked out when the request is answered.

unreachablepauseddegradedhealthy
last_seen_atstring · null

RFC 3339, or null if the machine has never checked in.

log_levelstring · null

The per-machine log-level override, or null when this machine inherits its enrollment profile's level.

machine_groupstring · null
observed_addressstring · null

The address the server last saw this machine's requests arrive from. null before its first beat.

Personal data and a coarse location signal: it names the network a machine connects from. Same grant as above.

panel_show_collectionboolean · null
panel_show_steeringboolean · null

The per-machine panel overrides; null means the machine inherits the setting from its profile.

paused_untilstring · null

When this machine's user paused enforcement until, as it last reported. null means enforcing, which almost every machine almost always is.

A value in the past is stale, not paused: the agent resumes on its own clock and clears the field when it next checks in. Read is_paused rather than comparing this to the current time yourself.

profileMachineProfileRef · null

The enrollment profile a machine enrolled through, by name.

idstringrequired
namestringrequired
reported_addressstring · null

The machine's own primary egress address, as it last reported one. null means it never has: either its agent is too old to report one, or it could not determine an address.

Personal data. Readable by anyone who can read machines.

reported_log_levelstring · null

What the agent last said it is actually running at, or null when it has never said — an agent from before the field, which must render as not reported rather than as obeying the assertion.

scan_categoriesstring[] · null
scan_enabledboolean · null

This machine's scan override, not the configuration it is running. null on any scan_* field means the machine inherits that field from the enrollment profile it enrolled through.

scan_full_hoursinteger · null
scan_max_depthinteger · null
scan_max_filesinteger · null
scan_rootsstring[] · null
scan_skipsstring[] · null
scan_smart_minutesinteger · null
suspended_atstring · null

RFC 3339 when Suspend was pressed, else null.

tool_hooksToolHooks · null

The hooks section. tools is keyed claude_code | codex | gemini_cli | cursor | windsurf | copilot_cli | antigravity; in a response every one of the five is present, and on a request an absent tool is on.

fallbackenumrequired

What a hook does when the agent cannot answer. One setting for every tool with hooks on.

allowblock
toolsobjectrequired
tool_restrictionsToolRestrictions · null

The restrictions section, keyed local_mcp_servers | extensions | extension_directory. An absent key is not set.

uninstalled_atstring · null

RFC 3339 when the agent reported its local uninstall, else null.

Errors

400

Unknown strategy, or one this machine did not enrol with

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

409

The machine is deleted or uninstalled

Suspend a machine

POST/machines/{machine_id}/suspend

On its next check-in the machine's agent puts back what it changed and stands down, still checking in every five minutes. Reversible with Resume.

Path parameters

machine_idstringrequired

Response204

Suspended

Errors

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

409

already_suspended, uninstalled, archived or deleted

A machine's history

GET/machines/{machine_id}/timeline

Newest first: the audit records that name the machine, each command's queued, delivered and answered stages, and what the machine itself reported. Needs permission to manage the fleet.

Path parameters

machine_idstringrequired

Query parameters

beforestring · null

next_before from the previous page.

limitinteger · null

1–200; default 50.

Response200

The machine's history, newest first

entriesTimelineEntry[]required

Newest first.

atstringrequired

RFC 3339.

kindstringrequired

config_changed | lifecycle | diagnostics | companion_action | grant | command_queued | command_delivered | command_acked | command_expired | command_quarantined | config_applied | config_failed | restarted | pause_started | pause_ended | health_changed | gap | environment | surface | suspended | resumed | deleted | uninstalled | self_removed | archived | unarchived | replaced | tool_coverage | ask_unavailable | ask_available.

titlestringrequired

One line, composed by the server, in sentence case.

actorstring · null

The display name of the person who did it, or null when no person did.

detailobject

The entry's facts, or null when it has none.

next_beforestring · null

Pass back as before; null on the last page.

Errors

400

before is not a cursor this route issued

403

Caller lacks fleet:manage in this workspace

404

No such machine in this workspace

A machine's updates, newest first

GET/machines/{machine_id}/updates

Path parameters

machine_idstringrequired

Response200

Updates, newest first

attemptintegerrequired

1 for the first try; each retry adds one.

from_versionstringrequired
hostnamestringrequired
idstringrequired
machine_idstringrequired
osstringrequired

The machine's OS, as it reports it: windows | macos | linux.

partialbooleanrequired

The update reached its version and left something undone: a reconcile step failed, interrupted or deferred, a retired file failed, or a component skipped. false while outcome is null.

phase_atstringrequired

When state last changed.

rollout_idstringrequired
scopestringrequired

The rollout's scope: profile | machine.

started_atstringrequired
statestringrequired

waiting | downloading | verifying | installing | awaiting | updated | failed | cancelled | skipped.

target_versionstringrequired

What this machine is moving to: the default build of its OS when the rollout started.

updated_atstringrequired
last_errorstring · null

Why it failed or was skipped or cancelled, in a sentence.

next_retry_atstring · null

When the next automatic retry is due; null when none is.

outcomeUpdateOutcome · null

What an update did on the machine, in the agent's own account. An endpoint's word: shown, and trusted for nothing.

componentsUpdateComponentOutcome[]
reconcileUpdateReconcileStep[]
retiredUpdateRetiredOutcome[]
skip_reasonstring · null

Why a skipped machine was skipped: no_build (the release has no agent build for its OS), needs_reinstall (it runs a version too old to update in place) or ahead (it already runs something newer). null on every other state.

started_bystring · null

null when the sweep started it (automatic update).

Errors

401

No valid session

403

Caller lacks machines:read in this workspace

404

No such machine in this workspace

Update one machine to the default build

POST/machines/{machine_id}/updates

Path parameters

machine_idstringrequired

Request bodyStartUpdateRequest

max_retriesinteger · null

Automatic retries per machine, 0–5. Omitted means 3.

Response201

The rollout

countsobjectrequired

Rows per state, zeros left out.

idstringrequired
max_retriesintegerrequired

Automatic retries per machine, 0–5.

rowsMachineUpdate[]required
attemptintegerrequired

1 for the first try; each retry adds one.

from_versionstringrequired
hostnamestringrequired
idstringrequired
machine_idstringrequired
osstringrequired

The machine's OS, as it reports it: windows | macos | linux.

scopestringrequired

profile | machine.

started_atstringrequired
target_versionstringrequired

The highest version any of its machines is moving to — a headline. Machines of different OSes can move to different versions: targets says which, and each row carries its own target_version.

targetsRolloutTarget[]required

Per OS, in the order windows, macos, linux.

countsobjectrequired

Those machines per state, zeros left out.

machinesintegerrequired

The rollout's machines of this OS moving to version.

osstringrequired

windows | macos | linux.

versionstringrequired
cancelled_atstring · null
finished_atstring · null

Set once no machine has anything left to do.

profile_idstring · null
started_bystring · null

The user who started it; null when the sweep started it because the profile updates automatically (or the user has since been deleted — the audit row still names them).

Errors

400

max_retries outside 0–5

401

No valid session

403

Caller lacks fleet:manage in this workspace

404

No such live machine in this workspace

409

The machine is not behind the default, or no release is published