Skip to content

Products

Compliance Officer Service Expert-led compliance, end to end Compliance Portal Share security documents securely Open-source platform Deploy Probo on your own infrastructure

Resources

Probo stories How teams get compliant with Probo Blog Ideas and guidance from the Probo team Guides & tools Practical compliance guides and free tools Love from Customers What customers say about working with Probo Changelog Latest product updates Download Get the Probo Agent

Company

About The people and vision powering Probo Careers Join the team building Probo Brand assets Official logos and visual resources Security Review our security and compliance posture
Overview Understand Probo and its core concepts Product Explore Probo's GRC capabilities Developers Explore GraphQL, CLI, MCP, n8n, and webhooks Deployment Probo Cloud, self-hosting, and configuration

Explore

GitHub Explore our open-source compliance tools

Device Agent Endpoints

Request and response reference for the four Device Agent API routes — /enroll, /heartbeat, /postures, and /unenroll — plus their error codes.

View as Markdown

All Device Agent API routes use POST and are relative to {probo-origin}/api/agent/v1.

EndpointAuthenticationSuccess response
/enrollEnrollment token in body200 JSON
/heartbeatDevice API key200 JSON
/posturesDevice API key204
/unenrollDevice API key204

Send these headers with every request:

Accept: application/json
Content-Type: application/json
User-Agent: my-probo-agent/1.0.0

For every route except /enroll, also send:

Authorization: Bearer <device-api-key>

User-Agent is recommended for troubleshooting and is not used for authentication.

Exchanges a one-shot enrollment token for a device API key.

POST /api/agent/v1/enroll

The request body is limited to 16 KiB.

{
"token": "<enrollment-token>"
}
FieldTypeRequiredDescription
tokenstringYesOne-shot enrollment token

200 OK

{
"api_key": "<device-api-key>"
}

Store the key securely before starting the service. The enrollment token is deleted after a successful exchange and cannot be reused.

Reports the device identity and retrieves its reporting schedule. The first successful heartbeat changes a PENDING device to ACTIVE. Heartbeat and posture intervals are independent; update each local timer from the response.

POST /api/agent/v1/heartbeat
Authorization: Bearer <device-api-key>

The request body is limited to 16 KiB.

{
"hardware_uuid": "example-hardware-id",
"serial_number": "example-serial-number",
"hostname": "example-device",
"platform": "LINUX",
"os_version": "Example Linux 1.0",
"agent_version": "1.0.0"
}
FieldTypeRequiredDescription
hardware_uuidstringYesStable hardware identifier
serial_numberstringNoHardware serial number
hostnamestringYesCurrent device hostname
platformstringYesOne of the supported platform values below
os_versionstringYesHuman-readable operating-system version
agent_versionstringYesVersion of the reporting agent implementation

Valid platform values are:

ValuePlatform
DARWINmacOS
LINUXLinux
FREEBSDFreeBSD
WINDOWSWindows

The hardware UUID must be stable across restarts. Probo rejects activation if another device in the organization already uses it.

200 OK

{
"device_id": "<device-id>",
"heartbeat_interval_seconds": 300,
"posture_interval_seconds": 3600,
"server_time": "2026-08-05T14:00:00Z"
}
FieldTypeDescription
device_idstringProbo identifier for the enrolled device
heartbeat_interval_secondsintegerDelay between heartbeat requests
posture_interval_secondsintegerDelay between posture collection cycles
server_timestringCurrent server time in RFC 3339 UTC format

The current defaults are 300 seconds for heartbeats and 3,600 seconds for posture collection. Treat the response as authoritative: update each local timer after every successful heartbeat instead of hard-coding these values or assuming the schedules stay in lockstep.

Pushes a batch of locally evaluated posture checks. The device must have sent a successful heartbeat before reporting posture. A posture request while the device is still PENDING returns 401 Unauthorized—the same status used for revocation—so activate with /heartbeat first.

POST /api/agent/v1/postures
Authorization: Bearer <device-api-key>

The request body is limited to 1 MiB and can contain at most 100 results.

{
"results": [
{
"check_key": "FIREWALL_ENABLED",
"status": "PASS",
"evidence": {
"backend": "ufw",
"raw": "Status: active"
},
"observed_at": "2026-08-05T14:00:00Z"
}
]
}
FieldTypeRequiredDescription
resultsarrayYesUp to 100 posture results
check_keystringYesStable identifier for the check
statusstringYesResult status
evidenceJSON objectNoDetails supporting the result
observed_atstringYesObservation time in RFC 3339 format
correlation_idstringNoProbo posture-report ID used to group related result sets

An empty results array is accepted as a no-op. A successful request returns 204 No Content.

ValueMeaning
PASSThe check passed
FAILThe check failed
UNKNOWNThe agent could not determine the result
NOT_APPLICABLEThe check does not apply to this device

Use the official keys when your check has the same meaning. This allows Probo to interpret and display the evidence consistently.

Check keyWhat it evaluates
DISK_ENCRYPTIONFull-disk encryption
SCREEN_LOCKScreen or idle-lock configuration
FIREWALL_ENABLEDHost firewall
TIME_SYNCSystem clock synchronization
OS_VERSIONOperating-system version
AUTO_UPDATEAutomatic operating-system updates
PASSWORD_POLICYLocal password policy
REMOTE_LOGINRemote-login exposure
MALWARE_PROTECTIONBuilt-in malware protection

The API accepts other non-empty check keys, but Probo might display their evidence as unknown. Use a stable uppercase identifier and keep its semantics consistent across agent versions.

Evidence is free-form JSON. Prefer an object with concise machine-readable fields. Do not include secrets, full configuration files, or command output that might contain personal or sensitive data.

The official agent’s evidence schemas are the best reference when implementing a canonical check. See the checks package.

Results from one collection cycle should belong to one posture report. If correlation_id is omitted, Probo creates one ID and applies it to every result in the request.

Only provide a correlation ID when you already have a valid Probo device-posture-report ID for the same tenant. Invalid IDs, IDs for another entity type, and IDs from another tenant return 400 Bad Request.

Revokes the current device API key.

POST /api/agent/v1/unenroll
Authorization: Bearer <device-api-key>

No request fields are required. A successful request returns 204 No Content. Delete local credentials whether or not this best-effort request succeeds during uninstall.

StatusMeaning
400Invalid JSON, missing fields, invalid enum, or oversized batch
401Invalid enrollment token, missing/invalid API key, revocation, or posture before activation
405The route was called with a method other than POST
500Unexpected server error

Do not depend on the exact error message. Log the status and safe request context without logging credentials or posture evidence. Retry temporary network failures and 5xx responses with bounded exponential backoff. Do not retry 400 responses without changing the request, and clear credentials after 401 except during bring-up when a posture request precedes the first successful heartbeat.