mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 18:45:53 +00:00
8ea94d792b
Nothing in Pulse showed a paying customer what Patrol had done for them: about 164 runs a month per install, findings raised, investigations and fixes, and none of it summarised. GET /api/ai/patrol/digest rolls the last N days (default 7, max 30) up from records Pulse already keeps: run history, the findings store, Patrol-origin action audits, and the usage cost store. It adds no telemetry and persists nothing. The payload reports when the bounded run history no longer covers the window and when model pricing is unknown, rather than quietly under-counting. This is the first slice of the "Patrol weekly digest" named bet in the pulse-pro demand ledger; the in-app "This week" card follows once its browser pass is recorded. docs/PATROL_WEEKLY_DIGEST.md holds the design note and the honest limits of each line. status.json registers the patrol-value-visibility coverage gap, the candidate lane, and its work claim. It also drops the second, identical copy of the ai-provider-guided-setup coverage gap that landed with #1853; the duplicate id fails the status audit on main for every pull request.
1550 lines
61 KiB
Markdown
1550 lines
61 KiB
Markdown
# 🔌 Pulse API Reference
|
||
|
||
Pulse provides a comprehensive REST API for automation and integration.
|
||
|
||
**Base URL**: `http://<your-pulse-ip>:7655/api`
|
||
|
||
## 🔐 Authentication
|
||
|
||
Most API requests require authentication via one of the following methods:
|
||
|
||
### API Token (Recommended)
|
||
Pass the token in the `X-API-Token` header.
|
||
```bash
|
||
curl -H "X-API-Token: your-token" http://localhost:7655/api/health
|
||
```
|
||
|
||
### Bearer Token
|
||
```bash
|
||
curl -H "Authorization: Bearer your-token" http://localhost:7655/api/health
|
||
```
|
||
|
||
### Session Cookie
|
||
Standard browser session cookie (used by the UI).
|
||
|
||
Session endpoints:
|
||
- `POST /api/login` (sets `pulse_session` + `pulse_csrf`)
|
||
- `POST /api/logout` (clears session)
|
||
|
||
Login body:
|
||
```json
|
||
{ "username": "admin", "password": "secret", "rememberMe": true }
|
||
```
|
||
|
||
Public endpoints include:
|
||
- `GET /api/health`
|
||
- `GET /api/version`
|
||
- `GET /api/agent/version` (agent update checks)
|
||
- `GET /api/setup-script` (requires a setup token)
|
||
|
||
## 🔏 Scopes and Admin Access
|
||
|
||
Some endpoints require admin privileges and/or scopes. Common scopes include:
|
||
- `monitoring:read`
|
||
- `settings:read`
|
||
- `settings:write`
|
||
- `agent:config:read`
|
||
- `agent:manage`
|
||
|
||
Endpoints that require admin access are noted below.
|
||
|
||
---
|
||
|
||
## 📡 Core Endpoints
|
||
|
||
### System Health
|
||
`GET /api/health`
|
||
Check if Pulse is running.
|
||
```json
|
||
{
|
||
"status": "healthy",
|
||
"timestamp": 1700000000,
|
||
"uptime": 3600,
|
||
"devModeSSH": false
|
||
}
|
||
```
|
||
|
||
### System State
|
||
`GET /api/state`
|
||
Returns the complete state of your infrastructure (Nodes, VMs, Containers, Storage, Alerts). This is the main endpoint used by the dashboard.
|
||
|
||
`GET /api/state/summary`
|
||
Returns a lightweight integration summary for external dashboards and checks. Requires `monitoring:read`.
|
||
|
||
```json
|
||
{
|
||
"activeAlerts": 1,
|
||
"nodes": 2,
|
||
"vms": 8,
|
||
"containers": 12,
|
||
"dockerHosts": [
|
||
{
|
||
"name": "Docker Host",
|
||
"containers": 5,
|
||
"uptimeSeconds": 86400,
|
||
"cpuUsagePercent": 12.5
|
||
}
|
||
],
|
||
"verdicts": {
|
||
"ok": 17,
|
||
"attention": 1,
|
||
"critical": 1,
|
||
"stale": 1,
|
||
"off": 2,
|
||
"unknown": 0
|
||
},
|
||
"attention": [
|
||
{
|
||
"id": "node-1",
|
||
"name": "PVE Node 1",
|
||
"type": "agent",
|
||
"platformType": "proxmox",
|
||
"verdict": "critical",
|
||
"topReason": { "code": "offline" }
|
||
}
|
||
],
|
||
"lastUpdate": "2026-05-24T10:11:12Z"
|
||
}
|
||
```
|
||
|
||
`verdicts` uses the canonical `ok`, `attention`, `critical`, `stale`, `off`,
|
||
and `unknown` fleet-health vocabulary. `attention` is severity ordered and
|
||
capped at 30 entries. Powered-off workloads are neutral (`off`), and stale or
|
||
missing telemetry is never reported as `ok`.
|
||
|
||
### Simple Stats (HTML)
|
||
`GET /simple-stats`
|
||
Lightweight HTML status page for quick checks.
|
||
|
||
### Unified Resources
|
||
`GET /api/resources`
|
||
Returns the unified resource list with pagination + aggregations. Requires `monitoring:read`.
|
||
|
||
Query params:
|
||
- `type`: comma-separated list (e.g., `agent`, `vm`, `system-container`, `container`, `docker-service`, `storage`, `pbs`, `pmg`, `k8s-cluster`, `k8s-node`, `pod`, `k8s-deployment`, `physical_disk`, `ceph`)
|
||
- `source`: comma-separated list (e.g., `proxmox`, `agent`, `docker`, `pbs`, `pmg`, `kubernetes`)
|
||
- `excludeSource`: comma-separated list of sources that must not be present on a matching resource
|
||
- `status`: comma-separated list (`online`, `offline`, `warning`, `unknown`)
|
||
- `parent`: parent resource ID
|
||
- `cluster`: cluster name
|
||
- `namespace`: Kubernetes namespace (filters Kubernetes resources only)
|
||
- `q`: name search (contains match)
|
||
- `tags`: comma-separated tags
|
||
- `page`: page number (default `1`)
|
||
- `limit`: page size (default `50`, max `100`)
|
||
- `sort`: `name` (default), `status`, `type`, `lastSeen`
|
||
- `order`: `asc` (default) or `desc`
|
||
|
||
Note: `GET /api/resources` is optimized for list views. Some large, platform-specific fields may be omitted from the list response and are only returned by `GET /api/resources/{id}`.
|
||
|
||
Each list resource can include a backend-owned `health` envelope with a
|
||
canonical `verdict` and stable `reasons` (`code` plus optional compact
|
||
`detail`). Consumers should use this envelope for cross-platform posture
|
||
instead of deriving health from provider-specific status strings.
|
||
|
||
Note: guest disk usage percentages use `-1` as an "unknown" sentinel — reported when a VM is stopped or its guest agent is unavailable, so there is no filesystem view to measure. Consumers should treat negative values as "no data", not as a percentage; the accompanying `diskStatusReason` field (e.g. `vm-stopped`, `agent-disabled`) says why.
|
||
|
||
Availability is an additive resource facet. `availability` is the compatibility
|
||
summary used by existing clients; `availabilityChecks` contains every check
|
||
attached to the resource. Each check can include `correlationState`
|
||
(`attached`, `standalone`, `ambiguous`, or `unresolved`), its correlation
|
||
rule/reason/candidate count, and an `evidence` envelope with observation and
|
||
validity timestamps. Attached targets also add a `checks` relationship and do
|
||
not appear as separate `network-endpoint` rows.
|
||
|
||
`GET /api/resources/stats`
|
||
Returns aggregations (counts + health rollups).
|
||
|
||
`GET /api/resources/k8s/namespaces?cluster=<clusterName>`
|
||
Returns namespace-level rollups (pods + deployments) for a Kubernetes cluster. Requires `monitoring:read`.
|
||
```json
|
||
{
|
||
"cluster": "prod-k8s",
|
||
"data": [
|
||
{
|
||
"namespace": "default",
|
||
"pods": { "total": 12, "online": 10, "warning": 2, "offline": 0, "unknown": 0 },
|
||
"deployments": { "total": 3, "online": 3, "warning": 0, "offline": 0, "unknown": 0 }
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
`GET /api/resources/{id}`
|
||
Fetch a single resource by ID.
|
||
|
||
`GET /api/resources/{id}/children`
|
||
Returns child resources for the parent ID.
|
||
|
||
`GET /api/resources/{id}/metrics`
|
||
Returns the resource metrics payload.
|
||
|
||
`POST /api/resources/{id}/link`
|
||
Manually link two resources.
|
||
```json
|
||
{ "targetId": "resource-id", "reason": "optional note" }
|
||
```
|
||
|
||
`POST /api/resources/{id}/unlink`
|
||
Manually unlink two resources.
|
||
```json
|
||
{ "targetId": "resource-id", "reason": "optional note" }
|
||
```
|
||
|
||
`POST /api/resources/{id}/report-merge`
|
||
Report an incorrect merge (creates exclusions).
|
||
```json
|
||
{ "sources": ["proxmox", "agent"], "notes": "optional note" }
|
||
```
|
||
|
||
### Fleet Connections
|
||
`GET /api/connections`
|
||
Returns the canonical fleet connections ledger with per-row fleet-governance state. Requires admin access with `settings:read`.
|
||
|
||
The payload is the source of truth for enrollment, liveness, version drift, adapter health, config rollout, credential posture, update posture, and remote-control posture. Consumers must not rebuild those states from provider-specific config stores or display labels.
|
||
|
||
CLI adapter:
|
||
```bash
|
||
PULSE_API_TOKEN=your-token pulse fleet connections \
|
||
--api-url http://localhost:7655
|
||
```
|
||
|
||
### Unified Action Planning
|
||
`POST /api/actions/plan`
|
||
Returns the deterministic pre-execution plan for a capability advertised on a unified resource. Requires `ai:execute`.
|
||
|
||
This endpoint is API-first and plan-only: it resolves the resource from the unified registry, verifies the requested capability and parameter schema, returns approval policy, blast radius, stale-plan hashes, and preflight checks, and does not approve or execute anything.
|
||
|
||
`POST /api/actions/{id}/decision`
|
||
Records an explicit `approved` or `rejected` decision for a persisted `pending_approval` action. It does not execute the action.
|
||
|
||
`POST /api/actions/{id}/execute`
|
||
Starts execution only for an approved action or an approval-free executable plan, records `executing` before dispatch, and records the terminal result afterward. Dry-run-only plans are rejected and cannot be executed through this endpoint.
|
||
|
||
CLI adapter:
|
||
```bash
|
||
PULSE_API_TOKEN=your-token pulse actions capabilities \
|
||
--api-url http://localhost:7655 \
|
||
--resource-id vm:42
|
||
|
||
PULSE_API_TOKEN=your-token pulse actions plan \
|
||
--api-url http://localhost:7655 \
|
||
--request-id agent-run-123 \
|
||
--resource-id vm:42 \
|
||
--capability restart \
|
||
--param mode=graceful \
|
||
--reason "Recover after confirmed outage" \
|
||
--requested-by agent:oncall-helper
|
||
|
||
PULSE_API_TOKEN=your-token pulse actions decide \
|
||
--api-url http://localhost:7655 \
|
||
--action-id act_... \
|
||
--outcome approved \
|
||
--reason "Inside maintenance window"
|
||
|
||
PULSE_API_TOKEN=your-token pulse actions execute \
|
||
--api-url http://localhost:7655 \
|
||
--action-id act_... \
|
||
--reason "Execute approved recovery"
|
||
|
||
PULSE_API_TOKEN=your-token pulse actions audit \
|
||
--api-url http://localhost:7655 \
|
||
--resource-id vm:42 \
|
||
--limit 10
|
||
|
||
PULSE_API_TOKEN=your-token pulse actions events \
|
||
--api-url http://localhost:7655 \
|
||
--action-id act_...
|
||
```
|
||
|
||
Request:
|
||
```json
|
||
{
|
||
"requestId": "agent-run-123",
|
||
"resourceId": "vm:42",
|
||
"capabilityName": "restart",
|
||
"params": { "mode": "graceful" },
|
||
"reason": "Recover after confirmed outage",
|
||
"requestedBy": "agent:oncall-helper"
|
||
}
|
||
```
|
||
|
||
Response:
|
||
```json
|
||
{
|
||
"actionId": "act_...",
|
||
"requestId": "agent-run-123",
|
||
"allowed": true,
|
||
"requiresApproval": true,
|
||
"approvalPolicy": "admin",
|
||
"predictedBlastRadius": ["vm:42", "node-1"],
|
||
"rollbackAvailable": false,
|
||
"message": "Plan created for restart on web-42. Execution requires admin approval and is not performed by this endpoint.",
|
||
"plannedAt": "2026-05-03T10:00:00Z",
|
||
"expiresAt": "2026-05-03T10:05:00Z",
|
||
"resourceVersion": "resource:sha256:...",
|
||
"policyVersion": "policy:sha256:...",
|
||
"planHash": "sha256:...",
|
||
"preflight": {
|
||
"target": "vm:42",
|
||
"currentState": "web-42 is warning",
|
||
"intendedChange": "Restart the VM",
|
||
"dryRunAvailable": false,
|
||
"dryRunSummary": "No provider-supported dry run is advertised for this capability.",
|
||
"safetyChecks": [
|
||
"Resource was resolved from the unified resource registry.",
|
||
"Capability is advertised by the resource contract.",
|
||
"This endpoint plans only; it does not approve or execute the action.",
|
||
"Execution requires admin approval."
|
||
],
|
||
"verificationSteps": [
|
||
"Refresh the resource and confirm the expected state after execution.",
|
||
"Review /api/audit/actions/{actionId}/events for lifecycle evidence."
|
||
],
|
||
"generatedAt": "2026-05-03T10:00:00Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
### Resource Metadata
|
||
User notes, tags, and custom URLs for resources.
|
||
|
||
- `GET /api/agents/metadata` (admin or `monitoring:read`)
|
||
- `GET /api/agents/metadata/{agentId}` (admin or `monitoring:read`)
|
||
- `PUT /api/agents/metadata/{agentId}` (admin or `monitoring:write`)
|
||
- `DELETE /api/agents/metadata/{agentId}` (admin or `monitoring:write`)
|
||
|
||
- `GET /api/guests/metadata` (admin or `monitoring:read`)
|
||
- `GET /api/guests/metadata/{guestId}` (admin or `monitoring:read`)
|
||
- `PUT /api/guests/metadata/{guestId}` (admin or `monitoring:write`)
|
||
- `DELETE /api/guests/metadata/{guestId}` (admin or `monitoring:write`)
|
||
|
||
- `GET /api/docker/metadata` (admin or `monitoring:read`)
|
||
- `GET /api/docker/metadata/{containerId}` (admin or `monitoring:read`)
|
||
- `PUT /api/docker/metadata/{containerId}` (admin or `monitoring:write`)
|
||
- `DELETE /api/docker/metadata/{containerId}` (admin or `monitoring:write`)
|
||
|
||
- `GET /api/docker/runtimes/metadata` (admin or `monitoring:read`)
|
||
- `GET /api/docker/runtimes/metadata/{runtimeId}` (admin or `monitoring:read`)
|
||
- `PUT /api/docker/runtimes/metadata/{runtimeId}` (admin or `monitoring:write`)
|
||
- `DELETE /api/docker/runtimes/metadata/{runtimeId}` (admin or `monitoring:write`)
|
||
|
||
### Version Info
|
||
`GET /api/version`
|
||
Returns version, build time, and update status.
|
||
Example response:
|
||
```json
|
||
{
|
||
"version": "6.0.0",
|
||
"buildTime": "2026-02-21T00:00:00Z",
|
||
"channel": "stable",
|
||
"deploymentType": "systemd",
|
||
"updateAvailable": false,
|
||
"latestVersion": "6.0.0"
|
||
}
|
||
```
|
||
Version fields are returned as plain semantic versions (no leading `v`).
|
||
|
||
---
|
||
|
||
## 🖥️ Nodes & Config
|
||
|
||
### Public Config
|
||
`GET /api/config`
|
||
Returns a small public config payload (update channel, auto-update enabled).
|
||
|
||
### List Nodes
|
||
`GET /api/config/nodes`
|
||
|
||
### Add Node
|
||
`POST /api/config/nodes`
|
||
```json
|
||
{
|
||
"type": "pve",
|
||
"name": "Proxmox 1",
|
||
"host": "https://198.51.100.10:8006",
|
||
"user": "root@pam",
|
||
"password": "password"
|
||
}
|
||
```
|
||
|
||
### Test Connection
|
||
`POST /api/config/nodes/test-connection`
|
||
Validate credentials before saving.
|
||
|
||
### Test Node Config (Validation Only)
|
||
`POST /api/config/nodes/test-config`
|
||
Validates node config without saving.
|
||
|
||
### Update Node
|
||
`PUT /api/config/nodes/{id}`
|
||
|
||
### Delete Node
|
||
`DELETE /api/config/nodes/{id}`
|
||
|
||
### Test Node (Legacy)
|
||
`POST /api/config/nodes/{id}/test`
|
||
|
||
### Refresh Cluster Nodes
|
||
`POST /api/config/nodes/{id}/refresh-cluster`
|
||
|
||
### Export Configuration
|
||
`POST /api/config/export` (instance admin for the default organization, tenant
|
||
manager for a selected tenant, or an API token bound to the selected
|
||
organization with `settings:read`)
|
||
Request body:
|
||
```json
|
||
{ "passphrase": "use-a-strong-passphrase" }
|
||
```
|
||
Returns an encrypted export bundle in `data`. Passphrases must be at least 12 characters.
|
||
|
||
### Import Configuration
|
||
`POST /api/config/import` (instance admin for the default organization, tenant
|
||
manager for a selected tenant, or an API token bound to the selected
|
||
organization with `settings:write`)
|
||
Request body:
|
||
```json
|
||
{
|
||
"data": "<exported-bundle>",
|
||
"passphrase": "use-a-strong-passphrase"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🧭 Setup & Discovery
|
||
|
||
### Setup Script (Public)
|
||
`GET /api/setup-script`
|
||
Returns the Proxmox/PBS setup script as a shell-script download. Accepts an
|
||
optional temporary setup token in the `setup_token` query for embedded
|
||
non-interactive bootstrap; otherwise the script prompts for the one-time setup
|
||
token at runtime. Canonical callers must send a supported `type` of `pve` or
|
||
`pbs` plus non-empty `host` and `pulse_url`; the route no longer generates
|
||
placeholder-host scripts for later repair or reconstructs Pulse identity from
|
||
the request origin. The route now shares the same canonical type boundary as
|
||
`/api/setup-script-url`, rejecting unsupported node types instead of treating
|
||
unknown values as PBS, and it normalizes the supplied `host` before script
|
||
generation so downloaded artifacts and rerun URLs preserve the same canonical
|
||
node identity as the bootstrap response. The optional `backup_perms=true`
|
||
query is supported only for `type=pve`.
|
||
|
||
### Setup Script URL
|
||
`POST /api/setup-script-url` (auth)
|
||
Generates a one-time setup token and URL for `/api/setup-script`.
|
||
Canonical callers must send a supported `type` of `pve` or `pbs` plus a
|
||
non-empty `host`; the backend normalizes that host before minting the setup
|
||
token and now returns the canonical bootstrap identity back in the response as
|
||
`type`, `host`, `url`, `downloadURL`, `scriptFileName`, `command`, `commandWithEnv`,
|
||
`commandWithoutEnv`, `setupToken`, `tokenHint`, and `expires`. The returned
|
||
commands are canonical root-or-sudo `curl -fsSL` bootstrap commands for the
|
||
generated setup script, while `url`, `downloadURL`, and `scriptFileName` are
|
||
the runtime-owned artifact metadata used by copy and manual download surfaces.
|
||
The request body is a single canonical JSON object only; unknown fields and trailing JSON are
|
||
rejected as invalid request shape, and `backupPerms:true` is supported only for
|
||
`type:"pve"`. This route stays on the normal
|
||
authenticated bootstrap boundary: when Pulse auth is already configured it
|
||
requires a real authenticated session or API token, and setup tokens do not
|
||
authorize the request itself. Pulse-managed Proxmox monitor-token names on the
|
||
setup/bootstrap path derive from the canonical Pulse endpoint, not request-local
|
||
host fallbacks, so setup-script and turnkey node-add flows stay on one
|
||
deterministic `pulse-<canonical-scope-slug>` identity per Pulse instance.
|
||
`setupToken` remains bootstrap transport data for `/api/setup-script` and
|
||
`/api/auto-register`, while `tokenHint` is the operator-facing display field
|
||
for quick-setup surfaces and must stay masked instead of exposing the full
|
||
one-time token in UI copy. Shared frontend consumers may validate
|
||
`setupToken`, but they should not retain or display it once the returned
|
||
bootstrap artifact and `tokenHint` are available; visible quick-setup previews
|
||
should use the non-secret `commandWithoutEnv` form while copy actions keep
|
||
using the token-bearing `commandWithEnv` artifact, and manual download flows
|
||
should use the token-bearing `downloadURL` artifact instead of rebuilding a
|
||
plain setup-script URL from non-secret preview state. Non-frontend bootstrap
|
||
consumers such as the runtime-side Unified Agent bootstrap flow and shell installer must fail closed on that
|
||
same full artifact contract too, rejecting missing or mismatched
|
||
`downloadURL`, `tokenHint`, or expired `expires` values instead of accepting a
|
||
reduced setup-token-only response shape.
|
||
|
||
### Auto-Register (Public)
|
||
`POST /api/auto-register`
|
||
Registers a node through the canonical `/api/auto-register` contract using a temporary
|
||
setup token carried in the JSON `authToken` field. Canonical callers must send
|
||
a supported `type` of `pve` or `pbs`, an explicit `source` marker of `agent` or
|
||
`script`, a canonical Pulse-managed `tokenId` in the form
|
||
`pulse-monitor@{pve|pbs}!pulse-<canonical-scope-slug>` matching the requested
|
||
type, an explicit `serverName`, and missing-token requests now fail with
|
||
`Pulse setup token required`. Incomplete token completion requests now fail
|
||
with `tokenId and tokenValue must be provided together`, and other missing
|
||
canonical request fields fail with explicit `Missing required canonical
|
||
auto-register fields: ...` guidance.
|
||
Success responses now carry the canonical stored identity and caller boundary
|
||
back to the installer or runtime-side Unified Agent:
|
||
`{"status":"success","action":"use_token","type":"pve|pbs","source":"agent|script","host":"https://...","nodeId":"<stored-name>","nodeName":"<stored-name>",...}`.
|
||
|
||
### Agent Install Command
|
||
`POST /api/agent-install-command` (auth)
|
||
Generates an API token and install command for agent-based Proxmox setup.
|
||
|
||
### Discovery
|
||
`GET /api/discover` (auth)
|
||
Runs network discovery.
|
||
|
||
### AI Discovery (Service Discovery)
|
||
Service discovery is used by Pulse Assistant and the UI to inventory web services and enrich links.
|
||
|
||
- `GET /api/discovery` (list summaries)
|
||
- `GET /api/discovery/status`
|
||
- `PUT /api/discovery/settings` (admin, `settings:write`)
|
||
- `GET /api/discovery/type/{type}`
|
||
- `GET /api/discovery/agent/{agentId}`
|
||
- `GET /api/discovery/{type}/{targetId}/{resourceId}`
|
||
- `POST /api/discovery/{type}/{targetId}/{resourceId}` (trigger discovery, optional `force`)
|
||
- `DELETE /api/discovery/{type}/{targetId}/{resourceId}`
|
||
- `GET /api/discovery/{type}/{targetId}/{resourceId}/progress`
|
||
- `PUT /api/discovery/{type}/{targetId}/{resourceId}/notes`
|
||
|
||
### Test Notification
|
||
`POST /api/test-notification` (auth)
|
||
Broadcasts a WebSocket test event.
|
||
|
||
---
|
||
|
||
## 📊 Metrics & Charts
|
||
|
||
### Chart Data
|
||
`GET /api/charts?range=1h`
|
||
Returns time-series data for CPU, Memory, and Storage.
|
||
**Ranges**: `5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `24h`, `7d`
|
||
|
||
### Storage Charts
|
||
`GET /api/storage-charts`
|
||
Returns storage chart data.
|
||
|
||
### Storage Stats
|
||
`GET /api/storage/`
|
||
Detailed storage usage per node and pool.
|
||
|
||
### Recovery (formerly Backups / Snapshots)
|
||
Pulse v6 uses the recovery API to provide a platform-agnostic view of backup and snapshot artifacts.
|
||
The endpoints below carry the provider-neutral contract covering subjects,
|
||
points, rollups, posture, and filter semantics.
|
||
|
||
- `GET /api/recovery/points`
|
||
- Query params:
|
||
- Core filters: `provider`, `kind`, `mode`, `outcome`, `subjectResourceId`, `rollupId`
|
||
- Time window: `from` (RFC3339), `to` (RFC3339)
|
||
- Paging: `page`, `limit`
|
||
- Normalized filters: `q`, `cluster`, `node`, `namespace`, `scope=workload`, `verification` (`verified` | `unverified` | `unknown`)
|
||
- `GET /api/recovery/rollups`
|
||
- Query params: `provider`, `kind`, `mode`, `outcome`, `subjectResourceId`, `rollupId`, `from` (RFC3339), `to` (RFC3339), `page`, `limit`
|
||
- `GET /api/recovery/postures`
|
||
- Returns server-derived per-resource protection posture and provider evidence quality.
|
||
- Query params: repeated `resourceId` values (maximum 200), `state` (`protected` | `attention` | `unprotected` | `unknown`), `page`, `limit` (maximum 200)
|
||
- Batch clients must make one bounded request per 200 resource ids, never one request per table row.
|
||
- Unknown identity, permission, history, or collection completeness remains `unknown`; clients must not infer a healthier state from raw backup or snapshot artifacts.
|
||
- `GET /api/recovery/series`
|
||
- Returns per-day counts for the activity chart.
|
||
- Query params: same filters as `/api/recovery/points` (except paging), plus `tzOffsetMinutes` (integer; UTC offset minutes for day bucketing)
|
||
- `GET /api/recovery/facets`
|
||
- Returns distinct filter values (clusters/nodes/namespaces) and capability flags (size/verification/entity id present).
|
||
- Query params: same filters as `/api/recovery/points` (except paging)
|
||
|
||
---
|
||
|
||
## 🔔 Notifications
|
||
|
||
### Send Test Notification
|
||
`POST /api/notifications/test` (admin)
|
||
Triggers a test alert to all configured channels.
|
||
|
||
### Email, Apprise, and Webhooks
|
||
- `GET /api/notifications/email` (admin)
|
||
- `PUT /api/notifications/email` (admin)
|
||
- `GET /api/notifications/apprise` (admin)
|
||
- `PUT /api/notifications/apprise` (admin)
|
||
- `GET /api/notifications/webhooks` (admin)
|
||
- `POST /api/notifications/webhooks` (admin)
|
||
- `PUT /api/notifications/webhooks/<id>` (admin)
|
||
- `DELETE /api/notifications/webhooks/<id>` (admin)
|
||
- `POST /api/notifications/webhooks/test` (admin)
|
||
- `GET /api/notifications/webhook-templates` (admin)
|
||
- `GET /api/notifications/webhook-history` (admin)
|
||
- `GET /api/notifications/email-providers` (admin)
|
||
|
||
Email and webhook configurations accept optional `tagFilter` (an array of
|
||
resource-tag strings) and `tagFilterMode` (`"all"` or `"any"`). An omitted
|
||
field is preserved on update; an empty `tagFilter` clears routing and restores
|
||
delivery for all resources.
|
||
|
||
- `GET /api/notifications/health` (admin)
|
||
- Queue health is `degraded` whenever any retained `failed` or `dlq`
|
||
delivery exists, and `unavailable` when queue state cannot be read.
|
||
Recoverable failed attempts that returned to `pending` for retry do not
|
||
degrade health.
|
||
- `queue.attention_required` is the retained terminal-failure count.
|
||
`reason_codes` identifies failed and/or dead-letter state without exposing
|
||
notification content. Counts are retention-bounded: sent, failed, and
|
||
cancelled rows are retained for 7 days; dead-letter rows for 30 days.
|
||
|
||
### Audit Webhooks (Pro)
|
||
- `GET /api/admin/webhooks/audit` (admin, `settings:read`)
|
||
- `POST /api/admin/webhooks/audit` (admin, `settings:write`)
|
||
- Body: `{ "urls": ["https://..."] }`
|
||
- Strict JSON contract: unknown fields and trailing payload are rejected.
|
||
- Maximum `20` webhook URLs per update request.
|
||
- URLs are normalized (trimmed) and duplicate entries are ignored.
|
||
- Endpoint fails closed if URL validation runtime is unavailable.
|
||
|
||
### Advanced Reporting (Pro)
|
||
- `GET /api/admin/reports/catalog` (admin, `settings:read`)
|
||
- Returns the canonical reporting catalog for the settings surface, including locked-state teaser copy, enabled-surface guidance copy, performance-report options, canonical single-report filename subject, canonical fallback filename date style, and the nested VM inventory export definition.
|
||
- Metadata route: readable without the `advanced_reporting` feature so locked admin surfaces can render the same reporting definition before upsell.
|
||
- `GET /api/admin/reports/generate` (admin, `settings:read`)
|
||
- Query params: `format` (pdf/csv, default `pdf`), `resourceType`, `resourceId`, `metricType` (optional), `start`/`end` (RFC3339, optional; defaults to last 24h), `title` (optional)
|
||
- If `title` is omitted, the backend applies the canonical default title for that resource report.
|
||
- `POST /api/admin/reports/generate-multi` (admin, `settings:read`)
|
||
- Body fields: `resources` (1-50 entries of `{resourceType,resourceId}`), `format`, `metricType` (optional), `start`/`end` (RFC3339, optional; defaults to last 24h), `title` (optional)
|
||
- If `title` is omitted, the backend applies the canonical default fleet report title.
|
||
- `GET /api/admin/reports/inventory/vms/export` (admin, `settings:read`)
|
||
- Query params: `format` (`csv` only; optional and defaults to `csv`)
|
||
- Exports the current fleet-wide VM inventory as spreadsheet-friendly CSV using the canonical runtime model.
|
||
|
||
Validation and limits:
|
||
- `start` and `end` must be RFC3339 when provided.
|
||
- Malformed `start`/`end` values, `end` not strictly after `start`, or report windows over 366 days return `400 invalid_time_range`.
|
||
- `metricType` must match `[a-zA-Z0-9._:-]+` and be <= 64 chars, otherwise `400 invalid_metric_type`.
|
||
- `title` must be <= 256 chars, otherwise `400 invalid_title`.
|
||
- Multi-report body max size is 1MB; oversized payloads return `400 body_too_large`.
|
||
- Multi-report bodies reject trailing payload and unknown JSON fields with `400 invalid_body`.
|
||
- VM inventory export only accepts `csv`.
|
||
|
||
Common reporting error codes:
|
||
- `invalid_format`, `missing_params`, `invalid_resource_type`, `invalid_resource_id`
|
||
- `invalid_metric_type`, `invalid_title`, `invalid_time_range`
|
||
- `no_resources`, `too_many_resources`, `body_too_large`, `invalid_body`
|
||
|
||
### Queue and Dead-Letter Tools
|
||
- `GET /api/notifications/delivery-log?limit=200` (admin, `settings:read`)
|
||
- Returns recent per-attempt delivery evidence with destination identifiers,
|
||
alert identifiers, outcomes, timestamps, failure classes, and redacted error
|
||
text. Completed attempts are retained for 7 days; dead-letter attempts are
|
||
retained for 30 days, so the response reports both windows explicitly.
|
||
- `limit` defaults to 50 and is capped at 200.
|
||
- `GET /api/notifications/queue/stats` (admin)
|
||
- Returns counts for all rows still retained by the queue. Status counts have
|
||
different retention windows and are not a delivery rate or lifetime total.
|
||
- `GET /api/notifications/dlq` (admin)
|
||
- `POST /api/notifications/dlq/retry` (admin)
|
||
- `POST /api/notifications/dlq/delete` (admin)
|
||
- `POST /api/notifications/terminal-failures/retry` (admin, `settings:write`)
|
||
- Returns every retained `failed` or `dlq` delivery to `pending` with a fresh
|
||
retry budget. Existing per-attempt delivery history is preserved.
|
||
- `POST /api/notifications/terminal-failures/dismiss` (admin, `settings:write`)
|
||
- Marks every retained terminal delivery `cancelled`, clearing the active
|
||
queue-health warning without deleting delivery history.
|
||
|
||
---
|
||
|
||
## 🚨 Alerts
|
||
|
||
Alert configuration and history (requires `monitoring:read`/`monitoring:write`).
|
||
|
||
- `GET /api/alerts/config`
|
||
- `PUT /api/alerts/config`
|
||
- `GET /api/alerts/deadman/config` — returns only whether an external watchdog
|
||
is configured; `pingUrl` is `***REDACTED***` when present and never returns
|
||
the credential-bearing URL
|
||
- `PUT /api/alerts/deadman/config` — body `{ "pingUrl": "..." }`; accepts a
|
||
healthchecks-compatible base success URL, `***REDACTED***` to preserve the
|
||
saved value, or an empty string to remove it
|
||
- `GET /api/alerts/deadman/status` — live watchdog health, monitor-loop
|
||
progress, sanitized delivery failure state, and the most recent restart
|
||
interruption; never includes the URL or endpoint fingerprint
|
||
- `POST /api/alerts/activate`
|
||
- `GET /api/alerts/active`
|
||
- `GET /api/alerts/delivery-diagnosis?alertIdentifier=<alert-id>` (omit `alertIdentifier` to get the diagnosis array for every active alert)
|
||
- `GET /api/alerts/events?alertIdentifier=<alert-id>&type=<event-type,...>&since=<RFC3339>&limit=<n>` — append-only alert event log: lifecycle transitions and notification decisions, including suppressions with reasons; all parameters optional, newest first
|
||
- `GET /api/alerts/history`
|
||
- `DELETE /api/alerts/history`
|
||
- `GET /api/alerts/incidents`
|
||
- `POST /api/alerts/incidents/note`
|
||
- `POST /api/alerts/bulk/acknowledge`
|
||
- `POST /api/alerts/bulk/clear`
|
||
- `POST /api/alerts/acknowledge` (body: `{ "alertIdentifier": "alert-id" }`)
|
||
- `POST /api/alerts/unacknowledge` (body: `{ "alertIdentifier": "alert-id" }`)
|
||
- `POST /api/alerts/snooze` (body: `{ "alertIdentifier": "alert-id", "until": "RFC3339 timestamp" }`; pauses delivery and escalation for up to 30 days while monitoring continues)
|
||
- `POST /api/alerts/unsnooze` (body: `{ "alertIdentifier": "alert-id" }`; resumes normal policy without resolving the incident)
|
||
- `POST /api/alerts/clear` (body: `{ "id": "alert-id" }`)
|
||
|
||
---
|
||
|
||
## 🛡️ Security
|
||
|
||
### Security Status
|
||
`GET /api/security/status`
|
||
Returns authentication status, proxy auth state, and security posture flags.
|
||
|
||
### Change Password
|
||
`POST /api/security/change-password`
|
||
```json
|
||
{ "currentPassword": "old-pass", "newPassword": "new-pass" }
|
||
```
|
||
In Docker installs, the response includes a restart notice.
|
||
|
||
### List API Tokens
|
||
`GET /api/security/tokens`
|
||
|
||
### Create API Token
|
||
`POST /api/security/tokens`
|
||
```json
|
||
{ "name": "ansible-script", "scopes": ["monitoring:read"] }
|
||
```
|
||
|
||
### Edit API Token Scopes
|
||
`PATCH /api/security/tokens/<id>`
|
||
```json
|
||
{ "scopes": ["monitoring:read", "settings:read"] }
|
||
```
|
||
|
||
The `scopes` field is required and must contain at least one known scope.
|
||
Wildcard access (`"*"`) cannot be combined with other scopes. The update takes
|
||
effect on the token's next request without changing its ID, secret, expiry, or
|
||
organization bindings.
|
||
|
||
### Revoke Token
|
||
`DELETE /api/security/tokens/<id>`
|
||
|
||
### Recovery (Localhost or Recovery Token)
|
||
`POST /api/security/recovery`
|
||
Supports actions:
|
||
- `generate_token` (localhost only)
|
||
- `disable_auth`
|
||
- `enable_auth`
|
||
|
||
`GET /api/security/recovery` returns recovery mode status.
|
||
|
||
### Reset Account Lockout (Admin)
|
||
`POST /api/security/reset-lockout`
|
||
```json
|
||
{ "identifier": "admin" }
|
||
```
|
||
Identifier can be a username or IP address.
|
||
|
||
### Regenerate API Token (Admin)
|
||
`POST /api/security/regenerate-token`
|
||
|
||
Returns a new raw token (shown once) and updates stored hashes:
|
||
```json
|
||
{
|
||
"success": true,
|
||
"token": "raw-token",
|
||
"deploymentType": "systemd",
|
||
"requiresRestart": false,
|
||
"message": "New API token generated and active immediately! Save this token - it won't be shown again."
|
||
}
|
||
|
||
---
|
||
|
||
## 🧾 Audit Log (Pro)
|
||
|
||
These endpoints require admin access and the `settings:read` scope. On Community, the list endpoint returns an empty set and `persistentLogging: false`.
|
||
|
||
### List Audit Events
|
||
`GET /api/audit?limit=100&event=login&user=admin&success=true&startTime=2024-01-01T00:00:00Z&endTime=2024-01-31T23:59:59Z`
|
||
|
||
Response:
|
||
```json
|
||
{
|
||
"events": [
|
||
{
|
||
"id": "6b3c9c3c-9a2f-4b3c-9a3b-3d0e8c5c5d45",
|
||
"timestamp": "2024-01-12T10:15:30Z",
|
||
"event": "login",
|
||
"user": "admin",
|
||
"ip": "198.51.100.10",
|
||
"path": "/api/login",
|
||
"success": true,
|
||
"details": "Successful login",
|
||
"signature": "..."
|
||
}
|
||
],
|
||
"total": 1,
|
||
"persistentLogging": true
|
||
}
|
||
```
|
||
|
||
### Verify Audit Event Signature
|
||
`GET /api/audit/<id>/verify`
|
||
|
||
Response:
|
||
```json
|
||
{
|
||
"available": true,
|
||
"verified": true,
|
||
"message": "Event signature verified"
|
||
}
|
||
```
|
||
|
||
### Validate API Token (Admin)
|
||
`POST /api/security/validate-token`
|
||
```json
|
||
{ "token": "raw-token" }
|
||
```
|
||
Returns:
|
||
```json
|
||
{ "valid": true, "message": "Token is valid" }
|
||
```
|
||
|
||
### Bootstrap Token Validation (Public)
|
||
`POST /api/security/validate-bootstrap-token`
|
||
|
||
Provide the token via header `X-Setup-Token` or JSON body:
|
||
```json
|
||
{ "token": "bootstrap-token" }
|
||
```
|
||
|
||
Returns `204 No Content` on success.
|
||
|
||
### Quick Security Setup (Public, bootstrap token required)
|
||
`POST /api/security/quick-setup`
|
||
|
||
Requires a valid bootstrap token (header `X-Setup-Token`) or an authenticated session.
|
||
|
||
```json
|
||
{
|
||
"username": "admin",
|
||
"password": "StrongPass!1",
|
||
"apiToken": "token",
|
||
"enableNotifications": false,
|
||
"darkMode": false,
|
||
"force": false,
|
||
"setupToken": "optional-bootstrap-token"
|
||
}
|
||
```
|
||
|
||
### Apply Security Restart (Systemd Only)
|
||
`POST /api/security/apply-restart`
|
||
Applies auth changes by restarting the service (systemd deployments only).
|
||
|
||
---
|
||
|
||
## ⚙️ System Settings
|
||
|
||
### Get Settings
|
||
`GET /api/system/settings`
|
||
Retrieve current system settings.
|
||
|
||
### Update Settings
|
||
`POST /api/system/settings/update`
|
||
Update system settings. Requires admin + `settings:write`.
|
||
|
||
### Legacy System Settings (Read Only)
|
||
`GET /api/config/system`
|
||
Legacy system settings endpoint (read-only).
|
||
|
||
### Toggle Mock Mode
|
||
`GET /api/system/mock-mode`
|
||
`POST /api/system/mock-mode`
|
||
`PUT /api/system/mock-mode`
|
||
Enable or disable mock data generation (dev/demo only).
|
||
|
||
### SSH Config (Temperature Monitoring)
|
||
`POST /api/system/ssh-config`
|
||
Writes the SSH config used for temperature collection (requires setup token or auth).
|
||
|
||
### Verify Temperature SSH
|
||
`POST /api/system/verify-temperature-ssh`
|
||
Tests SSH connectivity for temperature collection (requires setup token or auth).
|
||
|
||
### Scheduler Health
|
||
`GET /api/monitoring/scheduler/health`
|
||
Returns scheduler health, DLQ, and breaker status. Requires `monitoring:read`.
|
||
|
||
### Updates (Admin)
|
||
- `GET /api/updates/check`
|
||
- `POST /api/updates/apply`
|
||
- `GET /api/updates/status`
|
||
- `GET /api/updates/stream`
|
||
- `GET /api/updates/plan?version=X.Y.Z` (optional `channel`, accepts `v` prefix)
|
||
- `GET /api/updates/history`
|
||
- `GET /api/updates/history/entry?id=<event_id>`
|
||
|
||
### Infrastructure Updates
|
||
- `GET /api/infra-updates` (requires `monitoring:read`)
|
||
- `GET /api/infra-updates/summary` (requires `monitoring:read`)
|
||
- `POST /api/infra-updates/check` (requires `monitoring:write`)
|
||
- `GET /api/infra-updates/agent/{agentId}` (requires `monitoring:read`)
|
||
- `GET /api/infra-updates/{resourceId}` (requires `monitoring:read`)
|
||
|
||
### Diagnostics
|
||
- `GET /api/diagnostics` (auth)
|
||
- `POST /api/diagnostics/docker/prepare-token` (admin, `settings:write`)
|
||
|
||
The Docker migration token request accepts `agentId`, optional `tokenName`, and
|
||
optional `enableHost`. When `enableHost` is omitted, the generated token and
|
||
install command enable both host and Docker monitoring so the machine appears
|
||
in both Hosts and Docker. Set `enableHost` to `false` only for an intentional
|
||
workload-only agent; that mode receives Docker-report scope only.
|
||
|
||
### Logs (Admin)
|
||
- `GET /api/logs/stream` (server-sent stream)
|
||
- `GET /api/logs/download` (bundled logs)
|
||
- `GET /api/logs/level`
|
||
- `POST /api/logs/level` (set log level)
|
||
|
||
### Server Info
|
||
`GET /api/server/info`
|
||
Returns minimal server info for installer scripts.
|
||
|
||
---
|
||
|
||
## 🔑 OIDC / SSO
|
||
|
||
### Provider Login
|
||
- `GET /api/oidc/{providerID}/login`
|
||
- `GET /api/oidc/{providerID}/callback`
|
||
|
||
OIDC and SAML configuration is managed via SSO providers.
|
||
|
||
### SSO Provider Management (Community)
|
||
- `GET /api/security/sso/providers` (admin)
|
||
- `POST /api/security/sso/providers` (admin)
|
||
- `GET /api/security/sso/providers/{id}` (admin)
|
||
- `PUT /api/security/sso/providers/{id}` (admin)
|
||
- `DELETE /api/security/sso/providers/{id}` (admin)
|
||
|
||
Provider mutation request contract:
|
||
- Max request body: 1MB.
|
||
- Strict JSON contract: unknown fields and trailing payload are rejected.
|
||
- Provider IDs must match server validation.
|
||
- OIDC and SAML providers are included with the Community SSO entitlement.
|
||
|
||
### SSO Test and Metadata Preview (Community)
|
||
- `POST /api/security/sso/providers/test` (admin)
|
||
- `POST /api/security/sso/providers/metadata/preview` (admin)
|
||
|
||
Test/preview request contract:
|
||
- Max request body: 32KB.
|
||
- Strict JSON contract: unknown fields and trailing payload are rejected.
|
||
- Common errors include `invalid_json`, `validation_error`, `rate_limited`, `body_too_large`.
|
||
|
||
---
|
||
|
||
## 💳 License (Relay / Pro / legacy Pro+ / Cloud)
|
||
|
||
### License Status (Admin)
|
||
`GET /api/license/status`
|
||
|
||
### License Features (Authenticated)
|
||
`GET /api/license/features`
|
||
|
||
### Activate License (Admin)
|
||
`POST /api/license/activate`
|
||
```json
|
||
{ "license_key": "PASTE_KEY_HERE" }
|
||
```
|
||
|
||
### Clear License (Admin)
|
||
`POST /api/license/clear`
|
||
|
||
---
|
||
|
||
## 👥 RBAC / Role Management (Pro)
|
||
|
||
Role-based access control endpoints for managing roles and user assignments. Requires admin access and the `rbac` license feature.
|
||
|
||
### List Roles
|
||
`GET /api/admin/roles`
|
||
Returns all defined roles.
|
||
|
||
### Create Role
|
||
`POST /api/admin/roles`
|
||
```json
|
||
{
|
||
"id": "operator",
|
||
"name": "Operator",
|
||
"description": "Can view and manage alerts",
|
||
"permissions": [
|
||
{ "action": "read", "resource": "alerts" },
|
||
{ "action": "write", "resource": "alerts" }
|
||
]
|
||
}
|
||
```
|
||
|
||
### Update Role
|
||
`PUT /api/admin/roles/{id}`
|
||
Update an existing role's name, description, or permissions.
|
||
|
||
### Delete Role
|
||
`DELETE /api/admin/roles/{id}`
|
||
|
||
### List Users
|
||
`GET /api/admin/users`
|
||
Returns all users with their role assignments and, when available, mutable SSO presentation fields (`displayName`, `email`, `providerType`, `providerId`, and `lastLoginAt`). The opaque `username` remains the stable authorization principal.
|
||
|
||
### Set User Roles
|
||
`PUT /api/admin/users/{username}/roles`
|
||
```json
|
||
{ "roleIds": ["operator", "viewer"] }
|
||
```
|
||
|
||
### Remove User Access
|
||
`DELETE /api/admin/users/{username}`
|
||
|
||
Deletes the Pulse RBAC identity and all assignments and revokes its active sessions. Administrators cannot remove their own current identity. This does not disable the upstream IdP account; a later authorized SSO login recreates the Pulse user record.
|
||
|
||
> **Note**: OIDC group-to-role mapping can automatically assign roles on login. See [OIDC.md](OIDC.md) for configuration.
|
||
|
||
---
|
||
|
||
## 🏢 Organizations (Enterprise)
|
||
|
||
Multi-tenant organization management. Requires `PULSE_MULTI_TENANT_ENABLED=true` and an Enterprise license with the `multi_tenant` feature. All endpoints require authentication.
|
||
|
||
See [MULTI_TENANT.md](MULTI_TENANT.md) for setup and architecture details.
|
||
|
||
### List Organizations
|
||
`GET /api/orgs` (requires `settings:read`)
|
||
Returns organizations accessible to the authenticated user.
|
||
|
||
### Create Organization
|
||
`POST /api/orgs` (requires `settings:write`, session auth only)
|
||
```json
|
||
{ "id": "acme-corp", "displayName": "Acme Corporation" }
|
||
```
|
||
The creator becomes the owner and first member. Organization IDs must be lowercase alphanumeric with hyphens, 3-64 characters.
|
||
|
||
### Get Organization
|
||
`GET /api/orgs/{id}` (requires `settings:read`)
|
||
Returns organization details. User must be a member.
|
||
|
||
### Update Organization
|
||
`PUT /api/orgs/{id}` (requires `settings:write`, session auth only)
|
||
```json
|
||
{ "displayName": "Updated Name" }
|
||
```
|
||
Admin or owner role required. The default organization cannot be updated.
|
||
|
||
### Delete Organization
|
||
`DELETE /api/orgs/{id}` (requires `settings:write`, session auth only)
|
||
Admin or owner role required. The default organization cannot be deleted.
|
||
|
||
### List Members
|
||
`GET /api/orgs/{id}/members` (requires `settings:read`)
|
||
Returns all members with their roles. User must be a member of the org.
|
||
|
||
### Add or Update Member
|
||
`POST /api/orgs/{id}/members` (requires `settings:write`, session auth only)
|
||
```json
|
||
{ "userId": "jane", "role": "editor" }
|
||
```
|
||
Roles: `owner`, `admin`, `editor`, `viewer`. Admin or owner role required. Setting role to `owner` transfers ownership (only current owner can do this). Default org members cannot be managed.
|
||
|
||
### Remove Member
|
||
`DELETE /api/orgs/{id}/members/{userId}` (requires `settings:write`, session auth only)
|
||
Admin or owner role required. The organization owner cannot be removed.
|
||
|
||
### List Outgoing Shares
|
||
`GET /api/orgs/{id}/shares` (requires `settings:read`)
|
||
Returns resources shared outbound from this organization to others.
|
||
|
||
### List Incoming Shares
|
||
`GET /api/orgs/{id}/shares/incoming` (requires `settings:read`)
|
||
Returns resources shared inbound to this organization from other organizations.
|
||
|
||
### Create Share
|
||
`POST /api/orgs/{id}/shares` (requires `settings:write`, session auth only)
|
||
```json
|
||
{
|
||
"targetOrgId": "partner-org",
|
||
"resourceType": "vm",
|
||
"resourceId": "vm-101",
|
||
"resourceName": "Web Server",
|
||
"accessRole": "viewer"
|
||
}
|
||
```
|
||
Share a resource with another organization. Valid resource types: `vm`, `container`, `agent`, `storage`, `pbs`, `pmg`. Access roles: `viewer`, `editor`, `admin`. Admin or owner role required on the source org.
|
||
|
||
### Delete Share
|
||
`DELETE /api/orgs/{id}/shares/{shareId}` (requires `settings:write`, session auth only)
|
||
Revoke a resource share. Admin or owner role required.
|
||
|
||
---
|
||
|
||
## 🤖 Pulse Intelligence
|
||
|
||
**Paid gating:** endpoints labeled with a paid plan require the relevant Relay, Pro, legacy Pro+, or Cloud capability and return `402 Payment Required` if the feature is not licensed.
|
||
|
||
### Get AI Settings
|
||
`GET /api/settings/ai`
|
||
Returns current AI configuration (providers, models, patrol status). Requires admin + `settings:read`.
|
||
|
||
### Update AI Settings
|
||
`PUT /api/settings/ai/update` (or `POST /api/settings/ai/update`)
|
||
Configure AI providers, API keys, and preferences. Requires admin + `settings:write`.
|
||
|
||
### List Models
|
||
`GET /api/ai/models`
|
||
Lists models available to the configured providers (queried live from provider APIs).
|
||
|
||
### Provider Tests (Admin)
|
||
- `POST /api/ai/test`
|
||
- `POST /api/ai/test/{provider}`
|
||
|
||
### Legacy Anthropic OAuth Cleanup
|
||
Anthropic subscription OAuth is unsupported. These routes remain only for
|
||
fail-closed compatibility and token cleanup:
|
||
- `POST /api/ai/oauth/start` (admin): returns `501` with `unsupported_anthropic_oauth`
|
||
- `POST /api/ai/oauth/exchange` (admin): returns `501` with `unsupported_anthropic_oauth`
|
||
- `GET /api/ai/oauth/callback` (public): redirects to settings with `ai_oauth_error=unsupported` unless the provider supplied a specific error
|
||
- `POST /api/ai/oauth/disconnect` (admin): clears stored legacy OAuth tokens
|
||
|
||
### Execute (Chat + Tools)
|
||
`POST /api/ai/execute`
|
||
Runs an AI request which may return tool calls, findings, or suggested actions.
|
||
|
||
### Execute (Streaming)
|
||
`POST /api/ai/execute/stream`
|
||
Streaming variant of execute (used by the UI for incremental responses).
|
||
|
||
### Assistant Chat & Sessions
|
||
- `GET /api/ai/status`
|
||
- `POST /api/ai/chat` (streaming)
|
||
- `GET /api/ai/sessions` returns session summaries; scoped Assistant handoffs may include a safe `handoff_summary` marker without model-only context text or command payloads.
|
||
- `POST /api/ai/sessions`
|
||
- `DELETE /api/ai/sessions/{id}`
|
||
- `GET /api/ai/sessions/{id}/messages`
|
||
- `POST /api/ai/sessions/{id}/abort`
|
||
- `POST /api/ai/sessions/{id}/summarize`
|
||
- `POST /api/ai/sessions/{id}/fork`
|
||
- Legacy OpenCode-style file-change routes (`GET /api/ai/sessions/{id}/diff`,
|
||
`POST /api/ai/sessions/{id}/revert`, `POST /api/ai/sessions/{id}/unrevert`)
|
||
return `501 Not Implemented`; Pulse Assistant sessions do not own file diffs
|
||
or file-level revert.
|
||
|
||
### Question Answers
|
||
- `POST /api/ai/question/{id}/answer`
|
||
|
||
### Kubernetes AI Analysis (Compatibility)
|
||
`POST /api/ai/kubernetes/analyze`
|
||
```json
|
||
{ "cluster_id": "cluster-id" }
|
||
```
|
||
Requires Pro, legacy Pro+, or Cloud with the `kubernetes_ai` feature enabled. This route remains
|
||
available for compatibility, but current v6 Pulse Pro marketing does not treat
|
||
Kubernetes-specific analysis as a standalone plan pillar.
|
||
|
||
### Alert Investigation (Pro)
|
||
`POST /api/ai/investigate-alert`
|
||
Runs a focused investigation for an alert payload (used by the UI).
|
||
|
||
### Patrol
|
||
- `GET /api/ai/patrol/digest`
|
||
- Returns the "what Patrol did for you" rollup for the last `days` days
|
||
(query `days`, 1–30, default 7): the window and whether retained run
|
||
history covers it, the effective Patrol mode, runs (total, scheduled,
|
||
event-triggered, manual, failed, checks, resources covered, last run),
|
||
findings (new, still open by severity, resolved, auto-resolved,
|
||
dismissed, suppressed), investigations by outcome, Patrol-origin actions
|
||
(proposed, approved, rejected, executed, verified, failed, pending),
|
||
alerts Patrol reviewed, and estimated model spend with a pricing-known
|
||
flag.
|
||
- Computed from records Pulse already retains (run history, the findings
|
||
store, canonical action audits, and usage cost events); nothing new is
|
||
persisted. Requires the `ai:execute` scope. Backs the Patrol page's
|
||
"This week" card; see `docs/PATROL_WEEKLY_DIGEST.md`.
|
||
- `GET /api/ai/patrol/attention`
|
||
- Returns the typed Patrol attention queue projected from canonical
|
||
operational lifecycle records. This is the active-count and queue source
|
||
used by both navigation and Patrol.
|
||
- Query params: `filter` (`active` | `open` | `acknowledged` | `suppressed` |
|
||
`stale_unknown` | `resolved` | `all`), `page` (minimum 1), and `limit`
|
||
(1–200).
|
||
- The response includes `data`, a lifecycle-wide `summary`, and bounded
|
||
pagination `meta`. Protection context is joined in one bounded batch, not
|
||
fetched per item.
|
||
- `GET /api/ai/patrol/attention/summary`
|
||
- Returns the canonical active, open, acknowledged, suppressed,
|
||
stale/unknown, and recent-resolved counts plus `calm`, `coverageState`, and
|
||
`evaluatedAt`.
|
||
- A lifecycle-read failure returns a typed unavailable error. It never
|
||
returns a synthetic zero or healthy state.
|
||
- `GET /api/ai/patrol/attention/{id}`
|
||
- Returns one attention item with its operational record, lifecycle
|
||
timeline, typed evidence, recommended next step, relationships, and
|
||
protection posture.
|
||
- `GET /api/ai/patrol/attention/{id}/evidence/{evidenceId}`
|
||
- Returns one exact retained evidence envelope with its current freshness.
|
||
- Returns `410 attention_evidence_detail_expired` when the operational
|
||
record still links the ID but the bounded detail has expired.
|
||
- `POST /api/ai/patrol/attention/{id}/acknowledge`
|
||
- `POST /api/ai/patrol/attention/{id}/unacknowledge`
|
||
- `POST /api/ai/patrol/attention/{id}/suppress`
|
||
- Body: `{ "reason": "...", "expiresAt": "<RFC3339>" }`.
|
||
- The expiry must be in the future and no more than 30 days away.
|
||
- `POST /api/ai/patrol/attention/{id}/unsuppress`
|
||
- `POST /api/ai/patrol/attention/{id}/actions/restart/plan`
|
||
- Creates or replays the one server-owned Docker restart plan attached to
|
||
this operational record and its exact evidence IDs.
|
||
- Requires the canonical action authorization, an eligible server-side
|
||
offer, and the Pulse Pro `ai_autofix` entitlement. Clients cannot supply
|
||
command authority or override the target.
|
||
- Attention reads require `monitoring:read`; lifecycle mutations require
|
||
`monitoring:write`. Action decision and execution use `/api/actions` and
|
||
retain their existing action-specific scopes.
|
||
- Attention IDs and evidence IDs are opaque and can contain slashes. Clients
|
||
must path-escape each ID.
|
||
- `GET /api/ai/patrol/autonomy`
|
||
- `PUT /api/ai/patrol/autonomy`
|
||
- `GET /api/ai/patrol/status`
|
||
- `GET /api/ai/patrol/findings`
|
||
- `DELETE /api/ai/patrol/findings` (clear all findings)
|
||
- `GET /api/ai/patrol/objectives`
|
||
- `POST /api/ai/patrol/objectives`
|
||
- `GET /api/ai/patrol/objectives/{id}`
|
||
- `PATCH /api/ai/patrol/objectives/{id}`
|
||
- `DELETE /api/ai/patrol/objectives/{id}?revision={revision}`
|
||
- Objective writes accept an outcome-oriented `brief`, optional
|
||
`optional_context`, and optional canonical `resource_ids`. `PATCH` also
|
||
accepts `status` (`active`, `paused`, or `archived`) and requires the
|
||
current `revision` in its JSON body.
|
||
- Responses include server-derived `coverage` (`covered`, `degraded`, or
|
||
`uncovered`) and observer lifecycle state. Clients cannot submit either
|
||
field or mark an objective covered. A saved objective remains uncovered
|
||
until core records a validated, installed read-only observer with a live
|
||
health lease.
|
||
- Reads and writes require `ai:execute`. Stale writes return
|
||
`409 patrol_objective_revision_conflict`.
|
||
- `GET /api/ai/patrol/history`
|
||
- `GET /api/ai/patrol/runs`
|
||
- `GET /api/ai/patrol/stream` (Pro)
|
||
- `POST /api/ai/patrol/run` (admin, Pro)
|
||
- `POST /api/ai/patrol/acknowledge` (Pro)
|
||
- `POST /api/ai/patrol/dismiss`
|
||
- `POST /api/ai/patrol/findings/note`
|
||
- `POST /api/ai/patrol/resolve`
|
||
- `POST /api/ai/patrol/snooze` (Pro)
|
||
- `POST /api/ai/patrol/suppress` (Pro)
|
||
- `GET /api/ai/patrol/suppressions` (Pro)
|
||
- `POST /api/ai/patrol/suppressions` (Pro)
|
||
- `DELETE /api/ai/patrol/suppressions/{id}` (Pro)
|
||
- `GET /api/ai/patrol/dismissed` (Pro)
|
||
|
||
### Findings & Investigations
|
||
- `GET /api/ai/unified/findings`
|
||
- `GET /api/ai/findings/{id}/investigation`
|
||
- `GET /api/ai/findings/{id}/investigation/messages`
|
||
- `POST /api/ai/findings/{id}/reinvestigate`
|
||
- `POST /api/ai/findings/{id}/reapprove` (Pro)
|
||
|
||
### Approvals & Command Execution (Pro)
|
||
- `GET /api/ai/approvals`
|
||
- `GET /api/ai/approvals/{id}`
|
||
- `POST /api/ai/approvals/{id}/approve`
|
||
- `POST /api/ai/approvals/{id}/deny`
|
||
- `POST /api/ai/run-command` (execute an approved command)
|
||
- `GET /api/ai/agents` (connected agents via `/api/agent/ws`)
|
||
|
||
### Remediation Plans (Pro)
|
||
- `GET /api/ai/remediation/plans`
|
||
- `GET /api/ai/remediation/plan?plan_id=<id>`
|
||
- `POST /api/ai/remediation/approve`
|
||
- `POST /api/ai/remediation/execute`
|
||
- `POST /api/ai/remediation/rollback`
|
||
|
||
Request bodies:
|
||
- `approve`: `{ "plan_id": "...", "approved_by": "api" }`
|
||
- `execute`: `{ "execution_id": "..." }`
|
||
- `rollback`: `{ "execution_id": "..." }`
|
||
|
||
### Intelligence & Forecasting
|
||
- `GET /api/ai/intelligence`
|
||
- `GET /api/ai/intelligence/patterns`
|
||
- `GET /api/ai/intelligence/predictions`
|
||
- `GET /api/ai/intelligence/correlations`
|
||
- `GET /api/ai/intelligence/changes` (canonical unified-resource timeline first, patrol-local memory fallback)
|
||
- `GET /api/ai/intelligence/baselines`
|
||
- `GET /api/ai/intelligence/remediations`
|
||
- `GET /api/ai/intelligence/anomalies`
|
||
- `GET /api/ai/intelligence/learning`
|
||
- `GET /api/ai/forecast` (params: `resource_id`, `metric`, optional `resource_name`, `horizon_hours`, `threshold`)
|
||
- `GET /api/ai/forecasts/overview` (params: `metric`, `horizon_hours`, `threshold`)
|
||
- `GET /api/ai/learning/preferences` (optional `resource_id`)
|
||
- `GET /api/ai/proxmox/events`
|
||
- `GET /api/ai/proxmox/correlations`
|
||
- `GET /api/ai/incidents` (optional `resource_id`, `limit`)
|
||
- `GET /api/ai/incidents/{resourceId}` (optional `limit`)
|
||
- `GET /api/ai/circuit/status`
|
||
|
||
### Knowledge Base
|
||
- `GET /api/ai/knowledge?guest_id=<id>`
|
||
- `POST /api/ai/knowledge/save`
|
||
- `POST /api/ai/knowledge/delete`
|
||
- `GET /api/ai/knowledge/export?guest_id=<id>`
|
||
- `POST /api/ai/knowledge/import`
|
||
- `POST /api/ai/knowledge/clear`
|
||
|
||
### Debug
|
||
- `GET /api/ai/debug/context` (admin)
|
||
|
||
### Cost Tracking
|
||
- `GET /api/ai/cost/summary`
|
||
- `GET /api/ai/patrol/cost-preview` (optional `model` as `provider:model`, `interval_minutes`; projects Patrol's 30-day cost for a model and schedule from Pulse's price table and the install's run history, with the per-run token assumption, 30-day spend against budget, and a recommended schedule)
|
||
- `GET /api/ai/patrol/model-guidance` (recommended / suggested / caution markers for the Patrol model pickers, plus this install's cached readiness pass)
|
||
- `POST /api/ai/cost/reset` (admin)
|
||
- `GET /api/ai/cost/export` (admin)
|
||
|
||
## 📈 Metrics Store
|
||
|
||
Auth required: `monitoring:read`.
|
||
|
||
### Store Stats
|
||
`GET /api/metrics-store/stats`
|
||
Returns stats for the persistent metrics store (SQLite-backed).
|
||
|
||
### History
|
||
`GET /api/metrics-store/history`
|
||
Returns historical metric series for a resource and time range.
|
||
|
||
Query params:
|
||
- `resourceType` (required): `node`, `vm`, `container`, `storage`, `dockerHost`, `dockerContainer`
|
||
- `resourceId` (required)
|
||
- `metric` (optional): `cpu`, `memory`, `disk`, etc. Omit for all metrics
|
||
- `range` (optional): `1h`, `6h`, `12h`, `24h`, `1d`, `7d`, `30d`, `90d` (default `24h`; duration strings also accepted)
|
||
- `maxPoints` (optional): Downsample to a target number of points
|
||
|
||
> **License**: Requests beyond Community's `7d` floor require the paid `long_term_metrics` entitlement. Relay unlocks `14d`, Pro and legacy Pro+ unlock `90d`, and requests beyond the active tier's limit return `402 Payment Required`.
|
||
> **Aliases**: `guest` (VM/LXC) and `docker` (Docker container) are accepted, but persistent store data uses the canonical types above.
|
||
|
||
---
|
||
|
||
## 🤖 Agent Endpoints
|
||
|
||
### Unified Agent (Recommended)
|
||
`GET /download/pulse-agent`
|
||
Downloads the unified agent binary. Without `arch`, Pulse serves the local binary on the server host.
|
||
|
||
Optional query:
|
||
- `?arch=linux-amd64` (supported: `linux-amd64`, `linux-arm64`, `linux-armv7`, `linux-armv6`, `linux-386`, `darwin-amd64`, `darwin-arm64`, `freebsd-amd64`, `freebsd-arm64`, `windows-amd64`, `windows-arm64`, `windows-386`)
|
||
|
||
The response includes `X-Checksum-Sha256` for verification.
|
||
|
||
The unified agent combines host, Docker, and Kubernetes monitoring. Use `--enable-docker` or `--enable-kubernetes` to enable additional metrics.
|
||
|
||
See [UNIFIED_AGENT.md](UNIFIED_AGENT.md) for installation instructions.
|
||
|
||
### Agent Version
|
||
`GET /api/agent/version`
|
||
Returns the current server version for agent update checks.
|
||
|
||
### Agent Fleet Diagnostics
|
||
`GET /api/agents/diagnostics` (admin, `settings:read`)
|
||
Returns read-only fleet triage for reported host, Docker / Podman, and Kubernetes agents, including liveness, version drift, profile deployment drift, identity-split evidence, and supported repair handoff hints. It does not enqueue remote actions.
|
||
|
||
### Unified Agent Installer Script
|
||
`GET /install.sh`
|
||
Serves the universal `install.sh` used to install `pulse-agent` on target machines.
|
||
|
||
### Unified Agent Installer (Windows)
|
||
`GET /install.ps1`
|
||
Serves the PowerShell installer for Windows.
|
||
|
||
### Submit Reports
|
||
`POST /api/agents/agent/report` - Agent metrics
|
||
`POST /api/agents/docker/report` - Docker container metrics
|
||
`POST /api/agents/kubernetes/report` - Kubernetes cluster metrics
|
||
|
||
### Agent Management
|
||
`GET /api/agents/agent/lookup?id=<agent_id>`
|
||
`GET /api/agents/agent/lookup?hostname=<hostname>`
|
||
Looks up an agent by ID or hostname/display name. Requires `agent:report`.
|
||
|
||
`POST /api/agents/agent/uninstall`
|
||
Agent self-unregister during uninstall. Requires `agent:report`.
|
||
|
||
`POST /api/agents/agent/unlink` (admin, `agent:manage`)
|
||
Unlinks an agent from a node.
|
||
|
||
`DELETE /api/agents/agent/{agent_id}` (admin, `agent:manage`)
|
||
Removes an agent from state.
|
||
|
||
### Agent Linking (Admin)
|
||
- `POST /api/agents/agent/link` (admin, `agent:manage`)
|
||
- `POST /api/agents/agent/unlink` (admin, `agent:manage`)
|
||
|
||
### Agent Remote Config
|
||
`GET /api/agents/agent/{agent_id}/config`
|
||
Returns the server-side config payload for an agent (used by remote config and debugging). Requires `agent:config:read`.
|
||
The `config` object includes the merged desired settings, command enablement
|
||
decision, and desired-config metadata. When signing is configured, the
|
||
signature remains backward-compatible with legacy agents: it covers
|
||
`agentId`, `commandsEnabled`, `settings`, `issuedAt`, and `expiresAt`.
|
||
`desiredConfig` is computed from the signed command decision plus the
|
||
agent-applied settings keys and returned as tamper-evident metadata for newer
|
||
clients to recompute and compare.
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"agentId": "agent-123",
|
||
"config": {
|
||
"commandsEnabled": true,
|
||
"settings": {
|
||
"enable_docker": true
|
||
},
|
||
"desiredConfig": {
|
||
"version": "host-agent-config/v1",
|
||
"hash": "sha256:..."
|
||
},
|
||
"issuedAt": "2026-05-13T17:00:00Z",
|
||
"expiresAt": "2026-05-13T17:15:00Z",
|
||
"signature": "..."
|
||
}
|
||
}
|
||
```
|
||
|
||
`PATCH /api/agents/agent/{agent_id}/config` (admin, `agent:manage`)
|
||
Updates server-side config for an agent (e.g., `commandsEnabled`).
|
||
|
||
### Docker / Podman Module Management (Admin)
|
||
These routes manage Docker / Podman telemetry and container actions reported by the Docker / Podman module inside the installed `pulse-agent` binary.
|
||
|
||
- `POST /api/agents/docker/commands/{commandId}/ack` (`docker:report`)
|
||
- `DELETE /api/agents/docker/runtimes/{agentId}` (`docker:manage`, supports `?hide=true` or `?force=true`)
|
||
- `POST /api/agents/docker/runtimes/{agentId}/allow-reenroll` (`docker:manage`)
|
||
- `PUT /api/agents/docker/runtimes/{agentId}/unhide` (`docker:manage`)
|
||
- `PUT /api/agents/docker/runtimes/{agentId}/pending-uninstall` (`docker:manage`)
|
||
- `PUT /api/agents/docker/runtimes/{agentId}/display-name` (`docker:manage`)
|
||
- `POST /api/agents/docker/runtimes/{agentId}/check-updates` (`docker:manage`)
|
||
- `POST /api/agents/docker/runtimes/{agentId}/update-all` (`docker:manage`) — retired, returns `410 Gone`; container updates run as reviewed per-container actions through `/api/actions`
|
||
- `POST /api/agents/docker/containers/update` (`docker:manage`) — retired, returns `410 Gone`; use the `/api/actions` plan/decision/execute flow instead
|
||
|
||
### Kubernetes Agent Management (Admin)
|
||
- `DELETE /api/agents/kubernetes/clusters/{clusterId}` (`kubernetes:manage`, supports `?hide=true` or `?force=true`)
|
||
- `POST /api/agents/kubernetes/clusters/{clusterId}/allow-reenroll` (`kubernetes:manage`)
|
||
- `PUT /api/agents/kubernetes/clusters/{clusterId}/unhide` (`kubernetes:manage`)
|
||
- `PUT /api/agents/kubernetes/clusters/{clusterId}/pending-uninstall` (`kubernetes:manage`)
|
||
- `PUT /api/agents/kubernetes/clusters/{clusterId}/display-name` (`kubernetes:manage`)
|
||
|
||
### Agent Profiles (Pro)
|
||
`GET /api/admin/profiles` (admin, Pro)
|
||
`POST /api/admin/profiles` (admin, Pro)
|
||
`GET /api/admin/profiles/{id}` (admin, Pro)
|
||
`PUT /api/admin/profiles/{id}` (admin, Pro)
|
||
`DELETE /api/admin/profiles/{id}` (admin, Pro)
|
||
`GET /api/admin/profiles/schema` (admin, Pro)
|
||
`POST /api/admin/profiles/validate` (admin, Pro)
|
||
`POST /api/admin/profiles/suggestions` (admin, Pro)
|
||
`GET /api/admin/profiles/changelog` (admin, Pro)
|
||
`GET /api/admin/profiles/deployments` (admin, Pro)
|
||
`POST /api/admin/profiles/deployments` (admin, Pro)
|
||
`GET /api/admin/profiles/{id}/versions` (admin, Pro)
|
||
`POST /api/admin/profiles/{id}/rollback/{version}` (admin, Pro)
|
||
`GET /api/admin/profiles/assignments` (admin, Pro)
|
||
`POST /api/admin/profiles/assignments` (admin, Pro)
|
||
`DELETE /api/admin/profiles/assignments/{agent_id}` (admin, Pro)
|
||
|
||
---
|
||
|
||
## Availability Checks
|
||
|
||
Agentless availability checks monitor endpoint-only devices and services with
|
||
ICMP ping, TCP port, UDP, HTTP, or HTTPS probes. They are managed from
|
||
**Settings -> Monitoring -> Availability checks** and are also exposed through
|
||
the API for automation.
|
||
|
||
### Target Management
|
||
|
||
- `GET /api/availability-targets` (`settings:read`) - List configured targets and latest probe status.
|
||
- `POST /api/availability-targets` (`settings:write`) - Add a target.
|
||
- `PUT /api/availability-targets/{id}` (`settings:write`) - Update a target.
|
||
- `DELETE /api/availability-targets/{id}` (`settings:write`) - Remove a target.
|
||
- `POST /api/availability-targets/test` (`settings:write`) - Test an unsaved target.
|
||
- `POST /api/availability-targets/{id}/test` (`settings:write`) - Test a saved target.
|
||
|
||
Target payload fields:
|
||
|
||
- `name` - Display name.
|
||
- `targetKind` - `machine`, `service`, or `device`; defaults to `service`.
|
||
- `address` - Hostname, IP address, or URL.
|
||
- `protocol` - `icmp`, `tcp`, `udp`, `http`, or `https`. The input alias `ping` is accepted and is stored/returned as canonical `icmp`.
|
||
- `port` - Required for `tcp`/`udp`, optional for `http`/`https`, and omitted for `icmp`.
|
||
- `path` - Optional HTTP path.
|
||
- `udpMode` - For UDP, `response_required` (default) or `open_or_filtered`. The latter reports silence as indeterminate and fails only on an explicit rejection.
|
||
- `udpRequest` - UTF-8 request bytes, up to 512 bytes. Required by `response_required`; optional in `open_or_filtered` mode.
|
||
- `udpExpectedResponse` - Optional exact UTF-8 response, up to 4096 bytes.
|
||
- `enabled` - Whether the target is scheduled.
|
||
- `pollIntervalSeconds` - Minimum 10 seconds; defaults to 60.
|
||
- `timeoutMillis` - Minimum 250 milliseconds; defaults to 2000.
|
||
- `failureThreshold` - Number of consecutive failures before alerting; defaults to 2.
|
||
- `linkedResourceId` - Optional resource id hint for attaching the probe facet to an existing resource.
|
||
- `certificateMonitoringDisabled` - Explicit HTTPS-only opt-out; certificate validity monitoring is enabled by default.
|
||
- `certificateExpiryWarningDays` - HTTPS certificate expiry warning window; defaults to 30 days.
|
||
- `probeAgentId` - Optional registered host-agent ID that runs the check instead of the Pulse server; requires the Pro `external_probe` entitlement. Send an explicit empty string on update to return the check to local execution.
|
||
|
||
An explicit `linkedResourceId` is authoritative and fails closed when it
|
||
cannot resolve. Without it, Pulse correlates only on one exact normalized IP
|
||
or hostname match. Zero matches remain standalone and multiple matches remain
|
||
ambiguous; Pulse does not guess. Every configured target remains a distinct
|
||
`network-endpoint` in `/api/resources`, including correlated targets. A
|
||
correlated target also projects an additive `availability` /
|
||
`availabilityChecks` facet onto the matched resource and exposes an outgoing
|
||
`checks` relationship from the check resource. The check row remains the owner
|
||
of probe status, incidents, evidence, and history.
|
||
|
||
Example ping-only target:
|
||
|
||
```json
|
||
{
|
||
"name": "Garage temperature sensor",
|
||
"targetKind": "device",
|
||
"address": "garage-sensor.local",
|
||
"protocol": "ping",
|
||
"enabled": true
|
||
}
|
||
```
|
||
|
||
The create response and subsequent reads return `"protocol": "icmp"`.
|
||
|
||
---
|
||
|
||
## 🐟 TrueNAS
|
||
|
||
TrueNAS connection management endpoints for adding, testing, and removing TrueNAS SCALE/CORE instances.
|
||
|
||
### Connection Management (Admin)
|
||
- `GET /api/truenas/connections` (admin, `settings:read`) — List configured TrueNAS connections.
|
||
- `POST /api/truenas/connections` (admin, `settings:write`) — Add a new TrueNAS connection.
|
||
- `POST /api/truenas/connections/test` (admin, `settings:write`) — Test a TrueNAS connection before saving.
|
||
- `DELETE /api/truenas/connections/{id}` (admin, `settings:write`) — Remove a TrueNAS connection.
|
||
|
||
TrueNAS resources (pools, datasets, disks, ZFS snapshots, replication tasks, alerts) are surfaced through the unified `/api/resources` endpoint with `source=truenas`.
|
||
|
||
---
|
||
|
||
## 📱 Relay / Mobile Remote Access (Relay and Above)
|
||
|
||
End-to-end encrypted relay protocol for mobile connectivity.
|
||
|
||
> Relay pairing endpoints generate the QR code and deep link used by supported Pulse Mobile clients.
|
||
|
||
### Relay Configuration (Admin, Relay and Above)
|
||
- `GET /api/settings/relay` (admin, `settings:read`, Relay+) — Get current relay configuration.
|
||
- `PUT /api/settings/relay` (admin, `settings:write`, Relay+) — Update relay configuration.
|
||
- `GET /api/settings/relay/status` (admin, `settings:read`, Relay+) — Get relay connection status.
|
||
|
||
### Mobile Onboarding
|
||
- `GET /api/onboarding/qr` (`settings:read`) — Generate QR code for Pulse Mobile pairing.
|
||
- `POST /api/onboarding/validate` (`settings:read`) — Validate a mobile onboarding connection.
|
||
- `GET /api/onboarding/deep-link` (`settings:read`) — Generate deep-link URL for mobile app.
|
||
|
||
---
|
||
|
||
## 🔌 WebSocket Endpoints
|
||
|
||
- `GET /ws` – Primary UI WebSocket (browser sessions).
|
||
- `GET /api/agent/ws` – Agent WebSocket used for AI command execution.
|
||
|
||
---
|
||
|
||
> **Note**: This is a summary of the most common endpoints. For a complete list, inspect the network traffic of the Pulse dashboard or check the source code in `internal/api/router.go`.
|