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. With a key that allows it, your tool can also act on a device: start or stop a backup, restart the backup service, sync settings, reform databases, and change the device's status or custom field. It can't change backup settings or restore data; do those in the Web Console.
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
- Identifying a device
- Endpoints
- Status values
- Remote commands
- Changing a device
- 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. Requests that send data (commands and changes) send JSON too.
- Access: a key sees the same devices its owner sees in the Web Console. Keys are read-only unless you allow remote commands and changes when you generate them.
- 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.
- If this key should be able to send remote commands and change devices, tick Allow remote commands and changes. Leave it unticked for keys that only monitor.
- 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, and a key that allows commands can also start and stop backups. 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.
Read only or read + write
The Access column on the API Keys page shows what each key can do:
- Read only: the key can read devices, backup history and alerts. This is the default, and all a monitoring integration needs.
- Read + write: the key can also send remote commands and change a device.
A key's access can't be changed after it is generated. To change it, generate a new key with the access you want and revoke the old one.
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.
- Subusers sending commands or changing status also need the matching permission in their Web Console settings: Remote Management to send commands, and Edit Computer Status to change a device's status.
- Devices that have been deleted, or that sit under a suspended or deleted account or brand, are not returned. Suspended devices are returned, with
computer_statusSuspended. - 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 $headersRequests that send data (POST and PATCH) send a JSON body with the header Content-Type: application/json:
curl -X POST -H "Authorization: Bearer rmm_live_YOUR_KEY" -H "Content-Type: application/json" \
-d '{"command": "start_backup"}' "https://dash.backupops.com/v1/endpoints/12345/commands"$headers = @{ Authorization = "Bearer rmm_live_YOUR_KEY" }
$body = @{ command = "start_backup" } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "https://dash.backupops.com/v1/endpoints/12345/commands" -Headers $headers -ContentType "application/json" -Body $bodyPaging
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
| Request | What it does | Key needed |
|---|---|---|
GET /v1/endpoints |
List devices, with filters | Any |
GET /v1/endpoints/{computer_id} |
One device | Any |
GET /v1/endpoints/{computer_id}/backups |
A device's backup history | Any |
GET /v1/alerts |
Devices that need attention | Any |
GET /v1/endpoints/{computer_id}/commands |
Is a command waiting for the device? | Any |
POST /v1/endpoints/{computer_id}/commands |
Send or cancel a remote command | Read + write |
PATCH /v1/endpoints/{computer_id} |
Change a device's status or custom field | Read + write |
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. Suspended devices are included: they don't back up, so they show as stale; check computer_status to tell them apart. 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.
status is the device's backup health and can't be changed. Don't confuse it with computer_status, the device's Active, Trial, Test or Suspended status in the Web Console, which you can change.
Remote commands
With a Read + write key you can send a device the same commands as the Web Console's Remote Manager. The device must be checking in with Remote Manager, which means it appears on the Web Console's Remote Manager page.
| Command | What it does |
|---|---|
start_backup |
Starts a backup now. Same as Start Backup in Remote Manager. |
stop_backup |
Stops a backup that is running. Same as Stop Backup. The run is recorded as interrupted, so the device's status becomes failed until its next backup. |
restart_service |
Restarts the backup service on the device. Same as Restart Service. |
sync_settings |
Makes the backup client fetch its latest settings. Same as Sync Settings. |
reform_dbs |
Rebuilds the backup client's local databases. Same as Reform DBs. |
cancel |
Withdraws a command that the device hasn't picked up yet. |
How commands are delivered
Commands work exactly as they do in Remote Manager: the command waits on our server, and the device picks it up the next time it checks in, normally within about 30 seconds. So sending a command and the device acting on it are two separate steps:
-
Send it with
POST. A202response means the command is queued. -
Check it was picked up with
GET.pending_commandgoes back tonullonce the device has taken it. -
See the result on the device itself, e.g. its
statusbecomesrunningafterstart_backup.
Only one command waits for a device at a time. If you send a command while an earlier one from the API is still waiting, the new one replaces it and the response names the one it replaced.
POST /v1/endpoints/{computer_id}/commands
Send {"command": "<name>"} with one of the names above.
POST /v1/endpoints/12345/commands
{"command": "start_backup"}
202 Accepted
{
"computer_id": "12345",
"command": "start_backup",
"state": "queued",
"replaced_command": null,
"agent_last_seen": "2026-10-12T08:41:30Z",
"agent_last_seen_display": "20 seconds ago",
"check_in_interval_seconds": 30
}-
replaced_command: the command this one replaced, ornull. -
agent_last_seen: when the device last checked in with Remote Manager. Has a_displaytwin. -
check_in_interval_seconds: how often the device checks in, so roughly how long until it picks the command up.
To withdraw a waiting command, send {"command": "cancel"}. It takes effect immediately and returns 200:
{
"computer_id": "12345",
"command": "cancel",
"state": "cancelled",
"cancelled_command": "start_backup",
"agent_last_seen": "2026-10-12T08:41:30Z",
"agent_last_seen_display": "25 seconds ago",
"check_in_interval_seconds": 30
}state is cancelled, or nothing_pending if no command was waiting. A command the device has already picked up can't be withdrawn: to end a backup that has started, send stop_backup.
A command is refused with 409 when:
- the device isn't checking in with Remote Manager, so it can't take commands;
- someone is using Remote Manager for the device in the Web Console, e.g. a restore window is open; try again in a few minutes;
- a command sent from the Web Console (e.g. a restore) is waiting for the device. The API won't replace or cancel it;
- you send
start_backupto a suspended device. Set itscomputer_statusback toActive,TrialorTestfirst.
GET /v1/endpoints/{computer_id}/commands
Whether a command is waiting for the device. Works with any key.
{
"computer_id": "12345",
"remote_management": true,
"pending_command": null,
"agent_last_seen": "2026-10-12T08:41:30Z",
"agent_last_seen_display": "20 seconds ago",
"check_in_interval_seconds": 30
}-
remote_management: whether the device checks in with Remote Manager. Iffalse, it can't take commands and the other fields arenull. -
pending_command: the name of the command waiting for the device,otherfor a command sent from the Web Console, ornullif nothing is waiting.
Changing a device
With a Read + write key you can change two things about a device, the same as you can in the Web Console:
-
computer_status: the device's status,Active,Trial,TestorSuspended. -
custom_field: the device's Custom Field, free text of up to 200 characters.
PATCH /v1/endpoints/{computer_id}
Send either field or both. The response is the updated device object, the same as GET /v1/endpoints/{computer_id}.
PATCH /v1/endpoints/12345
{"computer_status": "Active", "custom_field": "Head office server"}-
computer_status can be set to
Active,Trial,TestorSuspended. A suspended device stops backing up until you set it back toActive,TrialorTest, which you can also do through the API. Delete devices in the Web Console. Changing the status has the same effect as changing it in the Web Console. - computer_status can't be changed through the API for brands that run on their own WSBU Server; change it on that server.
-
custom_field: leading and trailing spaces are removed. Send
nullor""to clear it. The device must have backed up at least once. - The request is checked in full before anything is saved, so if any part is refused (
400or403), nothing changes. - Only these two fields can be changed. Sending any other field, including
status, returns400.
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. -
Unknown sizes are
null, not zero. If a backup client reports an impossible size (1 PB or more for one device), that byte field and its_displaytwin arenull. When adding up storage, skipnullvalues rather than counting them as zero. -
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. Can be changed. |
status |
string | Backup health: one of the status values. |
computer_status |
string | The device's status in the Web Console: Active, Trial, Test or Suspended. Can be changed. |
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). |
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",
"computer_status": "Active",
"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."}. A 400 names the field at fault instead, e.g. {"computer_status": "Must be one of: Active, Trial, Test, Suspended. Delete in the web console."}.
| Code | Meaning | What to do |
|---|---|---|
400 |
The request isn't valid: an unknown command, a field that can't be changed, or a value that isn't allowed. | Read the message, which names the field and what's allowed. |
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 not allowed to do this: the license is suspended or inactive; a subuser has no brands or accounts assigned, or lacks the Remote Management or Edit Computer Status permission; or a read-only key tried to send a command or make a change. | Check the license status, the subuser's permissions, or use a Read + write key. |
404 |
The device doesn't exist, the key can't see it, or the URL isn't an API address. | Check the computer_id and the URL. |
409 |
The device can't take a command right now (see Remote commands). | Read the message. Most cases clear within a few minutes. |
429 |
Too many requests (see below). | Wait the number of seconds in the Retry-After header, then try again. |
500 |
Something went wrong on our side. | Try again later. If it keeps happening, contact support. |
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. -
300 commands and changes per hour (
POSTandPATCHrequests), 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. -
Don't resend a command to make sure. A
202means it's queued; checkpending_commandrather than sending it again. To act on several devices, send one command per device. - Use a read-only key for monitoring and a separate Read + write key only where your tool sends commands or makes changes.
- 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.