banshee is under active development: collectors will keep changing, and a version you publish will likely need adjustments. For stable use, wait for version 1.0.0.

Storage

banshee/storage-collection/storage/truenas/https/api-v2.0/

pools

The health and the space of each ZFS pool of a TrueNAS by its REST API v2.0.

  • storage
  • truenas
  • zfs
  • pool
  • https
  • api

by banshee1 installation2 versions

v2Latest

Published on October 28, 2026. One naming convention across collections; documentation completed.

Keen 1.0.0 · 53 lines
// The health and space of each ZFS pool of a TrueNAS, by its REST API v2.0 (GET /api/v2.0/pool), behind an
// API key. The REST API v2.0 answers on TrueNAS CORE 12 and 13 and on TrueNAS SCALE up to 25.10; TrueNAS 26
// removed it, for a JSON-RPC API over WebSocket that Keen does not speak.
// The address of the API is the host's own: https://<host:address>/api/v2.0/.
need('protocol:http');
$address = need('host:address');
$token = need('protocol:http:token');

per('pool', 'Pools');
output('health', 'text', array('label' => 'Health', 'per' => 'pool'));
output('used-percent', 'number', array('label' => 'Used space', 'unit' => '%', 'per' => 'pool'));
output('free', 'number', array('label' => 'Free space', 'unit' => 'GiB', 'per' => 'pool'));
output('size', 'number', array('label' => 'Size', 'unit' => 'GiB', 'per' => 'pool'));

watch.expect('unhealthy', 'Pool not online', 'health', array('warning' => array('online')));
watch.state('failed', 'Pool failed', 'health', array('critical' => array('faulted', 'unavail', 'removed', 'suspended')));
watch.above('used', 'Used space', 'used-percent', array('warning' => 80, 'critical' => 90));
watch.above('full-soon', 'Full within a week', 'used-percent', array('warning' => 99, 'ahead' => '7 d'));
watch.missing('missing', 'Pool missing', 'health', array('enabled' => false));

// The key goes in a header: the answer is not secret, its body having carried none.
$answer = http.get('https://' . $address . '/api/v2.0/pool', headers=array('Authorization' => 'Bearer ' . $token));
if ($answer['status'] == 401 || $answer['status'] == 403) {
    fail('misconfigured', 'The TrueNAS API refuses the key, code ' . $answer['status']);
}
if ($answer['status'] != 200) {
    fail('unreachable', 'The TrueNAS API answers code ' . $answer['status'],
        'A TrueNAS 26 or later has no REST API: it answers 404.');
}

// A list of pools: {"name": "tank", "status": "ONLINE", "healthy": true, "size": 3985729650688,
// "allocated": 1052266987520, "free": 2933462663168, ...}, the sizes in bytes. An exported or failed pool
// may have no size: only an online or degraded pool's space is read.
$pools = json.read($answer['body']);
$read = 0;
foreach ($pools as $pool) {
    $read = $read + 1;
    $name = $pool['name'];
    $health = text.lower($pool['status']);
    value('health', $health, $name);
    if ($health != 'online' && $health != 'degraded') {
        continue;
    }
    // Allocated over size: what zpool list shows as its capacity.
    if ($pool['size'] > 0) {
        value('used-percent', number.round(100 * $pool['allocated'] / $pool['size'], 1), $name);
    }
    value('free', number.round($pool['free'] / 1073741824, 1), $name);
    value('size', number.round($pool['size'] / 1073741824, 1), $name);
}
if ($read == 0) {
    fail('misconfigured', 'The TrueNAS API lists no pool');
}