The WholesaleBackup RMM API lets your RMM or monitoring tool read the backup status of every device you manage: whether the last backup succeeded, how much is stored, what went wrong, and which devices need attention. It is read-only: it can't change settings, start backups or restore data.
This article is the general reference. It works with any tool that can make an HTTPS request and read JSON, such as NinjaOne, N-able, Datto RMM, Syncro, ConnectWise, a PowerShell script or a monitoring system.
Contents
- Overview
- Getting an API key
- Making requests
- Endpoints
- Status values
- Field reference
- Errors and rate limits
- Tips for RMM scripts
Overview
-
Base URL:
https://dash.backupops.com/v1/ -
Authentication: an API key, sent as
Authorization: Bearer <key>on every request. - Format: every response is JSON.
- Access: read-only. A key sees the same devices its owner sees in the Web Console.
- Encryption: HTTPS only, TLS 1.2 or newer.
Getting an API key
- Sign in to the Web Console.
- Open the user menu (your username, top right) and choose API Keys.
- Optionally enter a label (for example NinjaOne) so you can tell your keys apart, then click Generate new key.
- Copy the key straight away. For your security it is shown only once. If you lose it, revoke it and generate a new one.
Keys look like rmm_live_ followed by a long random string. Treat a key like a password: anyone who has it can read your backup status. Store it in your RMM's secure or secret variables, not in plain script text.
You can create as many keys as you like. A separate key for each tool makes it easy to replace one without affecting the others. To stop a key working, click Revoke next to it on the API Keys page. It stops working immediately.
What a key can see
- Partner accounts: every device under your brands and accounts.
- Subusers: only the brands and accounts assigned to them. If those assignments change, the key's access changes with them; there's no need to create a new key.
- Devices that have been deleted or deactivated, or that sit under a suspended or deleted account or brand, are not returned.
- If your license is suspended, requests return
403until it is reactivated.
Making requests
Send the key in the Authorization header. For example, with curl:
curl -H "Authorization: Bearer rmm_live_YOUR_KEY" "https://dash.backupops.com/v1/endpoints?limit=50"
Or with PowerShell:
$headers = @{ Authorization = "Bearer rmm_live_YOUR_KEY" }
Invoke-RestMethod -Uri "https://dash.backupops.com/v1/endpoints?limit=50" -Headers $headersPaging
Lists are returned a page at a time, in this envelope:
{
"count": 137,
"next": "https://dash.backupops.com/v1/endpoints?limit=50&offset=50",
"previous": null,
"results": [ ... ]
}-
limit: how many results per page. Default50, maximum200. -
offset: how many results to skip. -
count: the total number of results across all pages. -
next/previous: the full URL of the next or previous page, ornull. To read everything, keep requestingnextuntil it isnull.
Identifying a device
Every device has a computer_id: a stable number that identifies exactly one device and never changes. It’s the best way to match a device in your RMM to its backup status.
-
Find the device’s regcode. A regcode is four numbers separated by colons, e.g.
1001:2002:3003:12345. You can get it either way:- In the Web Console: on the Storage, Transfers or Remote Manager page, use the table’s column picker to show the hidden Regcode column.
-
On a Windows device, from the backup client. Run it as an administrator. It can take up to about 30 seconds.
-
YourBrandName.exe -getregcode, from the backup client’s install folder (Located inC:\Program Files\YourBrandName\by default)
If the command doesn’t respond, the backup client is an older version that doesn’t support it yet. Use the Web Console instead.
-
-
Take the
computer_idfrom it. It’s the last of the four numbers:1001:2002:3003:12345→12345. You can also look the device up directly with/v1/endpoints?regcode=1001:2002:3003:12345. -
Store the
computer_idin your RMM, in a custom field on each device, and match the API’s results on it.
If you can’t get a regcode, you can search by hostname instead. Hostnames are not unique, so add the brand and account filters and check that exactly one device is returned.
Endpoints
Fetching one device
There are three ways to get a single device. They differ in what you supply and in the shape of the response:
| Request | You supply | Returns |
|---|---|---|
/v1/endpoints/12345 |
The computer_id only |
The device object itself, or 404
|
/v1/endpoints?regcode=1001:2002:3003:12345 |
The full regcode, all four numbers | The paging envelope, with 0 or 1 device in results
|
/v1/endpoints?hostname=…&brand=…&account=… |
Hostname, brand and account | The paging envelope, usually with 1 device in results, but possibly more |
With the filters, read the device from results and check that count is 1.
GET /v1/endpoints
Every device the key can see, each with its current status and the details of its latest backup. Results are ordered by computer_id.
Optional filters, which can be combined:
| Parameter | Matches |
|---|---|
regcode |
Recommended. The device's current registration code, e.g. 1001:2002:3003:12345. Use the full regcode, all four numbers. Identifies exactly one device. |
brand |
The brand name, exact match. |
account |
The account name, exact match. |
hostname |
Fallback only. The device name as shown in the Web Console, e.g. example-pc@workgroup. Exact match. Hostnames are not unique: many sites use the same default name, and one machine registered under several brands appears once per brand. Combine with brand and account. |
GET /v1/endpoints?regcode=1001:2002:3003:12345 GET /v1/endpoints?hostname=example-pc@workgroup&brand=AcmeBackup&account=Main_Office
GET /v1/endpoints/{computer_id}
One device, by its computer_id. The response is a single device object (no paging envelope). Returns 404 if the device doesn't exist or the key can't see it.
computer_id is the stable identifier for a device. Find it with the list endpoint, or take it from the device's regcode: it is the last of the four numbers. This endpoint accepts only the computer_id, not a full regcode.
Have a regcode or hostname instead of a computer_id? Use the filters on /v1/endpoints. They return the usual list, normally with one device in results. Check that count is 1.
GET /v1/endpoints/{computer_id}/backups
The device's backup history, newest first, one record per backup run. Restores, test connections and other job types are not included. Paged like the list endpoint.
GET /v1/alerts
Only the devices that need attention: those whose status is warning, failed or stale. Same device objects and paging as /v1/endpoints. This is the simplest way to drive alerts in your RMM. Its rate limit is lower than the other endpoints' (see Errors and rate limits).
Status values
Every device has one status, based on its latest backup run. It matches the row colours in the Web Console's Transfers page.
| Status | Console color | Meaning | Alert? |
|---|---|---|---|
ok |
Green | The latest backup completed without errors or warnings. | No |
running |
White | A backup is in progress: the device checked in within the last 90 minutes and the run hasn't finished. | No |
warning |
Amber | The latest backup completed, but reported errors or warnings. | Yes |
failed |
Red | The latest backup stopped without completing (no check-in for over 90 minutes), or ended in a fatal error or was interrupted. | Yes |
stale |
Blue | No backup activity in the last week, or the device has never backed up. | Yes |
New status values may be added in future versions. Treat any value you don't recognise as needing attention.
status follows the same rules as the Web Console, so in rare cases a device can be ok while error_count is above zero. Alert on status, and use the counts and messages for detail.
Field reference
How values are formatted
-
Large numbers are strings. Byte and file counts, and
computer_idandsession_id, are returned as strings (for example"1048576") so they stay exact in languages that can't hold very large integers. Convert them to numbers before doing arithmetic. -
Readable twins. Byte, duration and timestamp fields have a matching
*_displayfield that is ready to show, e.g.stored_bytes="1048576"andstored_display="1.0 MB". Timestamps' twins are relative, e.g."2 hours ago". Do calculations on the raw value; show the twin as it is. -
Timestamps are ISO 8601 in UTC, e.g.
2026-01-15T09:30:00Z. -
Missing values are
null. -
Devices that have never backed up have
statusstaleand no backup-run fields. - Stable names. Field names won't change within V1. New fields may be added, so ignore any you don't use.
Device identity
| Field | Type | Description |
|---|---|---|
computer_id |
string | Stable device identifier. Use it for the detail and history endpoints. |
hostname |
string | Device name as shown in the Web Console. Not unique. |
regcode |
string | The device's registration code from its latest connection. |
custom_field |
string | The device's Custom Field from the Web Console, exactly as entered, or null if empty. Free text for your own notes; it can contain anything, so don't use it to identify devices. |
status |
string | One of the status values. |
brand |
string | Brand name. |
account |
string | Account name. |
os |
string | Operating system. |
agent_version |
string | Backup client version. |
ip |
string | Last reported IP address. |
licensed_cpu |
string | The computer name the device is licensed as. |
actual_cpu |
string | The computer name the device actually reported. |
is_local |
boolean | Whether the latest backup went to a local destination. |
last_successful_backup |
timestamp | When the device last completed a backup successfully. Has a _display twin. |
Storage
What the device has stored, from its latest backup. stored_bytes is the space actually used after deduplication; selected_bytes and restorable_bytes are the logical size of the data, so they can be larger than stored_bytes.
| Field | Type | Description |
|---|---|---|
selected_bytes |
string | Size of the data selected for backup. Has a _display twin. |
selected_files |
string | Number of files selected for backup. |
stored_bytes |
string | Space used in storage, after deduplication. Has a _display twin. |
restorable_bytes |
string | Size of the data that can currently be restored. Has a _display twin. |
restorable_files |
string | Number of files that can currently be restored. |
shared_bytes |
string | Data shared with other backups through deduplication. Has a _display twin. |
shared_files |
string | Number of shared files. |
quota_bytes |
string | Storage quota. Has a _display twin. |
retention_versions |
integer | Number of versions kept. |
retention_days |
integer | Number of days versions are kept. |
vault_bucket |
string | The storage bucket the backup is written to. |
Backup run
Details of one backup run. On /v1/endpoints and /v1/alerts these describe the device's latest backup; on /backups each record is one past run.
| Field | Type | Description |
|---|---|---|
session_id |
string | Identifier of the backup run. |
tran_type |
string | Job type. Always Upload (a backup) in V1. |
stage |
string | The stage the backup client last reported, e.g. completed. |
started_at |
timestamp | When the run started. Has a _display twin. |
reported_at |
timestamp | When the device last checked in during this run. Has a _display twin. |
total_files |
string | Files in the backup set. |
total_bytes |
string | Size of the backup set. Has a _display twin. |
changed_files |
string | Files that changed since the previous run. |
changed_bytes |
string | Size of the changed data. Has a _display twin. |
sent_bytes |
string | Data actually sent, after compression. Has a _display twin. |
progress_pct |
integer | Progress of the run, 0 to 100. |
eta_seconds |
integer | Estimated time remaining. Has a eta_display twin. |
current_file |
string | The file being backed up, while a run is in progress. |
upload_mbps |
number | Upload speed, MB/s. |
download_mbps |
number | Download speed, MB/s. |
error_count |
integer | Number of errors in the run. |
warning_count |
integer | Number of warnings in the run. |
messages |
array | The run's error and warning messages, newest first, up to 100. Each has type, text, file and reported_at. |
messages_truncated |
boolean |
true when the run had more errors than messages contains. The backup client sends a limited number of messages per run, so for the full log open the run in the Web Console's Transfers page. |
Records from /backups contain hostname, custom_field and status (the status of that run), plus the backup-run and storage fields.
Example
GET /v1/endpoints/12345
{
"hostname": "example-pc@workgroup",
"custom_field": null,
"computer_id": "12345",
"regcode": "1001:2002:3003:12345",
"status": "warning",
"account": "Main_Office",
"brand": "AcmeBackup",
"os": "Windows_Server_2019",
"agent_version": "26.04.15.1a2b3c4d.64",
"last_successful_backup": "2026-10-12T02:14:09Z",
"last_successful_backup_display": "6 hours ago",
"stored_bytes": "48211230720",
"stored_display": "44.9 GB",
"retention_days": 30,
"session_id": "1234567890123456789",
"tran_type": "Upload",
"stage": "completed (with errors)",
"reported_at": "2026-10-12T02:14:09Z",
"reported_display": "6 hours ago",
"error_count": 2,
"warning_count": 0,
"messages_truncated": false,
"messages": [
{
"type": "Error",
"text": "The process cannot access the file because it is being used by another process.",
"file": "C:\\Data\\open.pst",
"reported_at": "2026-10-12T02:13:55Z"
}
]
}Shortened for readability; a real response includes every field listed above.
Errors and rate limits
Errors return JSON with a detail message, e.g. {"detail": "Invalid or revoked API key."}.
| Code | Meaning | What to do |
|---|---|---|
401 |
The key is missing, wrong or revoked, or its owner's account is inactive. | Check the Authorization header and the key on the API Keys page. |
403 |
The key is valid but has no access: the license is suspended or inactive, or a subuser has no brands or accounts assigned. | Check the license status, or the subuser's assignments. |
404 |
The device doesn't exist, or the key can't see it. | Check the computer_id. |
429 |
Too many requests (see below). | Wait the number of seconds in the Retry-After header, then try again. |
503 |
The request took too long to process. | Retry with a smaller limit, or narrow the request with a filter. |
Rate limits
- 600 requests per hour across all endpoints, per Web Console user. All keys belonging to the same user share this limit.
-
60 requests per hour to
/v1/alerts, per user, in addition to the limit above. - After 20 failed authentication attempts in 10 minutes from one IP address, that address is blocked for 10 minutes, even with a valid key.
These limits are generous for normal monitoring: polling every 5 to 15 minutes, as described below, uses only a small share.
Tips for RMM scripts
-
Poll from one machine, not every device. One scheduled script that reads
/v1/endpoints(200 devices per page) or/v1/alertscovers your whole fleet in a few requests, then updates each device in your RMM. Running a script on every device that calls the API for itself uses one request per device per run, and a large fleet will soon hit the rate limit. - Poll every 5 to 15 minutes. Status changes only as devices check in, so polling more often doesn't give fresher results.
-
Match devices by
computer_id, not hostname. See Identifying a device. Hostnames repeat across sites and brands. -
On a Windows device, you can get its regcode from the backup client: run your brand's client executable with
-getregcode, e.g.YourBrand.exe -getregcode. It can take up to about 30 seconds, and isn't yet available on macOS. Then look the device up with?regcode=, and store itscomputer_idin your RMM so later lookups need no extra step. -
Use a timeout of 30 to 60 seconds on each request, and retry later on
429or503. - Older Windows can't connect. The API requires modern TLS 1.2 ciphers, which Windows Server 2012 R2, Windows Server 2008 R2, Windows 8.1 and Windows 7 don't support. Run your polling script on Windows Server 2016 or Windows 10 or later, or on macOS or Linux. Devices on older Windows are still reported; they just can't call the API themselves.
- Keep keys out of scripts. Use your RMM's secret or secure variables, and use one key per tool so you can replace one without disrupting the others.