HowTo: Use ZPE Cloud REST API

HowTo: Use ZPE Cloud REST API

How To Use ZPE Cloud REST API:
Querying Device Information via a Simple Python Script

Overview

ZPE Cloud provides a rich REST API that administrators can use to programmatically manage and monitor their Nodegrid devices. Instead of navigating the web console, you can write scripts that authenticate to the API, query device data, and process the results however you need — whether that's generating reports, feeding a monitoring system, or simply checking device status from the command line.  You can find links to the ZPE Cloud REST API documentation in the ZPE Cloud when you login located as a dropdown on your username from the About menu.

This article walks through a practical example: a short Python script that connects to ZPE Cloud, looks up a device by hostname, and displays key information in a table.

Prerequisites

  • Python 3.6 or later
  • The following Python packages (install with pip):
    pip install requests tabulate2
  • A ZPE Cloud user account with access to the devices you want to query

How It Works

The ZPE Cloud REST API is hosted at https://api.zpecloud.com. All communication uses JSON payloads over HTTPS. Authentication is session-based: you POST your credentials to the login endpoint, and the API returns a session cookie. That cookie is automatically included in all subsequent requests, so there are no API keys or tokens to manage.

The three steps are:
  1. Authenticate — POST credentials to /user/auth
  2. Request data — GET device information from /device
  3. Use the data — Extract the fields you need and display them

Step 1: Authenticate to the API

To authenticate, send a POST request to /user/auth with your email and password as a JSON body. The API returns user information and sets a session cookie on the response. Using a requests.Session object ensures the cookie is stored and sent with all future requests automatically.
import getpass
import sys

import requests

user = sys.argv[1]
password = getpass.getpass("Password: ")

session = requests.Session()
resp = session.post(
"https://api.zpecloud.com/user/auth",
json={"email": user, "password": password},
)
if resp.status_code == 401:
sys.exit("Error: Invalid credentials.")
resp.raise_for_status()
print("Authenticated successfully.")
The script takes the user's email as its first command-line argument. Only the password is prompted interactively, so it never appears in shell history. If the credentials are valid, the session is now authenticated. All further requests made through this session object will include the session cookie automatically.

Step 2: Query Device Data

Use GET /device to search for devices. The search query parameter tells the API to filter results server-side by hostname, serial number, model, site name, or company name. This is much more efficient than fetching the entire device list and filtering locally.

Since search is a broad filter (it matches across multiple fields), we do a final case-insensitive match on hostname from the returned results to ensure we get the right device. The hostname is taken from the script's second command-line argument.
hostname = sys.argv[2]

resp = session.get(
"https://api.zpecloud.com/device",
params={"search": hostname, "limit": 100},
)
resp.raise_for_status()

devices = [d for d in resp.json()["list"]
if d.get("hostname", "").lower() == hostname.lower()]
if not devices:
sys.exit(f"Error: No device found with hostname '{hostname}'.")
device = devices[0]
The response contains a list of device objects, each with fields like hostname, serial_number, version, device_status, last_connection, uptime, and many more.

Step 3: Display the Results

Extract the fields you need from the device object and present them. The uptime field is returned as a number of seconds, so we convert it to a human-readable format. The last_connection timestamp is cleaned up by removing the fractional seconds and formatting it for readability. Here we use the tabulate2 library to format the output as a grid table.
from tabulate2 import tabulate

uptime_sec = device.get("uptime", 0)
days, rem = divmod(int(uptime_sec), 86400)
hours, rem = divmod(rem, 3600)
minutes, secs = divmod(rem, 60)
uptime_str = f"{days}d {hours}h {minutes}m {secs}s"

last_conn = device.get("last_connection", "")
if last_conn:
last_conn = last_conn.replace("T", " ").replace("Z", " UTC")
# Strip fractional seconds (e.g. ".240000")
dot = last_conn.find(".")
if dot != -1:
last_conn = last_conn[:dot] + last_conn[last_conn.find(" ", dot):]

rows = [[
device.get("hostname", ""),
device.get("serial_number", ""),
device.get("version", ""),
device.get("device_status", ""),
last_conn,
uptime_str,
]]
headers = ["Hostname", "Serial Number", "OS Version",
"Status", "Last Connection", "Uptime"]
print(tabulate(rows, headers=headers, tablefmt="grid"))

Full Script

Here is the complete script in a single block, ready to copy and run:
#!/usr/bin/env python3
"""
Example: Query device information from ZPE Cloud by hostname.

Usage:
python kb-device-info.py <user> <hostname>
"""

import getpass
import sys

import requests
from tabulate2 import tabulate

if len(sys.argv) != 3:
sys.exit("Usage: python kb-device-info.py <user> <hostname>")

user = sys.argv[1]
hostname = sys.argv[2]

# ---------------------------------------------------------------
# Step 1: Authenticate to the ZPE Cloud API
# ---------------------------------------------------------------
password = getpass.getpass("Password: ")

session = requests.Session()
resp = session.post(
"https://api.zpecloud.com/user/auth",
json={"email": user, "password": password},
)
if resp.status_code == 401:
sys.exit("Error: Invalid credentials.")
resp.raise_for_status()
print("Authenticated successfully.\n")

# ---------------------------------------------------------------
# Step 2: Look up device by hostname
# ---------------------------------------------------------------
resp = session.get(
"https://api.zpecloud.com/device",
params={"search": hostname, "limit": 100},
)
resp.raise_for_status()

devices = [d for d in resp.json()["list"]
if d.get("hostname", "").lower() == hostname.lower()]
if not devices:
sys.exit(f"Error: No device found with hostname '{hostname}'.")
device = devices[0]

# ---------------------------------------------------------------
# Step 3: Display device information
# ---------------------------------------------------------------
uptime_sec = device.get("uptime", 0)
days, rem = divmod(int(uptime_sec), 86400)
hours, rem = divmod(rem, 3600)
minutes, secs = divmod(rem, 60)
uptime_str = f"{days}d {hours}h {minutes}m {secs}s"

last_conn = device.get("last_connection", "")
if last_conn:
last_conn = last_conn.replace("T", " ").replace("Z", " UTC")
# Strip fractional seconds (e.g. ".240000")
dot = last_conn.find(".")
if dot != -1:
last_conn = last_conn[:dot] + last_conn[last_conn.find(" ", dot):]

rows = [[
device.get("hostname", ""),
device.get("serial_number", ""),
device.get("version", ""),
device.get("device_status", ""),
last_conn,
uptime_str,
]]
headers = ["Hostname", "Serial Number", "OS Version",
"Status", "Last Connection", "Uptime"]
print(tabulate(rows, headers=headers, tablefmt="grid"))
Save this as kb-device-info.py and run it:
python kb-device-info.py admin@example.com nodegrid-hq-01

Example Output

$ python kb-device-info.py admin@example.com nodegrid-hq-01
Password:
Authenticated successfully.
+-----------------+-----------------+--------------+----------+----------------------+-------------------+
| Hostname | Serial Number | OS Version | Status | Last Connection | Uptime |
+=================+=================+==============+==========+======================+===================+
| nodegrid-hq-01 | 400383918 | 5.8.6 | Online | 2026-03-23 19:45:27 UTC | 45d 3h 22m 10s |
+-----------------+-----------------+--------------+----------+----------------------+-------------------+

API Reference

The three endpoints used in this example:
Method Endpoint Description
POST /user/auth Authenticate with email and password. Returns user info and sets a session cookie.
GET /device List and search devices. Supports search, sort_by, offset, and limit query parameters.
GET /device/{id} Get full detail for a single device (not used in this example, but useful for retrieving all fields including network interfaces).

The search parameter on GET /device filters across hostname, serial number, model, site name, and company name in a single query.

Notes

  • Session-based authentication. The API uses session cookies rather than API keys or bearer tokens. The requests.Session object handles cookie management automatically.
  • Pagination. The GET /device endpoint returns paginated results. The default page size is 20; the maximum is 100 (set via the limit parameter). For accounts with more than 100 devices, use the offset parameter to page through results.
  • Available fields. The device objects returned by GET /device include many fields beyond those shown here, such as model, ipv4, site, groups, firmware_version, and more. Use GET /device/{id} for the complete set of fields including network interface details.
  • Production use. For scripts that run unattended, consider passing the password via an environment variable instead of the interactive prompt to avoid manual intervention.