Skip to content

Level.io

Level.io is Opentra’s RMM connector. Devices and alerts flow in, and alerts can become tickets so monitoring lives in the same queue as everything else.

  • Device sync. Level devices land against the right client organisation.
  • Alerts → tickets. Alerts can raise tickets automatically, routed to the matching org.
  • Runs on a daily sync, plus the device and alert feeds.

Resolution order when the sync runs:

  1. An explicit group → organisation mapping you’ve set.
  2. An exact group-name equals org-name match.
  3. Otherwise, the existing assignment is preserved — Opentra never guesses or clobbers.
  1. In Settings → Integrations, connect Level.io.
  2. Map each device group to an organisation.
  3. Devices and alerts sync in; alerts route to the mapped org.

The Level agent only reports the Debian base OS on Proxmox hosts — never the PVE version, subscription status, or pending-update count. And because those hosts sit behind client-site firewalls, Opentra can’t reach the Proxmox API directly. Instead, a Level automation runs a small script on each host (over the agent’s existing outbound channel) and pushes the facts to Opentra, where they appear on the device page.

  • PVE version (e.g. 8.4.19) — shown on the device header and in a dedicated Proxmox VE card. Versions on the 8.x line show a reminder that VE 8 support ends 2026-08-31.
  • Subscription statusActive badge, or the raw status (e.g. notfound) for unsubscribed hosts.
  • Pending updates — a count, flagged amber when non-zero.
  • Reported — how long ago the host last checked in.
  1. Set a dedicated secret on the Level.io integration config (proxmoxFactsSecret). This is separate from the alert webhook secret on purpose — it lives on client hosts, so it must never be able to forge sessions or alter alert handling. Because that’s its entire blast radius (an attacker who reads it can only push cosmetic version numbers), it’s fine to inline it in the script rather than fight Level’s variable substitution.

  2. Create a Level Automation (scheduled daily, plus run-on-demand) targeting your Proxmox device group. The script self-skips non-PVE hosts, identifies itself by its own hostname, then signs and POSTs the facts. It uses no Level template variables — deliberately, since hand-typed {{...}} tokens are not substituted (only variables inserted via Level’s {x} picker are), which is a common source of 401s:

    #!/usr/bin/env bash
    command -v pveversion >/dev/null 2>&1 || exit 0 # skip non-Proxmox hosts
    OPENTRA_URL="https://opentra.example.com" # your Opentra host — no angle brackets!
    SECRET="paste-your-proxmoxFactsSecret-here" # must equal Opentra's proxmoxFactsSecret
    HOST=$(hostname -s) # matches the synced device
    VER=$(pveversion | sed -n 's/^pve-manager\/\([^ /]*\).*/\1/p') # e.g. 8.4.19
    SUB=$(pvesubscription get 2>/dev/null | sed -n 's/^status: *//p') # active / notfound
    UPD=$(apt-get -s upgrade 2>/dev/null | grep -c '^Inst ') # pending updates
    TS=$(date +%s)
    BODY=$(printf '{"hostname":"%s","proxmoxVersion":"%s","subscription":"%s","pendingUpdates":%s,"ts":%s}' \
    "$HOST" "$VER" "$SUB" "$UPD" "$TS")
    SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -r | cut -d' ' -f1)
    curl -fsS -X POST "$OPENTRA_URL/api/integrations/proxmox/facts" \
    -H "Content-Type: application/json" -H "X-Opentra-Signature: sha256=$SIG" \
    --data "$BODY"

    hostname -s must match the device’s hostname as synced from Level (it does for the standard <client>-pve naming). If you’d rather key on the Level device ID instead, POST deviceId (the device’s Level external ID) in place of hostname — the endpoint accepts either.

Where you see it, and how the team is notified

Section titled “Where you see it, and how the team is notified”

Each host’s facts show on its device page — a PVE <version> chip in the header and a Proxmox VE card (version, subscription, pending updates, “reported” age, and a VE 8 end-of-life reminder).

A daily health monitor (08:00) turns those facts into proactive signal. It evaluates every reporting host and, for anything at risk, notifies the team through every channel at once:

Condition Severity What happens
End-of-life — Proxmox VE < 9 (VE 8 support ends 2026-08-31) HIGH Fleet alert + auto-created ticket + admin notification + digest
Not reporting — no facts for > 3 days HIGH Fleet alert + auto-created ticket + admin notification + digest
Updates pending — > 100 packages MEDIUM Fleet alert + admin notification + digest (no ticket)
  • Customer fleet — each issue is recorded as an Alert against the client org and device, visible in the Alerts module and on the org/device pages. Alerts auto-resolve when the condition clears (upgraded to VE 9, host reporting again, updates applied).
  • Tickets — the HIGH, actionable conditions raise a ticket into the queue so the work is tracked. Pending-updates stays an alert only (it would otherwise churn a ticket daily).
  • In-app — admins get a notification per newly-raised issue, linked to the device.
  • Email digest — active admins/managers get an at-risk summary weekly (Mondays), plus immediately on any day a new issue appears.

Master switch: Settingsalerts.proxmoxHealthEnabled (on by default).