| POST | /api/hosts/heartbeat |
| POST | /api/hosts/posture |
Agent heartbeat
POST/api/hosts/heartbeat
Called by the installed Shellius agent every 60 s via its systemd timer. Authentication: X-Agent-Token header, resolved by agentAuth (per-host token preferred; falls back to the legacy AGENT_SHARED_SECRET — see middleware/agentAuth.js). Per-host tokens resolve the server/org identity themselves, so the body's serverId/orgId are IGNORED in that mode — a stolen/legacy token (or a compromised host) can no longer forge another server's heartbeat by editing the request body. Legacy mode has no per-host identity to fall back on, so it keeps the old body-scoped lookup.
Authentication: none — the token in the request is the credential.
Request body
| Name | Type | Required | Notes |
|---|---|---|---|
agentId | string | Yes | |
serverId | string | Yes | |
orgId | string | Yes | |
agentVersion | string | No | May be null. |
hostname | string | No | May be null. |
ipAddress | string | No | May be null. |
curl -X POST "https://shellius.example.com/api/hosts/heartbeat" \
-H "Content-Type: application/json" \
-d '{
"agentId": "…",
"serverId": "…",
"orgId": "…"
}'200 OK
{ "success": true, "data": { … } }Posture
POST/api/hosts/posture
This route parses its own body: the app-wide express.json() keeps express's 100kb default, which a legitimate snapshot can exceed. The larger parser is mounted HERE so only this endpoint accepts a bigger body, and it is still bounded — 256KB, the same number the Content-Length check below enforces.
Authentication: none.
Request body
| Name | Type | Required | Notes |
|---|---|---|---|
schemaVersion | number | No | Default 1. 1–1. |
scanner | string | No | At most 128 characters. May be null. |
agentVersion | string | No | At most 64 characters. May be null. |
collectedAt | date | Yes | ISO 8601. |
hostname | string | No | At most 512 characters. May be null. |
collectorOk | boolean | No | Default true. |
degradedReason | string | No | At most 512 characters. May be null. |
firewall | object | No | |
listeners | array | No | Default []. At most 500. |
services | array | No | Default []. At most 300. |
serviceScan | object | No | |
metrics | object | No | May be null. |
curl -X POST "https://shellius.example.com/api/hosts/posture" \
-H "Content-Type: application/json" \
-d '{
"collectedAt": "…"
}'200 OK
{ "success": true, "data": { … } }