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.

Endpoint Authentication Success response
/enroll Enrollment token in body 200 JSON
/heartbeat Device API key 200 JSON
/postures Device API key 204
/unenroll Device API key 204

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>"
}
Field Type Required Description
token string Yes One-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"
}
Field Type Required Description
hardware_uuid string Yes Stable hardware identifier
serial_number string No Hardware serial number
hostname string Yes Current device hostname
platform string Yes One of the supported platform values below
os_version string Yes Human-readable operating-system version
agent_version string Yes Version of the reporting agent implementation

Valid platform values are:

Value Platform
DARWIN macOS
LINUX Linux
FREEBSD FreeBSD
WINDOWS Windows

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"
}
Field Type Description
device_id string Probo identifier for the enrolled device
heartbeat_interval_seconds integer Delay between heartbeat requests
posture_interval_seconds integer Delay between posture collection cycles
server_time string Current 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"
}
]
}
Field Type Required Description
results array Yes Up to 100 posture results
check_key string Yes Stable identifier for the check
status string Yes Result status
evidence JSON object No Details supporting the result
observed_at string Yes Observation time in RFC 3339 format
correlation_id string No Probo 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.

Value Meaning
PASS The check passed
FAIL The check failed
UNKNOWN The agent could not determine the result
NOT_APPLICABLE The 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 key What it evaluates
DISK_ENCRYPTION Full-disk encryption
SCREEN_LOCK Screen or idle-lock configuration
FIREWALL_ENABLED Host firewall
TIME_SYNC System clock synchronization
OS_VERSION Operating-system version
AUTO_UPDATE Automatic operating-system updates
PASSWORD_POLICY Local password policy
REMOTE_LOGIN Remote-login exposure
MALWARE_PROTECTION Built-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.

Status Meaning
400 Invalid JSON, missing fields, invalid enum, or oversized batch
401 Invalid enrollment token, missing/invalid API key, revocation, or posture before activation
405 The route was called with a method other than POST
500 Unexpected 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.