API and webhooks
Use API keys to read backup status from other tools, and webhooks to be told about events as they happen.
The API
Everything the portals do goes through the REST API under /api/v1. Your server publishes an OpenAPI description of it at https://<your domain>/api/v1/openapi.json. The portals call it with a signed-in user's session.
API keys are for machine access. Today an API key can call:
| Endpoint | Returns |
|---|---|
GET /api/v1/whoami |
The key's tenant, role and scope, to check a key works |
GET /api/v1/integrations/backup-status |
Every device's backup status for the key's tenant, or for all tenants |
Send the key as a bearer token:
curl -H "Authorization: Bearer <api key>" https://backups.your-msp.com/api/v1/integrations/backup-status
Backup status
Each device in the response has:
| Field | Meaning |
|---|---|
host |
The device's hostname |
tenantName |
Only with an all-tenants key |
os, agentVersion |
Platform and agent build |
status |
ok, failed, stale (no successful backup for 48 hours) or never |
lastBackupAt, lastBackupBytes |
The newest successful restore point and its size |
snapshotCount |
Restore points kept |
lastOutcome, lastOutcomeKind, lastOutcomeAt |
The latest backup or recovery result and when |
lastError |
The error, when the last outcome failed |
CVN PSA uses this endpoint. See CVN PSA.
API keys
| Key | Created in | Covers |
|---|---|---|
| Tenant key | Tenant admin portal > API Keys, or the tenant in the global admin API & Webhooks page | One tenant |
| All-tenants key | Global admin portal > API & Webhooks, tenant All tenants (current & future) | Every tenant, including ones you add later |
Each key has a scope: read (GET only), write (changes only) or read and write. For status reads, create a read key.
The key is shown once, when you create it. The server keeps only a hash and a short prefix so you can tell keys apart. Delete a key to revoke it at once.
Webhooks
A webhook sends an HTTPS POST to your URL when something happens in a tenant.
| Event | When | Data |
|---|---|---|
snapshot.created |
A device recorded a new restore point | snapshotId, deviceId |
quota.warning |
A new restore point took the tenant past the warning level | snapshotId |
security.alert |
An agent reported a security alert, such as an altered canary | deviceId, type, detail |
Create webhooks in the tenant admin portal under Webhooks, or for any tenant in the global admin API & Webhooks page. Give each one a URL, a secret and the events it wants.
The body is JSON:
{"event": "snapshot.created", "tenantId": "...", "data": {"snapshotId": "...", "deviceId": "..."}}
Verify the signature
Every delivery carries an X-CVN-Signature header: the hex HMAC-SHA256 of the raw request body, keyed with the webhook's secret. Compute the same over the body you received and compare before you trust it.
Delivery
- A delivery that fails with a network error or a 5xx response is retried after 2, 10 and 30 seconds.
- A 2xx, 3xx or 4xx response ends the attempts.
- Webhook URLs that resolve to private, loopback or link-local addresses are refused, at creation and again when connecting.
NetLock RMM
If you use NetLock RMM, the global admin portal can push each device's backup status into a NetLock custom field, link NetLock devices to backup devices by hostname, and show NetLock alerts. Set the NetLock server address in the server configuration and paste an API token with custom-field write access under Netlock RMM. From there you can preview the hostname matches, then push status on demand. A push interval in the server configuration keeps it updated automatically.