What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general.

Learn more

PRTG Network Monitor

Intuitive to Use. Easy to manage.
More than 500,000 users rely on Paessler PRTG every day. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free Download

Top Tags

View all Tags

Roadmap for adding a move to group API



Is there any plans on expanding the API so that I can via the API move devices/sensors to groups? The Multiselect, while it works, does not work consistently. After moving about 3 to 4 groups of multiselected items, will appear to work but the items are not moved. You have to switch to another view, and then back to management before you can move more.

api groups move

Created on Oct 11, 2014 5:21:32 PM

4 Replies



Dear Belz

This specific API feature is currently not in development.

About the inconsistent multiedit feature, please contact [email protected] and include screenshots.

Created on Oct 13, 2014 4:09:26 PM by  Arne Seifert [Paessler Support]



We are five years on and this function still doesn't appear to have been implemented in the API. That's a problem for me. I took a look at the regular Web GUI and it seems like an API call could be done using a form POST.

The URL is:


The form fields are:

id searchtext (can be blank) targetid

where the targetid is the parent group the object is to be moved to.

I guess I am going to have to write a supplementary API module that leverages these non REST URLs to get certain things done. I have thousands of Access Points to manage. Sometimes the access points go offline for months and then get powered back on. I want to be able to move a device into a special "Morgue" group if it disappears but then be able to restore it with its past history if it should suddenly reappear months later. I need group movement for this to work using programs.

Created on Sep 26, 2019 2:56:49 PM



Dear GwigstaNummerEin,

it is correct that the Rest API covers only some features. Other operations require a complex HTTP POST, which is not documented. You can use either browser developer tools, or Wireshark, to read the POST when doing it manuall, and the reproduce it. You can also check the Webserver Access log (default path "C:\ProgramData\Paessler\PRTG Network Monitor\Logs\webserver") of PRTG to read the requests.

An alternative is the Powershell implementation of an abstract layer by lordmilko. It is available here.

Created on Sep 26, 2019 7:20:00 PM by  Arne Seifert [Paessler Support]

Last change on Sep 26, 2019 7:20:41 PM by  Arne Seifert [Paessler Support]



This is some python code that outlines how to make this work.

The module is called using code like this:

from prtg.prtgweb import prtgWeb
parmsDict = {
                    "host":         "prtgaero01.palmbeach.k12.fl.us",
                    "user":         "***",
                    "port":         "443",
                    "pwd":          "***",
                    "certfile":        "/etc/ssl/certs/ca-certificates.crt"
prtgWebObj = prtgWeb(parmsDict)
# Now test the device move function
deviceId = input('Enter the index for the access point to be moved:')
parentId = input('Enter the index for the group to which the AP is to be moved:')
result = prtgWebObj.moveDevice(deviceId,parentId)

The actual module code is as follows:

Created on Sep 26, 2019

@author: ed

import re
from lxml import html
from bs4 import BeautifulSoup
import mechanicalsoup

_USERNAME = '*******'
_PASSWORD = '*******'
_CERTFILE = "/etc/ssl/certs/ca-certificates.crt"

class prtgWeb:

    def __init__(self, paramDict={}):
        self.host = ""
        self.port = ""
        self.user = ""
        self.pwd = ""
        self.certfile = ""
        # Make sure that the dictionary keys exist
        if 'host' in paramDict:
            self.host = paramDict['host']
            self.host = 'prtg.palmbeach.k12.fl.us'

        if 'port' in paramDict:
            self.port = paramDict['port']
            self.port = '443'
        if 'user' in paramDict:
            self.user = paramDict['user']
            self.user = _USERNAME
        if 'password' in paramDict:
            self.pwd = paramDict['password']
            self.pwd = _PASSWORD

        if 'certfile' in paramDict:
            self.certfile = paramDict['certfile']
            self.certfile = _CERTFILE
        self.baseUrl = "https://%s:%s" % ( self.host, self.port )
        loginUrl = "%s/index.htm" % (self.baseUrl)
        self.br = mechanicalsoup.StatefulBrowser(soup_config={'features': 'lxml'})    
        sign_in = self.br.open(loginUrl,verify = self.certfile)
        self.br["username"] = self.user
        self.br["password"] = self.pwd
        # Mechanical Soup drops the html directly into a soup object
        response = self.br.submit_selected()
        # Check the page's <title>
        soup = BeautifulSoup(response.text,'lxml')
        if not soup.title.get_text()[0:7] == "Welcome":
            raise ValueError
    def  moveDevice(self,deviceId,parentId):
        browser = self.br
        postParams = { 'id': deviceId, 'searchtext': '', 'targetid': parentId }
        moveUrl = "%s/%s" % (self.baseUrl,"moveobjectnow.htm")
        response = browser.post( url = moveUrl, data = postParams )
        if response.soup.get_text() == 'ok':
            return True
            return False

Created on Sep 26, 2019 7:36:26 PM

Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.