Zuvio Atlas/API & SDKs
Sign in

Zuvio Atlas API & SDKs

Everything you need to integrate: monitor background jobs from any language, push custom metrics from your servers, and drive every resource over a simple REST API.

Authentication

The public REST API uses a Bearer token. Generate a key in Workspace → API Keys (keys are prefixed za_live_; requires a paid plan).

Authorization: Bearer za_live_your_api_key_here
Base URL: https://atlas.zuviosystems.com/api/v1
Three ways to authenticate.
  • Bearer za_live_ key (Pro+) — every /api/v1/* REST endpoint, custom-metrics reads, and job key mode pings. Account-wide — keep it in a secrets manager, not on low-trust hosts.
  • X-Agent-Token — the token embedded in an installed server's service. Used by telemetry and custom-metrics ingest. Scoped to one server.
  • Slug capability URL (no auth) — job run pings by slug. The random slug is the token; a leak only affects that one monitor.
Limits. Resource counts are capped per plan and pooled across your org (see each tier in Billing) — creation past a cap returns 402. Ingestion is rate-limited (telemetry & custom-metrics ~30 requests/server/min → 429; job runs ~60/monitor/min). Raw metrics and custom metrics are retained 7 days, job-run history 30 days (configurable per monitor).

Job Monitoring & SDKs

Track each run of a cron job or scheduled script start-to-finish — duration, exit code, and alerts on failed, overrun, or missed runs. Create a monitor in Uptime → Cron Jobs to get its slug, then wrap the job with an SDK or the raw API.

Language SDKs

Zero-dependency wrappers — supported languages: Shell/cron, Node, Python, and PHP & Laravel. Replace your-job-slugwith your monitor's slug.

install
sudo curl -fsSL https://atlas.zuviosystems.com/sdk/zuvio-run -o /usr/local/bin/zuvio-run
sudo chmod +x /usr/local/bin/zuvio-run
crontab
# wrap any command — Atlas records start, finish/fail, duration & exit code
0 3 * * *  ZUVIO_JOB_SLUG=your-job-slug zuvio-run -- /opt/backup.sh

Direct integration (any HTTP client)

telemetry API
# 1. mark the run started (returns {"ok":true,"runId":"..."})
RUN=$(curl -s "https://atlas.zuviosystems.com/api/jobs/ping/your-job-slug/start" | grep -o '"runId":"[^"]*"' | cut -d'"' -f4)

/opt/backup.sh   # ...do the work...

# 2. report the outcome
curl "https://atlas.zuviosystems.com/api/jobs/ping/your-job-slug/finish?runId=$RUN&exitCode=0"   # success
curl "https://atlas.zuviosystems.com/api/jobs/ping/your-job-slug/fail?runId=$RUN&exitCode=1&message=boom"   # or failure

Actions are start, finish, fail, and tick (a liveness stamp for long runs). All accept GET or POST, with parameters in the query string or a JSON body: runId, exitCode, message, durationMs, host.

Checking only the status code is not enough. Pings are best-effort by design, so a disabled monitor, a rate-limited ping (60/monitor/min), and a finish with no open run all return 200 with a note field explaining what happened. Only an unknown slug returns 404. If you are debugging runs that never appear, log the response body — not just res.ok.

Two ways to identify a monitor. A slug is a random, unauthenticated capability token — secretless, works on any tier, but you create the monitor in the dashboard first. A key is a human name you choose; it needs a za_live_ Bearer key (Pro+), and unlocks monitoring-as-code (put()) plus auto-create on first ping.

API-key mode — monitoring-as-code

Set ZUVIO_ATLAS_KEY, declare the monitor from code with put() (idempotent), and report runs by your chosen key — which auto-creates on first ping.

crontab
# ZUVIO_ATLAS_KEY makes the identifier a human key (auto-created)
0 3 * * *  ZUVIO_ATLAS_KEY=za_live_...  ZUVIO_JOB_SLUG=nightly-backup zuvio-run -- /opt/backup.sh

Custom Metrics

Push your own numeric metrics from a monitored server and alert on them with a CUSTOM_METRIC alert rule. Ingestion authenticates with the server's X-Agent-Token (the same token the agent uses), while the read endpoints use your za_live_ API key.

push metrics (from the monitored server)
curl -X POST https://atlas.zuviosystems.com/api/v1/custom-metrics/YOUR_SERVER_ID \
  -H "X-Agent-Token: <server agent token>" \
  -H "Content-Type: application/json" \
  -d '[{"name":"queue_depth","value":42,"unit":"jobs"}]'
POST/api/v1/custom-metrics/{serverId}

Ingest up to 50 metrics for a server. Auth: X-Agent-Token. Values are retained 7 days.

Path Parameters

serverIdstringTarget server ID

Request Body (JSON)

namestringMatches ^[a-z][a-z0-9_]{0,49}$
valuenumberFinite number
unitstring (optional)Optional label, ≤ 20 chars
timestampstring (optional)Optional ISO time (defaults to now)

Response

{ "success": true, "count": 1 }
GET/api/v1/custom-metrics

List custom metric definitions with each one's latest value. Auth: Bearer za_live_. Optional ?serverId= filter.

Response

{ "customMetrics": [ { "id": "clx...", "serverId": "clx...", "name": "queue_depth",
    "unit": "jobs", "latestValue": 42, "latestTimestamp": "..." } ] }
GET/api/v1/custom-metrics/{serverId}/{name}

Time-series for one metric (last 7 days). Auth: Bearer za_live_. ?limit= up to 500 (default 200).

Path Parameters

serverIdstringServer ID
namestringMetric name

Response

{ "serverId": "clx...", "serverName": "web-01", "metric": "queue_depth", "unit": "jobs",
    "dataPoints": [ { "value": 42, "timestamp": "..." } ] }

Servers

List and inspect servers registered to your account.

GET/api/v1/servers

Returns all servers registered to your account, ordered newest first.

Response

{
  "servers": [
    {
      "id": "clx...",
      "name": "web-01",
      "hostname": "web-01.example.com",
      "status": "ONLINE",
      "lastSeenAt": "2026-06-25T10:30:00.000Z",
      "agentVersion": "0.11.0",
      "osInfo": "Ubuntu 24.04 LTS",
      "tags": ["production", "web"]
    }
  ]
}
GET/api/v1/servers/{id}

Returns a single server with its latest metric snapshot.

Path Parameters

idstringResource ID

Response

{ "server": { "id": "clx...", "name": "web-01", "status": "ONLINE", ... },
  "latestMetrics": { "timestamp": "...", "cpuPercent": 12.4, "memTotalBytes": 8589934592, ... } }

Uptime Checks

HTTP and TCP uptime monitors.

GET/api/v1/uptime-checks

List all uptime checks.

Response

{ "uptimeChecks": [ { "id": "clx...", "name": "API", "url": "https://api.example.com/health",
    "checkType": "http", "method": "GET", "currentStatus": "up", "isEnabled": true, ... } ] }
POST/api/v1/uptime-checks

Create an uptime check.

Request Body (JSON)

namestringDisplay name
urlstringURL (http) or host:port (tcp)
checkTypestring (optional)http | tcp — defaults to http
methodstring (optional)HTTP method — defaults to GET
alertThresholdnumber (optional)Consecutive failures before alerting (default 2)
webhookUrlstring (optional)Notification destination
webhookTypestring (optional)EMAIL | SLACK | DISCORD | GENERIC | … (default GENERIC)
isEnabledboolean (optional)Defaults to true

Response

{ "uptimeCheck": { "id": "clx...", "name": "API", "currentStatus": "pending", ... } }
GET/api/v1/uptime-checks/{id}

Fetch one check.

Path Parameters

idstringResource ID

Response

{ "uptimeCheck": { ... } }
PATCH/api/v1/uptime-checks/{id}

Update any of the create fields.

Path Parameters

idstringResource ID

Response

{ "uptimeCheck": { ... } }
DELETE/api/v1/uptime-checks/{id}

Delete a check.

Path Parameters

idstringResource ID

Response

{ "deleted": true }

SSL Checks

Certificate expiry monitoring.

GET/api/v1/ssl-checks

List all SSL checks.

Response

{ "sslChecks": [ { "id": "clx...", "hostname": "example.com", "port": 443,
    "currentStatus": "valid", "daysUntilExpiry": 62, "expiresAt": "...", "issuer": "...", ... } ] }
POST/api/v1/ssl-checks

Create an SSL check.

Request Body (JSON)

hostnamestringHost to inspect
portnumber (optional)TLS port — defaults to 443
alertDaysBeforeExpirynumber (optional)Alert when ≤ N days remain (default 14)
webhookUrlstring (optional)Notification destination
webhookTypestring (optional)Channel type (default GENERIC)

Response

{ "sslCheck": { "id": "clx...", "hostname": "example.com", "currentStatus": "unknown", ... } }
GET/api/v1/ssl-checks/{id}

Fetch one check.

Path Parameters

idstringResource ID

Response

{ "sslCheck": { ... } }
PATCH/api/v1/ssl-checks/{id}

Update fields.

Path Parameters

idstringResource ID

Response

{ "sslCheck": { ... } }
DELETE/api/v1/ssl-checks/{id}

Delete a check.

Path Parameters

idstringResource ID

Response

{ "deleted": true }

Domain Checks

Domain registration expiry monitoring (RDAP).

GET/api/v1/domain-checks

List all domain checks.

Response

{ "domainChecks": [ { "id": "clx...", "domain": "example.com", "currentStatus": "valid",
    "daysUntilExpiry": 120, "expiresAt": "...", "registrar": "...", ... } ] }
POST/api/v1/domain-checks

Create a domain check.

Request Body (JSON)

domainstringDomain name
alertDaysBeforeExpirynumber (optional)Alert when ≤ N days remain (default 30)
webhookUrlstring (optional)Notification destination
webhookTypestring (optional)Channel type (default GENERIC)

Response

{ "domainCheck": { "id": "clx...", "domain": "example.com", "currentStatus": "unknown", ... } }
GET/api/v1/domain-checks/{id}

Fetch one check.

Path Parameters

idstringResource ID

Response

{ "domainCheck": { ... } }
PATCH/api/v1/domain-checks/{id}

Update fields.

Path Parameters

idstringResource ID

Response

{ "domainCheck": { ... } }
DELETE/api/v1/domain-checks/{id}

Delete a check.

Path Parameters

idstringResource ID

Response

{ "deleted": true }

Heartbeats

Dead-man's-switch reverse pings. For full run tracking (duration + exit codes) see Job Monitoring above.

Send a heartbeat from a device, daemon, or webhook — a ping every interval keeps it alive, and state=fail reports a failure. Use the slug URL directly, or a human key with the SDKs (auto-created on first ping).

direct
# alive ping (resets the dead-man's-switch)
curl https://atlas.zuviosystems.com/api/heartbeats/ping/important-heartbeat

# report a failure, with an optional message
curl "https://atlas.zuviosystems.com/api/heartbeats/ping/important-heartbeat?state=fail&msg=disk%20full"

# by human key (Pro+): add your API key as a Bearer header
curl -H "Authorization: Bearer $ZUVIO_ATLAS_KEY" https://atlas.zuviosystems.com/api/heartbeats/ping/important-heartbeat

Management endpoints

GET/api/v1/heartbeats

List all heartbeats.

Response

{ "heartbeats": [ { "id": "clx...", "name": "Nightly backup", "slug": "ab12...",
    "interval": 5, "grace": 1, "currentStatus": "up", "lastPingedAt": "...", ... } ] }
PUT/api/v1/heartbeats

Upsert by key. Creates the heartbeat if the key is new (201), otherwise updates it in place (200). Idempotent — safe to run on every deploy. Plan limits apply only when creating.

Request Body (JSON)

keystringStable identifier matching ^[a-z0-9][a-z0-9_-]{0,63}$
namestring (optional)Display name
intervalnumber (optional)Expected minutes between pings
gracenumber (optional)Grace minutes before marking late/down

Response

// 201 when created, 200 when updated
{ "heartbeat": { "id": "clx...", "key": "nightly-etl", "slug": "ab12...", ... } }
POST/api/v1/heartbeats

Create a heartbeat. Ping GET/POST {APP_URL}/api/heartbeats/ping/{slug} within interval + grace.

Request Body (JSON)

namestringDisplay name
intervalnumber (optional)Expected minutes between pings (default 5)
gracenumber (optional)Grace minutes before alerting (default 1)
webhookUrlstring (optional)Notification destination
webhookTypestring (optional)Channel type (default GENERIC)

Response

{ "heartbeat": { "id": "clx...", "slug": "ab12...", "currentStatus": "new", ... } }
GET/api/v1/heartbeats/{id}

Fetch one heartbeat.

Path Parameters

idstringResource ID

Response

{ "heartbeat": { ... } }
PATCH/api/v1/heartbeats/{id}

Update fields.

Path Parameters

idstringResource ID

Response

{ "heartbeat": { ... } }
DELETE/api/v1/heartbeats/{id}

Delete a heartbeat.

Path Parameters

idstringResource ID

Response

{ "deleted": true }

Job Monitors (management)

Create and manage cron/job monitors via the API. Runs are reported to the public ping URLs (see Job Monitoring above).

GET/api/v1/job-monitors

List all job monitors.

Response

{ "jobMonitors": [ { "id": "clx...", "name": "Backup", "slug": "ab12...",
    "scheduleType": "cron", "cronExpression": "0 3 * * *", "timezone": "UTC",
    "currentStatus": "up", "lastRunAt": "...", "lastDurationMs": 4200, ... } ] }
PUT/api/v1/job-monitors

Upsert by key — the monitoring-as-code entry point. Creates the monitor if the key is new (201), otherwise updates it in place (200). Idempotent, so it is safe to run on every deploy. Plan limits apply only when creating.

Request Body (JSON)

keystringStable identifier matching ^[a-z0-9][a-z0-9_-]{0,63}$
namestring (optional)Display name
scheduleTypestring (optional)interval | cron
expectedIntervalSecnumber (optional)Required when creating in interval mode
cronExpressionstring (optional)Required when creating in cron mode
timezonestring (optional)IANA tz for cron (default UTC)
graceSecnumber (optional)Lateness grace before missed

Response

// 201 when created, 200 when updated
{ "jobMonitor": { "id": "clx...", "key": "nightly-backup", "slug": "ab12...", ... } }
POST/api/v1/job-monitors

Create a job monitor. Reports runs via the slug ping URLs.

Request Body (JSON)

namestringDisplay name
keystring (optional)Stable identifier you choose ([a-z0-9][a-z0-9_-]{0,63}). Lets you PUT-upsert this monitor from config.
scheduleTypestring (optional)interval | cron (default interval)
expectedIntervalSecnumber (optional)Seconds between runs. REQUIRED in interval mode. Values below 60 are raised to 60.
cronExpressionstring (optional)5-field cron. REQUIRED when scheduleType is cron.
timezonestring (optional)IANA tz for cron (default UTC)
graceSecnumber (optional)Lateness grace before missed (default 60)
expectedDurationSecnumber (optional)Soft ceiling → overrun
maxDurationSecnumber (optional)Hard ceiling → overrun
webhookUrlstring (optional)Notification destination
webhookTypestring (optional)Channel type (default GENERIC)

Response

{ "jobMonitor": { "id": "clx...", "slug": "ab12...", "currentStatus": "new", ... } }
GET/api/v1/job-monitors/{id}

Fetch one monitor (with recent runs).

Path Parameters

idstringResource ID

Response

{ "jobMonitor": { ..., "runs": [ ... ] } }
PATCH/api/v1/job-monitors/{id}

Update fields.

Path Parameters

idstringResource ID

Response

{ "jobMonitor": { ... } }
DELETE/api/v1/job-monitors/{id}

Delete a monitor.

Path Parameters

idstringResource ID

Response

{ "deleted": true }

Alert Rules

Metric threshold and anomaly alerts on server telemetry.

GET/api/v1/alert-rules

List all alert rules.

Response

{ "alertRules": [ { "id": "clx...", "name": "High CPU", "metric": "CPU_PERCENT",
    "operator": "GREATER_THAN", "threshold": 90, "durationSec": 300, "currentState": "OK", ... } ] }
POST/api/v1/alert-rules

Create an alert rule.

Request Body (JSON)

namestringRule name
metricstringCPU_PERCENT | MEMORY_PERCENT | DISK_PERCENT | LOAD_AVERAGE | TCP_CONNECTIONS | SERVER_OFFLINE | CUSTOM_METRIC | ANOMALY | …
operatorstringGREATER_THAN | LESS_THAN | EQUALS
thresholdnumberFor ANOMALY this is the sigma multiplier
metricNamestring (optional)Required for CUSTOM_METRIC and ANOMALY
serverIdstring (optional)Scope to one server (omit = all)
durationSecnumber (optional)Sustained duration before firing (default 0)
cooldownSecnumber (optional)Re-fire cooldown (default 300)
webhookUrlstring (optional)Notification destination
webhookTypestring (optional)Channel type (default GENERIC)

Response

{ "alertRule": { "id": "clx...", "name": "High CPU", "currentState": "OK", ... } }
GET/api/v1/alert-rules/{id}

Fetch one rule (with last 10 history entries).

Path Parameters

idstringResource ID

Response

{ "alertRule": { ..., "alertHistory": [ ... ] } }
PATCH/api/v1/alert-rules/{id}

Update fields.

Path Parameters

idstringResource ID

Response

{ "alertRule": { ... } }
DELETE/api/v1/alert-rules/{id}

Delete a rule.

Path Parameters

idstringResource ID

Response

{ "deleted": true }

Incidents

Create and manage incidents. Incidents appear on your public status page and notify subscribers.

GET/api/v1/incidents

Unresolved incidents + those resolved in the last 90 days (max 50).

Response

{ "incidents": [ { "id": "clx...", "title": "API latency elevated", "status": "INVESTIGATING",
    "severity": "MAJOR", "message": "...", "updates": [ ... ], ... } ] }
POST/api/v1/incidents

Create an incident. An optional message becomes the first timeline update.

Request Body (JSON)

titlestringIncident title
statusstring (optional)INVESTIGATING | IDENTIFIED | MONITORING | RESOLVED (default INVESTIGATING)
severitystring (optional)CRITICAL | MAJOR | MINOR | MAINTENANCE (default MINOR)
messagestring (optional)First timeline update

Response

{ "incident": { "id": "clx...", "status": "INVESTIGATING", "updates": [ ... ] } }
PATCH/api/v1/incidents/{id}

Update status and/or add a timeline update. RESOLVED sets resolvedAt automatically.

Path Parameters

idstringResource ID

Request Body (JSON)

statusstring (optional)INVESTIGATING | IDENTIFIED | MONITORING | RESOLVED
messagestring (optional)Update message added to the timeline

Response

{ "incident": { "id": "clx...", "status": "RESOLVED", "resolvedAt": "...", "updates": [ ... ] } }

Other monitor types

These follow exactly the same shape as the families above — Bearer za_live_ auth, plan-limited on create, and the same five operations:

GET    /api/v1/{resource}          list
POST   /api/v1/{resource}          create
GET    /api/v1/{resource}/{id}     detail
PATCH  /api/v1/{resource}/{id}     partial update
DELETE /api/v1/{resource}/{id}     delete → { "deleted": true }
/api/v1/dependency-checksThird-party service status (Stripe, GitHub, …)
/api/v1/log-alert-rulesPattern matches over ingested log events
/api/v1/maintenance-windowsSuppress alerts during planned downtime
/api/v1/snmp-checksSNMP polling for network gear and UPSes
/api/v1/synthetic-checksMulti-step scripted HTTP transactions
/api/v1/ip-blacklist-checksDNSBL reputation for a public IPv4

Errors

All errors return JSON with an error field.

StatusMeaning
401Missing, invalid, or revoked API key — also returned when the key's plan is below Pro, since the public API is Pro+
400Malformed request body or missing required field
402Plan limit reached — you are at your plan's cap for that resource
404Resource not found or doesn't belong to your account
409Conflict — a monitor with that key already exists (slugs are server-generated and never collide)
500Internal server error

Example

Create an incident and resolve it using curl:

# Create an incident
curl -X POST https://atlas.zuviosystems.com/api/v1/incidents \
  -H "Authorization: Bearer za_live_..." \
  -H "Content-Type: application/json" \
  -d '{"title":"API latency elevated","severity":"MAJOR","message":"Investigating."}'

# Resolve it
curl -X PATCH https://atlas.zuviosystems.com/api/v1/incidents/{id} \
  -H "Authorization: Bearer za_live_..." \
  -H "Content-Type: application/json" \
  -d '{"status":"RESOLVED","message":"Issue resolved."}'
Zuvio Atlas API — Back to Dashboard